From e90470b75fc47667da578139985ef38d75eacd4f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 16 Jun 2026 13:48:32 +0200 Subject: [PATCH 1/2] vendor: github.com/open-policy-agent/opa v1.14.1 updating to the lowest minor release that contains [opa@e9ca3ed], which removed some redundant imports that resulted in indirect dependencies. full diff: https://github.com/open-policy-agent/opa/compare/v1.10.1...v1.14.1 [opa@e9ca3ed]: https://github.com/open-policy-agent/opa/commit/e9ca3ed4151e5f1850b379aa62cad77669f453a5 Signed-off-by: Sebastiaan van Stijn --- go.mod | 19 +- go.sum | 37 +- vendor/github.com/beorn7/perks/LICENSE | 20 - .../beorn7/perks/quantile/exampledata.txt | 2388 -------- .../beorn7/perks/quantile/stream.go | 316 -- vendor/github.com/go-ini/ini/.editorconfig | 12 - vendor/github.com/go-ini/ini/.gitignore | 7 - vendor/github.com/go-ini/ini/.golangci.yml | 27 - vendor/github.com/go-ini/ini/LICENSE | 191 - vendor/github.com/go-ini/ini/Makefile | 15 - vendor/github.com/go-ini/ini/README.md | 43 - vendor/github.com/go-ini/ini/codecov.yml | 16 - vendor/github.com/go-ini/ini/data_source.go | 76 - vendor/github.com/go-ini/ini/deprecated.go | 22 - vendor/github.com/go-ini/ini/error.go | 49 - vendor/github.com/go-ini/ini/file.go | 541 -- vendor/github.com/go-ini/ini/helper.go | 24 - vendor/github.com/go-ini/ini/ini.go | 176 - vendor/github.com/go-ini/ini/key.go | 837 --- vendor/github.com/go-ini/ini/parser.go | 520 -- vendor/github.com/go-ini/ini/section.go | 256 - vendor/github.com/go-ini/ini/struct.go | 747 --- .../github.com/lestrrat-go/httprc/v3/Changes | 4 + .../lestrrat-go/httprc/v3/client.go | 14 +- .../lestrrat-go/httprc/v3/controller.go | 5 +- .../lestrrat-go/httprc/v3/options.go | 2 +- .../lestrrat-go/httprc/v3/resource.go | 19 +- .../lestrrat-go/jwx/v3/.golangci.yml | 3 + vendor/github.com/lestrrat-go/jwx/v3/Changes | 50 + .../lestrrat-go/jwx/v3/MODULE.bazel | 4 +- .../jwx/v3/formatkind_string_gen.go | 5 +- .../lestrrat-go/jwx/v3/internal/json/goccy.go | 1 - .../jwx/v3/internal/json/stdlib.go | 2 +- .../lestrrat-go/jwx/v3/jwa/secp2561k.go | 1 - .../jwx/v3/jwe/internal/aescbc/aescbc.go | 4 +- .../github.com/lestrrat-go/jwx/v3/jwe/jwe.go | 138 +- .../lestrrat-go/jwx/v3/jwe/message.go | 40 +- .../lestrrat-go/jwx/v3/jwe/options.go | 5 +- .../lestrrat-go/jwx/v3/jwe/options.yaml | 40 +- .../lestrrat-go/jwx/v3/jwe/options_gen.go | 42 + .../lestrrat-go/jwx/v3/jwk/cache.go | 2 +- .../lestrrat-go/jwx/v3/jwk/ecdsa.go | 4 +- .../lestrrat-go/jwx/v3/jwk/es256k.go | 1 - .../lestrrat-go/jwx/v3/jwk/fetch.go | 2 +- .../lestrrat-go/jwx/v3/jwk/interface.go | 7 +- .../github.com/lestrrat-go/jwx/v3/jwk/jwk.go | 13 +- .../github.com/lestrrat-go/jwx/v3/jwk/okp.go | 4 +- .../github.com/lestrrat-go/jwx/v3/jwk/rsa.go | 4 +- .../github.com/lestrrat-go/jwx/v3/jwk/set.go | 14 +- .../lestrrat-go/jwx/v3/jwk/symmetric.go | 2 +- .../github.com/lestrrat-go/jwx/v3/jwk/x509.go | 2 +- .../lestrrat-go/jwx/v3/jws/es256k.go | 1 - .../github.com/lestrrat-go/jwx/v3/jws/jws.go | 17 +- .../lestrrat-go/jwx/v3/jws/jwsbb/header.go | 2 +- .../lestrrat-go/jwx/v3/jws/legacy.go | 5 +- .../lestrrat-go/jwx/v3/jws/legacy/legacy.go | 2 +- .../lestrrat-go/jwx/v3/jws/options.go | 4 +- .../lestrrat-go/jwx/v3/jws/options.yaml | 6 +- .../lestrrat-go/jwx/v3/jws/options_gen.go | 6 +- .../lestrrat-go/jwx/v3/jws/signer.go | 57 +- .../jwx/v3/jwt/internal/errors/errors.go | 2 + .../github.com/lestrrat-go/jwx/v3/jwt/jwt.go | 9 +- .../lestrrat-go/jwx/v3/jwt/options.go | 10 + .../lestrrat-go/jwx/v3/jwt/token_options.go | 2 +- .../jwx/v3/jwt/token_options_gen.go | 8 +- .../lestrrat-go/jwx/v3/jwt/validate.go | 9 +- .../github.com/lestrrat-go/option/.gitignore | 15 - vendor/github.com/lestrrat-go/option/LICENSE | 21 - .../github.com/lestrrat-go/option/README.md | 245 - .../github.com/lestrrat-go/option/option.go | 38 - .../opa/capabilities/capabilities.go | 3 - .../{v1.10.1.json => v1.11.0.json} | 33 +- .../opa/capabilities/v1.11.1.json | 4878 ++++++++++++++++ .../opa/capabilities/v1.12.0.json | 4896 ++++++++++++++++ .../opa/capabilities/v1.12.1.json | 4896 ++++++++++++++++ .../opa/capabilities/v1.12.2.json | 4896 ++++++++++++++++ .../opa/capabilities/v1.12.3.json | 4896 ++++++++++++++++ .../opa/capabilities/v1.13.0.json | 4916 +++++++++++++++++ .../opa/capabilities/v1.13.1.json | 4916 +++++++++++++++++ .../opa/capabilities/v1.13.2.json | 4916 +++++++++++++++++ .../opa/capabilities/v1.14.0.json | 4916 +++++++++++++++++ .../opa/capabilities/v1.14.1.json | 4916 +++++++++++++++++ .../internal/compiler/wasm/opa/callgraph.csv | 1223 ++-- .../opa/internal/compiler/wasm/opa/opa.wasm | Bin 436729 -> 431796 bytes .../internal/compiler/wasm/optimizations.go | 2 +- .../opa/internal/compiler/wasm/wasm.go | 429 +- .../opa/internal/config/config.go | 176 - .../internal/edittree/bitvector/bitvector.go | 25 +- .../opa/internal/edittree/edittree.go | 266 +- .../opa/internal/file/archive/tarball.go | 71 +- .../opa/internal/gojsonschema/utils.go | 2 +- .../opa/internal/planner/planner.go | 4 +- .../opa/internal/providers/aws/signing_v4.go | 2 + .../open-policy-agent/opa/internal/ref/ref.go | 4 +- .../opa/internal/report/report.go | 218 - .../opa/internal/runtime/init/init.go | 261 - .../opa/internal/semver/semver.go | 301 +- .../opa/internal/strvals/doc.go | 33 - .../opa/internal/strvals/parser.go | 429 -- .../opa/internal/wasm/encoding/reader.go | 2 +- .../opa/v1/ast/annotations.go | 18 +- .../open-policy-agent/opa/v1/ast/builtins.go | 110 +- .../opa/v1/ast/capabilities.go | 15 +- .../open-policy-agent/opa/v1/ast/check.go | 180 +- .../open-policy-agent/opa/v1/ast/compare.go | 35 +- .../open-policy-agent/opa/v1/ast/compile.go | 1417 +++-- .../opa/v1/ast/compilehelper.go | 3 +- .../open-policy-agent/opa/v1/ast/conflicts.go | 4 +- .../open-policy-agent/opa/v1/ast/env.go | 70 +- .../open-policy-agent/opa/v1/ast/errors.go | 21 +- .../open-policy-agent/opa/v1/ast/index.go | 74 +- .../opa/v1/ast/internal/scanner/scanner.go | 151 +- .../opa/v1/ast/internal/tokens/tokens.go | 108 +- .../open-policy-agent/opa/v1/ast/interning.go | 92 +- .../opa/v1/ast/location/location.go | 41 +- .../open-policy-agent/opa/v1/ast/parser.go | 486 +- .../opa/v1/ast/parser_ext.go | 18 +- .../opa/v1/ast/performance.go | 14 + .../open-policy-agent/opa/v1/ast/policy.go | 279 +- .../opa/v1/ast/policy_appenders.go | 324 ++ .../open-policy-agent/opa/v1/ast/rego_v1.go | 27 +- .../open-policy-agent/opa/v1/ast/slices.go | 15 + .../opa/v1/ast/string_length.go | 351 ++ .../open-policy-agent/opa/v1/ast/strings.go | 2 + .../open-policy-agent/opa/v1/ast/syncpools.go | 88 +- .../open-policy-agent/opa/v1/ast/term.go | 543 +- .../opa/v1/ast/term_appenders.go | 266 + .../open-policy-agent/opa/v1/ast/transform.go | 45 +- .../open-policy-agent/opa/v1/ast/unify.go | 11 +- .../open-policy-agent/opa/v1/ast/varset.go | 14 +- .../opa/v1/ast/version_index.json | 849 +-- .../open-policy-agent/opa/v1/ast/visit.go | 464 +- .../open-policy-agent/opa/v1/bundle/bundle.go | 316 +- .../open-policy-agent/opa/v1/bundle/file.go | 13 +- .../open-policy-agent/opa/v1/bundle/filefs.go | 3 - .../open-policy-agent/opa/v1/bundle/hash.go | 3 +- .../open-policy-agent/opa/v1/bundle/store.go | 10 +- .../open-policy-agent/opa/v1/bundle/verify.go | 4 - .../opa/v1/capabilities/capabilities.go | 3 - .../open-policy-agent/opa/v1/config/config.go | 393 -- .../open-policy-agent/opa/v1/format/format.go | 100 +- .../open-policy-agent/opa/v1/hooks/hooks.go | 97 - .../open-policy-agent/opa/v1/loader/loader.go | 6 +- .../opa/v1/plugins/plugins.go | 1195 ---- .../opa/v1/plugins/rest/auth.go | 1211 ---- .../opa/v1/plugins/rest/aws.go | 1088 ---- .../opa/v1/plugins/rest/azure.go | 287 - .../opa/v1/plugins/rest/gcp.go | 173 - .../opa/v1/plugins/rest/rest.go | 366 -- .../open-policy-agent/opa/v1/rego/rego.go | 41 +- .../opa/v1/rego/resultset.go | 18 +- .../opa/v1/storage/inmem/inmem.go | 37 +- .../opa/v1/storage/interface.go | 12 + .../opa/v1/topdown/aggregates.go | 12 +- .../open-policy-agent/opa/v1/topdown/array.go | 55 +- .../opa/v1/topdown/bindings.go | 106 +- .../opa/v1/topdown/builtins/builtins.go | 27 +- .../opa/v1/topdown/cache/cache.go | 25 +- .../open-policy-agent/opa/v1/topdown/cidr.go | 2 +- .../copypropagation/copypropagation.go | 17 +- .../opa/v1/topdown/crypto.go | 68 +- .../opa/v1/topdown/encoding.go | 72 +- .../opa/v1/topdown/errors.go | 26 +- .../open-policy-agent/opa/v1/topdown/eval.go | 366 +- .../opa/v1/topdown/graphql.go | 4 +- .../open-policy-agent/opa/v1/topdown/http.go | 130 +- .../opa/v1/topdown/http_fixup.go | 3 +- .../opa/v1/topdown/http_fixup_darwin.go | 3 - .../open-policy-agent/opa/v1/topdown/json.go | 219 +- .../opa/v1/topdown/jsonschema.go | 4 +- .../open-policy-agent/opa/v1/topdown/net.go | 2 +- .../opa/v1/topdown/numbers.go | 2 +- .../opa/v1/topdown/object.go | 31 +- .../open-policy-agent/opa/v1/topdown/print.go | 27 +- .../opa/v1/topdown/providers.go | 47 +- .../open-policy-agent/opa/v1/topdown/query.go | 3 +- .../open-policy-agent/opa/v1/topdown/regex.go | 86 +- .../opa/v1/topdown/resolver.go | 2 +- .../opa/v1/topdown/semver.go | 21 +- .../open-policy-agent/opa/v1/topdown/sets.go | 24 +- .../open-policy-agent/opa/v1/topdown/sink.go | 73 + .../opa/v1/topdown/strings.go | 77 +- .../opa/v1/topdown/template.go | 6 +- .../opa/v1/topdown/template_string.go | 45 + .../opa/v1/topdown/tokens.go | 39 +- .../open-policy-agent/opa/v1/topdown/trace.go | 6 +- .../open-policy-agent/opa/v1/topdown/walk.go | 25 +- .../open-policy-agent/opa/v1/types/types.go | 3 +- .../open-policy-agent/opa/v1/util/graph.go | 7 +- .../opa/v1/util/performance.go | 71 +- .../opa/v1/util/read_gzip_body.go | 38 +- .../open-policy-agent/opa/v1/util/strings.go | 13 + .../opa/v1/version/version.go | 2 +- .../prometheus/client_golang/LICENSE | 201 - .../prometheus/client_golang/NOTICE | 18 - .../client_golang/prometheus/.gitignore | 1 - .../client_golang/prometheus/README.md | 1 - .../prometheus/build_info_collector.go | 38 - .../client_golang/prometheus/collector.go | 128 - .../client_golang/prometheus/collectorfunc.go | 30 - .../client_golang/prometheus/counter.go | 358 -- .../client_golang/prometheus/desc.go | 211 - .../client_golang/prometheus/doc.go | 210 - .../prometheus/expvar_collector.go | 86 - .../client_golang/prometheus/fnv.go | 42 - .../client_golang/prometheus/gauge.go | 311 -- .../client_golang/prometheus/get_pid.go | 26 - .../prometheus/get_pid_gopherjs.go | 23 - .../client_golang/prometheus/go_collector.go | 274 - .../prometheus/go_collector_go116.go | 122 - .../prometheus/go_collector_latest.go | 574 -- .../client_golang/prometheus/histogram.go | 2056 ------- .../prometheus/internal/almost_equal.go | 60 - .../prometheus/internal/difflib.go | 655 --- .../internal/go_collector_options.go | 34 - .../prometheus/internal/go_runtime_metrics.go | 143 - .../prometheus/internal/metric.go | 101 - .../client_golang/prometheus/labels.go | 189 - .../client_golang/prometheus/metric.go | 276 - .../client_golang/prometheus/num_threads.go | 25 - .../prometheus/num_threads_gopherjs.go | 22 - .../client_golang/prometheus/observer.go | 64 - .../prometheus/process_collector.go | 180 - .../prometheus/process_collector_darwin.go | 130 - .../process_collector_mem_cgo_darwin.c | 84 - .../process_collector_mem_cgo_darwin.go | 51 - .../process_collector_mem_nocgo_darwin.go | 39 - .../process_collector_not_supported.go | 33 - .../process_collector_procfsenabled.go | 96 - .../prometheus/process_collector_windows.go | 125 - .../client_golang/prometheus/registry.go | 1076 ---- .../client_golang/prometheus/summary.go | 830 --- .../client_golang/prometheus/timer.go | 81 - .../client_golang/prometheus/untyped.go | 42 - .../client_golang/prometheus/value.go | 274 - .../client_golang/prometheus/vec.go | 709 --- .../client_golang/prometheus/vnext.go | 23 - .../client_golang/prometheus/wrap.go | 248 - .../prometheus/client_model/LICENSE | 201 - .../github.com/prometheus/client_model/NOTICE | 5 - .../prometheus/client_model/go/metrics.pb.go | 1399 ----- vendor/github.com/prometheus/common/LICENSE | 201 - vendor/github.com/prometheus/common/NOTICE | 5 - .../prometheus/common/expfmt/decode.go | 464 -- .../prometheus/common/expfmt/encode.go | 196 - .../prometheus/common/expfmt/expfmt.go | 212 - .../prometheus/common/expfmt/fuzz.go | 39 - .../common/expfmt/openmetrics_create.go | 712 --- .../prometheus/common/expfmt/text_create.go | 532 -- .../prometheus/common/expfmt/text_parse.go | 997 ---- .../prometheus/common/model/alert.go | 162 - .../prometheus/common/model/fingerprinting.go | 105 - .../github.com/prometheus/common/model/fnv.go | 42 - .../prometheus/common/model/labels.go | 229 - .../prometheus/common/model/labelset.go | 158 - .../common/model/labelset_string.go | 43 - .../prometheus/common/model/metadata.go | 28 - .../prometheus/common/model/metric.go | 593 -- .../prometheus/common/model/model.go | 16 - .../prometheus/common/model/signature.go | 142 - .../prometheus/common/model/silence.go | 107 - .../prometheus/common/model/time.go | 359 -- .../prometheus/common/model/value.go | 365 -- .../prometheus/common/model/value_float.go | 99 - .../common/model/value_histogram.go | 179 - .../prometheus/common/model/value_type.go | 83 - .../github.com/prometheus/procfs/.gitignore | 2 - .../prometheus/procfs/.golangci.yml | 59 - .../prometheus/procfs/CODE_OF_CONDUCT.md | 3 - .../prometheus/procfs/CONTRIBUTING.md | 121 - vendor/github.com/prometheus/procfs/LICENSE | 201 - .../prometheus/procfs/MAINTAINERS.md | 3 - vendor/github.com/prometheus/procfs/Makefile | 31 - .../prometheus/procfs/Makefile.common | 503 -- vendor/github.com/prometheus/procfs/NOTICE | 7 - vendor/github.com/prometheus/procfs/README.md | 61 - .../github.com/prometheus/procfs/SECURITY.md | 6 - vendor/github.com/prometheus/procfs/arp.go | 117 - .../github.com/prometheus/procfs/buddyinfo.go | 83 - .../github.com/prometheus/procfs/cmdline.go | 30 - .../github.com/prometheus/procfs/cpuinfo.go | 518 -- .../prometheus/procfs/cpuinfo_armx.go | 18 - .../prometheus/procfs/cpuinfo_loong64.go | 18 - .../prometheus/procfs/cpuinfo_mipsx.go | 18 - .../prometheus/procfs/cpuinfo_others.go | 18 - .../prometheus/procfs/cpuinfo_ppcx.go | 18 - .../prometheus/procfs/cpuinfo_riscvx.go | 18 - .../prometheus/procfs/cpuinfo_s390x.go | 18 - .../prometheus/procfs/cpuinfo_x86.go | 18 - vendor/github.com/prometheus/procfs/crypto.go | 154 - vendor/github.com/prometheus/procfs/doc.go | 44 - vendor/github.com/prometheus/procfs/fs.go | 56 - .../prometheus/procfs/fs_statfs_notype.go | 22 - .../prometheus/procfs/fs_statfs_type.go | 32 - .../github.com/prometheus/procfs/fscache.go | 423 -- .../prometheus/procfs/internal/fs/fs.go | 58 - .../prometheus/procfs/internal/util/parse.go | 126 - .../procfs/internal/util/readfile.go | 37 - .../procfs/internal/util/sysreadfile.go | 68 - .../internal/util/sysreadfile_compat.go | 26 - .../procfs/internal/util/valueparser.go | 91 - vendor/github.com/prometheus/procfs/ipvs.go | 241 - .../prometheus/procfs/kernel_hung.go | 44 - .../prometheus/procfs/kernel_random.go | 62 - .../github.com/prometheus/procfs/loadavg.go | 62 - vendor/github.com/prometheus/procfs/mdstat.go | 353 -- .../github.com/prometheus/procfs/meminfo.go | 422 -- .../github.com/prometheus/procfs/mountinfo.go | 197 - .../prometheus/procfs/mountstats.go | 710 --- .../prometheus/procfs/net_conntrackstat.go | 118 - .../github.com/prometheus/procfs/net_dev.go | 205 - .../prometheus/procfs/net_dev_snmp6.go | 99 - .../prometheus/procfs/net_ip_socket.go | 248 - .../prometheus/procfs/net_protocols.go | 183 - .../github.com/prometheus/procfs/net_route.go | 143 - .../prometheus/procfs/net_sockstat.go | 159 - .../prometheus/procfs/net_softnet.go | 155 - .../github.com/prometheus/procfs/net_tcp.go | 72 - .../prometheus/procfs/net_tls_stat.go | 119 - .../github.com/prometheus/procfs/net_udp.go | 64 - .../github.com/prometheus/procfs/net_unix.go | 257 - .../prometheus/procfs/net_wireless.go | 182 - .../github.com/prometheus/procfs/net_xfrm.go | 189 - .../github.com/prometheus/procfs/netstat.go | 82 - .../prometheus/procfs/nfnetlink_queue.go | 85 - vendor/github.com/prometheus/procfs/proc.go | 338 -- .../prometheus/procfs/proc_cgroup.go | 98 - .../prometheus/procfs/proc_cgroups.go | 98 - .../prometheus/procfs/proc_environ.go | 37 - .../prometheus/procfs/proc_fdinfo.go | 139 - .../prometheus/procfs/proc_interrupts.go | 98 - .../github.com/prometheus/procfs/proc_io.go | 59 - .../prometheus/procfs/proc_limits.go | 161 - .../github.com/prometheus/procfs/proc_maps.go | 209 - .../prometheus/procfs/proc_netstat.go | 443 -- .../github.com/prometheus/procfs/proc_ns.go | 68 - .../github.com/prometheus/procfs/proc_psi.go | 102 - .../prometheus/procfs/proc_smaps.go | 163 - .../github.com/prometheus/procfs/proc_snmp.go | 353 -- .../prometheus/procfs/proc_snmp6.go | 381 -- .../github.com/prometheus/procfs/proc_stat.go | 235 - .../prometheus/procfs/proc_statm.go | 117 - .../prometheus/procfs/proc_status.go | 284 - .../github.com/prometheus/procfs/proc_sys.go | 51 - .../github.com/prometheus/procfs/schedstat.go | 121 - vendor/github.com/prometheus/procfs/slab.go | 151 - .../github.com/prometheus/procfs/softirqs.go | 160 - vendor/github.com/prometheus/procfs/stat.go | 259 - vendor/github.com/prometheus/procfs/swaps.go | 89 - vendor/github.com/prometheus/procfs/thread.go | 80 - vendor/github.com/prometheus/procfs/ttar | 413 -- vendor/github.com/prometheus/procfs/vm.go | 211 - .../github.com/prometheus/procfs/zoneinfo.go | 193 - vendor/github.com/segmentio/asm/LICENSE | 31 +- .../segmentio/asm/base64/decode_arm64.s | 14 +- vendor/github.com/valyala/fastjson/arena.go | 8 +- vendor/github.com/valyala/fastjson/doc.go | 1 - vendor/github.com/valyala/fastjson/fuzz.go | 1 + vendor/github.com/valyala/fastjson/pool.go | 1 + vendor/github.com/valyala/fastjson/update.go | 3 + .../vektah/gqlparser/v2/ast/argmap.go | 10 +- .../vektah/gqlparser/v2/ast/definition.go | 9 +- .../vektah/gqlparser/v2/ast/directive.go | 9 +- .../vektah/gqlparser/v2/ast/document.go | 7 +- .../vektah/gqlparser/v2/ast/dumper.go | 14 +- .../vektah/gqlparser/v2/ast/path.go | 4 +- .../vektah/gqlparser/v2/ast/selection.go | 5 +- .../vektah/gqlparser/v2/ast/source.go | 2 +- .../vektah/gqlparser/v2/ast/value.go | 13 +- .../vektah/gqlparser/v2/gqlerror/error.go | 31 +- .../vektah/gqlparser/v2/lexer/lexer.go | 101 +- .../vektah/gqlparser/v2/parser/parser.go | 6 +- .../vektah/gqlparser/v2/parser/query.go | 10 +- .../gqlparser/v2/validator/core/helpers.go | 19 +- .../gqlparser/v2/validator/core/walk.go | 10 +- .../validator/rules/fields_on_correct_type.go | 28 +- .../rules/fragments_on_composite_types.go | 15 +- .../validator/rules/known_argument_names.go | 15 +- .../v2/validator/rules/known_directives.go | 15 +- .../validator/rules/known_fragment_names.go | 1 - .../v2/validator/rules/known_root_type.go | 1 - .../v2/validator/rules/known_type_names.go | 1 - .../rules/lone_anonymous_operation.go | 1 - .../rules/max_introspection_depth.go | 13 +- .../v2/validator/rules/no_fragment_cycles.go | 7 +- .../validator/rules/no_undefined_variables.go | 10 +- .../v2/validator/rules/no_unused_fragments.go | 1 - .../v2/validator/rules/no_unused_variables.go | 7 +- .../rules/overlapping_fields_can_be_merged.go | 138 +- .../rules/possible_fragment_spreads.go | 29 +- .../gqlparser/v2/validator/rules/rules.go | 9 +- .../v2/validator/rules/scalar_leafs.go | 13 +- .../rules/single_field_subscriptions.go | 1 - .../validator/rules/unique_argument_names.go | 1 - .../rules/unique_directives_per_location.go | 6 +- .../validator/rules/unique_fragment_names.go | 1 - .../rules/unique_input_field_names.go | 1 - .../validator/rules/unique_operation_names.go | 1 - .../validator/rules/unique_variable_names.go | 1 - .../validator/rules/values_of_correct_type.go | 95 +- .../rules/variables_are_input_types.go | 1 - .../rules/variables_in_allowed_position.go | 13 +- .../vektah/gqlparser/v2/validator/schema.go | 230 +- .../gqlparser/v2/validator/validator.go | 19 +- .../vektah/gqlparser/v2/validator/vars.go | 48 +- .../encoding/protodelim/protodelim.go | 160 - vendor/modules.txt | 50 +- 407 files changed, 56930 insertions(+), 47930 deletions(-) delete mode 100644 vendor/github.com/beorn7/perks/LICENSE delete mode 100644 vendor/github.com/beorn7/perks/quantile/exampledata.txt delete mode 100644 vendor/github.com/beorn7/perks/quantile/stream.go delete mode 100644 vendor/github.com/go-ini/ini/.editorconfig delete mode 100644 vendor/github.com/go-ini/ini/.gitignore delete mode 100644 vendor/github.com/go-ini/ini/.golangci.yml delete mode 100644 vendor/github.com/go-ini/ini/LICENSE delete mode 100644 vendor/github.com/go-ini/ini/Makefile delete mode 100644 vendor/github.com/go-ini/ini/README.md delete mode 100644 vendor/github.com/go-ini/ini/codecov.yml delete mode 100644 vendor/github.com/go-ini/ini/data_source.go delete mode 100644 vendor/github.com/go-ini/ini/deprecated.go delete mode 100644 vendor/github.com/go-ini/ini/error.go delete mode 100644 vendor/github.com/go-ini/ini/file.go delete mode 100644 vendor/github.com/go-ini/ini/helper.go delete mode 100644 vendor/github.com/go-ini/ini/ini.go delete mode 100644 vendor/github.com/go-ini/ini/key.go delete mode 100644 vendor/github.com/go-ini/ini/parser.go delete mode 100644 vendor/github.com/go-ini/ini/section.go delete mode 100644 vendor/github.com/go-ini/ini/struct.go delete mode 100644 vendor/github.com/lestrrat-go/option/.gitignore delete mode 100644 vendor/github.com/lestrrat-go/option/LICENSE delete mode 100644 vendor/github.com/lestrrat-go/option/README.md delete mode 100644 vendor/github.com/lestrrat-go/option/option.go rename vendor/github.com/open-policy-agent/opa/capabilities/{v1.10.1.json => v1.11.0.json} (99%) create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.11.1.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.12.0.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.12.1.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.12.2.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.12.3.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.13.0.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.13.1.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.13.2.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.14.0.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.14.1.json delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/config/config.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/report/report.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/strvals/doc.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/ast/policy_appenders.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/ast/slices.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/ast/string_length.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/ast/term_appenders.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/config/config.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/hooks/hooks.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/plugins/plugins.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/plugins/rest/auth.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/plugins/rest/aws.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/plugins/rest/azure.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/plugins/rest/gcp.go delete mode 100644 vendor/github.com/open-policy-agent/opa/v1/plugins/rest/rest.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/topdown/sink.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/topdown/template_string.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/util/strings.go delete mode 100644 vendor/github.com/prometheus/client_golang/LICENSE delete mode 100644 vendor/github.com/prometheus/client_golang/NOTICE delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/.gitignore delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/README.md delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/counter.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/desc.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/doc.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/fnv.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/gauge.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/get_pid.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/go_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/histogram.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/labels.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/metric.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/num_threads.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/observer.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/registry.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/summary.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/timer.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/untyped.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/value.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/vec.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/vnext.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/wrap.go delete mode 100644 vendor/github.com/prometheus/client_model/LICENSE delete mode 100644 vendor/github.com/prometheus/client_model/NOTICE delete mode 100644 vendor/github.com/prometheus/client_model/go/metrics.pb.go delete mode 100644 vendor/github.com/prometheus/common/LICENSE delete mode 100644 vendor/github.com/prometheus/common/NOTICE delete mode 100644 vendor/github.com/prometheus/common/expfmt/decode.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/encode.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/expfmt.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/fuzz.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/openmetrics_create.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/text_create.go delete mode 100644 vendor/github.com/prometheus/common/expfmt/text_parse.go delete mode 100644 vendor/github.com/prometheus/common/model/alert.go delete mode 100644 vendor/github.com/prometheus/common/model/fingerprinting.go delete mode 100644 vendor/github.com/prometheus/common/model/fnv.go delete mode 100644 vendor/github.com/prometheus/common/model/labels.go delete mode 100644 vendor/github.com/prometheus/common/model/labelset.go delete mode 100644 vendor/github.com/prometheus/common/model/labelset_string.go delete mode 100644 vendor/github.com/prometheus/common/model/metadata.go delete mode 100644 vendor/github.com/prometheus/common/model/metric.go delete mode 100644 vendor/github.com/prometheus/common/model/model.go delete mode 100644 vendor/github.com/prometheus/common/model/signature.go delete mode 100644 vendor/github.com/prometheus/common/model/silence.go delete mode 100644 vendor/github.com/prometheus/common/model/time.go delete mode 100644 vendor/github.com/prometheus/common/model/value.go delete mode 100644 vendor/github.com/prometheus/common/model/value_float.go delete mode 100644 vendor/github.com/prometheus/common/model/value_histogram.go delete mode 100644 vendor/github.com/prometheus/common/model/value_type.go delete mode 100644 vendor/github.com/prometheus/procfs/.gitignore delete mode 100644 vendor/github.com/prometheus/procfs/.golangci.yml delete mode 100644 vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md delete mode 100644 vendor/github.com/prometheus/procfs/CONTRIBUTING.md delete mode 100644 vendor/github.com/prometheus/procfs/LICENSE delete mode 100644 vendor/github.com/prometheus/procfs/MAINTAINERS.md delete mode 100644 vendor/github.com/prometheus/procfs/Makefile delete mode 100644 vendor/github.com/prometheus/procfs/Makefile.common delete mode 100644 vendor/github.com/prometheus/procfs/NOTICE delete mode 100644 vendor/github.com/prometheus/procfs/README.md delete mode 100644 vendor/github.com/prometheus/procfs/SECURITY.md delete mode 100644 vendor/github.com/prometheus/procfs/arp.go delete mode 100644 vendor/github.com/prometheus/procfs/buddyinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/cmdline.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_armx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_loong64.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_others.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_s390x.go delete mode 100644 vendor/github.com/prometheus/procfs/cpuinfo_x86.go delete mode 100644 vendor/github.com/prometheus/procfs/crypto.go delete mode 100644 vendor/github.com/prometheus/procfs/doc.go delete mode 100644 vendor/github.com/prometheus/procfs/fs.go delete mode 100644 vendor/github.com/prometheus/procfs/fs_statfs_notype.go delete mode 100644 vendor/github.com/prometheus/procfs/fs_statfs_type.go delete mode 100644 vendor/github.com/prometheus/procfs/fscache.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/fs/fs.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/parse.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/readfile.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go delete mode 100644 vendor/github.com/prometheus/procfs/internal/util/valueparser.go delete mode 100644 vendor/github.com/prometheus/procfs/ipvs.go delete mode 100644 vendor/github.com/prometheus/procfs/kernel_hung.go delete mode 100644 vendor/github.com/prometheus/procfs/kernel_random.go delete mode 100644 vendor/github.com/prometheus/procfs/loadavg.go delete mode 100644 vendor/github.com/prometheus/procfs/mdstat.go delete mode 100644 vendor/github.com/prometheus/procfs/meminfo.go delete mode 100644 vendor/github.com/prometheus/procfs/mountinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/mountstats.go delete mode 100644 vendor/github.com/prometheus/procfs/net_conntrackstat.go delete mode 100644 vendor/github.com/prometheus/procfs/net_dev.go delete mode 100644 vendor/github.com/prometheus/procfs/net_dev_snmp6.go delete mode 100644 vendor/github.com/prometheus/procfs/net_ip_socket.go delete mode 100644 vendor/github.com/prometheus/procfs/net_protocols.go delete mode 100644 vendor/github.com/prometheus/procfs/net_route.go delete mode 100644 vendor/github.com/prometheus/procfs/net_sockstat.go delete mode 100644 vendor/github.com/prometheus/procfs/net_softnet.go delete mode 100644 vendor/github.com/prometheus/procfs/net_tcp.go delete mode 100644 vendor/github.com/prometheus/procfs/net_tls_stat.go delete mode 100644 vendor/github.com/prometheus/procfs/net_udp.go delete mode 100644 vendor/github.com/prometheus/procfs/net_unix.go delete mode 100644 vendor/github.com/prometheus/procfs/net_wireless.go delete mode 100644 vendor/github.com/prometheus/procfs/net_xfrm.go delete mode 100644 vendor/github.com/prometheus/procfs/netstat.go delete mode 100644 vendor/github.com/prometheus/procfs/nfnetlink_queue.go delete mode 100644 vendor/github.com/prometheus/procfs/proc.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_cgroup.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_cgroups.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_environ.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_fdinfo.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_interrupts.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_io.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_limits.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_maps.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_netstat.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_ns.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_psi.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_smaps.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_snmp.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_snmp6.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_stat.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_statm.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_status.go delete mode 100644 vendor/github.com/prometheus/procfs/proc_sys.go delete mode 100644 vendor/github.com/prometheus/procfs/schedstat.go delete mode 100644 vendor/github.com/prometheus/procfs/slab.go delete mode 100644 vendor/github.com/prometheus/procfs/softirqs.go delete mode 100644 vendor/github.com/prometheus/procfs/stat.go delete mode 100644 vendor/github.com/prometheus/procfs/swaps.go delete mode 100644 vendor/github.com/prometheus/procfs/thread.go delete mode 100644 vendor/github.com/prometheus/procfs/ttar delete mode 100644 vendor/github.com/prometheus/procfs/vm.go delete mode 100644 vendor/github.com/prometheus/procfs/zoneinfo.go delete mode 100644 vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go diff --git a/go.mod b/go.mod index 11981d34db2e..14ebe64979f1 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( github.com/moby/sys/atomicwriter v0.1.0 github.com/moby/sys/mountinfo v0.7.2 github.com/morikuni/aec v1.1.0 - github.com/open-policy-agent/opa v1.10.1 + github.com/open-policy-agent/opa v1.14.1 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 github.com/pelletier/go-toml/v2 v2.3.1 @@ -97,7 +97,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.6 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.43.3 // indirect github.com/aws/smithy-go v1.27.2 // indirect - github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -118,7 +117,6 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect - github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.25.2 // indirect @@ -162,9 +160,8 @@ require ( github.com/lestrrat-go/dsig v1.0.0 // indirect github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc/v3 v3.0.1 // indirect - github.com/lestrrat-go/jwx/v3 v3.0.11 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lestrrat-go/httprc/v3 v3.0.2 // indirect + github.com/lestrrat-go/jwx/v3 v3.0.13 // indirect github.com/lestrrat-go/option/v2 v2.0.0 // indirect github.com/mattn/go-runewidth v0.0.23 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect @@ -185,15 +182,11 @@ require ( github.com/oklog/ulid/v2 v2.1.1 // indirect github.com/package-url/packageurl-go v0.1.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.23.2 // indirect - github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.5 // indirect - github.com/prometheus/procfs v0.20.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect github.com/secure-systems-lab/go-securesystemslib v0.11.0 // indirect - github.com/segmentio/asm v1.2.0 // indirect + github.com/segmentio/asm v1.2.1 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/sigstore/protobuf-specs v0.5.1 // indirect github.com/sigstore/rekor v1.5.2 // indirect @@ -207,8 +200,8 @@ require ( github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect github.com/transparency-dev/formats v0.1.1 // indirect github.com/transparency-dev/merkle v0.0.2 // indirect - github.com/valyala/fastjson v1.6.4 // indirect - github.com/vektah/gqlparser/v2 v2.5.30 // indirect + github.com/valyala/fastjson v1.6.7 // indirect + github.com/vektah/gqlparser/v2 v2.5.32 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect diff --git a/go.sum b/go.sum index b9e02df6ee08..4ed4f7cd4c61 100644 --- a/go.sum +++ b/go.sum @@ -98,8 +98,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bytecodealliance/wasmtime-go/v37 v37.0.0 h1:DPjdn2V3JhXHMoZ2ymRqGK+y1bDyr9wgpyYCvhjMky8= -github.com/bytecodealliance/wasmtime-go/v37 v37.0.0/go.mod h1:Pf1l2JCTUFMnOqDIwkjzx1qfVJ09xbaXETKgRVE4jZ0= +github.com/bytecodealliance/wasmtime-go/v39 v39.0.1 h1:RibaT47yiyCRxMOj/l2cvL8cWiWBSqDXHyqsa9sGcCE= +github.com/bytecodealliance/wasmtime-go/v39 v39.0.1/go.mod h1:miR4NYIEBXeDNamZIzpskhJ0z/p8al+lwMWylQ/ZJb4= 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/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= @@ -203,16 +203,14 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= -github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= +github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0= +github.com/foxcpp/go-mockdns v1.2.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-chi/chi/v5 v5.3.0 h1:halUjDxhshgXHMrao5bB8eNBXo/rnzwr8m5m36glehM= github.com/go-chi/chi/v5 v5.3.0/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto= -github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= -github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -379,12 +377,10 @@ github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7 github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/httprc/v3 v3.0.1 h1:3n7Es68YYGZb2Jf+k//llA4FTZMl3yCwIjFIk4ubevI= -github.com/lestrrat-go/httprc/v3 v3.0.1/go.mod h1:2uAvmbXE4Xq8kAUjVrZOq1tZVYYYs5iP62Cmtru00xk= -github.com/lestrrat-go/jwx/v3 v3.0.11 h1:yEeUGNUuNjcez/Voxvr7XPTYNraSQTENJgtVTfwvG/w= -github.com/lestrrat-go/jwx/v3 v3.0.11/go.mod h1:XSOAh2SiXm0QgRe3DulLZLyt+wUuEdFo81zuKTLcvgQ= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/httprc/v3 v3.0.2 h1:7u4HUaD0NQbf2/n5+fyp+T10hNCsAnwKfqn4A4Baif0= +github.com/lestrrat-go/httprc/v3 v3.0.2/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0= +github.com/lestrrat-go/jwx/v3 v3.0.13 h1:AdHKiPIYeCSnOJtvdpipPg/0SuFh9rdkN+HF3O0VdSk= +github.com/lestrrat-go/jwx/v3 v3.0.13/go.mod h1:2m0PV1A9tM4b/jVLMx8rh6rBl7F6WGb3EG2hufN9OQU= github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg= github.com/letsencrypt/boulder v0.20260309.0 h1:kZynrxK3QfqLGx6hhoz+Rfs3hgltJs1p9Mp+4+VwnY0= @@ -451,8 +447,8 @@ github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0 github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= -github.com/open-policy-agent/opa v1.10.1 h1:haIvxZSPky8HLjRrvQwWAjCPLg8JDFSZMbbG4yyUHgY= -github.com/open-policy-agent/opa v1.10.1/go.mod h1:7uPI3iRpOalJ0BhK6s1JALWPU9HvaV1XeBSSMZnr/PM= +github.com/open-policy-agent/opa v1.14.1 h1:MhurLB9mSbXmojYFCmGbiC1Uagu1+aFAV4XVotDA86M= +github.com/open-policy-agent/opa v1.14.1/go.mod h1:B5gykwJ2l0g0wZS4ClCcpfSSEx51n4NHpTsWfuPwqnQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -499,8 +495,8 @@ github.com/sassoftware/relic/v7 v7.6.2 h1:rS44Lbv9G9eXsukknS4mSjIAuuX+lMq/FnStgm github.com/sassoftware/relic/v7 v7.6.2/go.mod h1:kjmP0IBVkJZ6gXeAu35/KCEfca//+PKM6vTAsyDPY+k= github.com/secure-systems-lab/go-securesystemslib v0.11.0 h1:iuCR9kcMFD4QurdKrGvPLoKZLv9YvwPYVr0473BdtFs= github.com/secure-systems-lab/go-securesystemslib v0.11.0/go.mod h1:+PMOTjUGwHj2vcZ+TFKlb1tXRbrdWE1LYDT5i9JC80Q= -github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= -github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= +github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b h1:h+3JX2VoWTFuyQEo87pStk/a99dzIO1mM9KxIyLPGTU= @@ -540,7 +536,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= @@ -576,12 +571,12 @@ github.com/transparency-dev/formats v0.1.1 h1:4bVHJc+KdBgpA1OJD1yjI+g0i5Z1graCpp github.com/transparency-dev/formats v0.1.1/go.mod h1:qtZ8goRuJ8FTBG9c9+Bj0rn2rUG7eG/AUTkr+Aw3jFw= github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4= github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A= -github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= -github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= +github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM= +github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/vbatts/tar-split v0.12.3 h1:Cd46rkGXI3Td4yrVNwU8ripbxFaQbmesqhjBUUYAJSw= github.com/vbatts/tar-split v0.12.3/go.mod h1:sQOc6OlqGCr7HkGx/IDBeKiTIvqhmj8KffNhEXG4Nq0= -github.com/vektah/gqlparser/v2 v2.5.30 h1:EqLwGAFLIzt1wpx1IPpY67DwUujF1OfzgEyDsLrN6kE= -github.com/vektah/gqlparser/v2 v2.5.30/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= +github.com/vektah/gqlparser/v2 v2.5.32 h1:k9QPJd4sEDTL+qB4ncPLflqTJ3MmjB9SrVzJrawpFSc= +github.com/vektah/gqlparser/v2 v2.5.32/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= diff --git a/vendor/github.com/beorn7/perks/LICENSE b/vendor/github.com/beorn7/perks/LICENSE deleted file mode 100644 index 339177be6636..000000000000 --- a/vendor/github.com/beorn7/perks/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (C) 2013 Blake Mizerany - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/beorn7/perks/quantile/exampledata.txt b/vendor/github.com/beorn7/perks/quantile/exampledata.txt deleted file mode 100644 index 1602287d7ce5..000000000000 --- a/vendor/github.com/beorn7/perks/quantile/exampledata.txt +++ /dev/null @@ -1,2388 +0,0 @@ -8 -5 -26 -12 -5 -235 -13 -6 -28 -30 -3 -3 -3 -3 -5 -2 -33 -7 -2 -4 -7 -12 -14 -5 -8 -3 -10 -4 -5 -3 -6 -6 -209 -20 -3 -10 -14 -3 -4 -6 -8 -5 -11 -7 -3 -2 -3 -3 -212 -5 -222 -4 -10 -10 -5 -6 -3 -8 -3 -10 -254 -220 -2 -3 -5 -24 -5 -4 -222 -7 -3 -3 -223 -8 -15 -12 -14 -14 -3 -2 -2 -3 -13 -3 -11 -4 -4 -6 -5 -7 -13 -5 -3 -5 -2 -5 -3 -5 -2 -7 -15 -17 -14 -3 -6 -6 -3 -17 -5 -4 -7 -6 -4 -4 -8 -6 -8 -3 -9 -3 -6 -3 -4 -5 -3 -3 -660 -4 -6 -10 -3 -6 -3 -2 -5 -13 -2 -4 -4 -10 -4 -8 -4 -3 -7 -9 -9 -3 -10 -37 -3 -13 -4 -12 -3 -6 -10 -8 -5 -21 -2 -3 -8 -3 -2 -3 -3 -4 -12 -2 -4 -8 -8 -4 -3 -2 -20 -1 -6 -32 -2 -11 -6 -18 -3 -8 -11 -3 -212 -3 -4 -2 -6 -7 -12 -11 -3 -2 -16 -10 -6 -4 -6 -3 -2 -7 -3 -2 -2 -2 -2 -5 -6 -4 -3 -10 -3 -4 -6 -5 -3 -4 -4 -5 -6 -4 -3 -4 -4 -5 -7 -5 -5 -3 -2 -7 -2 -4 -12 -4 -5 -6 -2 -4 -4 -8 -4 -15 -13 -7 -16 -5 -3 -23 -5 -5 -7 -3 -2 -9 -8 -7 -5 -8 -11 -4 -10 -76 -4 -47 -4 -3 -2 -7 -4 -2 -3 -37 -10 -4 -2 -20 -5 -4 -4 -10 -10 -4 -3 -7 -23 -240 -7 -13 -5 -5 -3 -3 -2 -5 -4 -2 -8 -7 -19 -2 -23 -8 -7 -2 -5 -3 -8 -3 -8 -13 -5 -5 -5 -2 -3 -23 -4 -9 -8 -4 -3 -3 -5 -220 -2 -3 -4 -6 -14 -3 -53 -6 -2 -5 -18 -6 -3 -219 -6 -5 -2 -5 -3 -6 -5 -15 -4 -3 -17 -3 -2 -4 -7 -2 -3 -3 -4 -4 -3 -2 -664 -6 -3 -23 -5 -5 -16 -5 -8 -2 -4 -2 -24 -12 -3 -2 -3 -5 -8 -3 -5 -4 -3 -14 -3 -5 -8 -2 -3 -7 -9 -4 -2 -3 -6 -8 -4 -3 -4 -6 -5 -3 -3 -6 -3 -19 -4 -4 -6 -3 -6 -3 -5 -22 -5 -4 -4 -3 -8 -11 -4 -9 -7 -6 -13 -4 -4 -4 -6 -17 -9 -3 -3 -3 -4 -3 -221 -5 -11 -3 -4 -2 -12 -6 -3 -5 -7 -5 -7 -4 -9 -7 -14 -37 -19 -217 -16 -3 -5 -2 -2 -7 -19 -7 -6 -7 -4 -24 -5 -11 -4 -7 -7 -9 -13 -3 -4 -3 -6 -28 -4 -4 -5 -5 -2 -5 -6 -4 -4 -6 -10 -5 -4 -3 -2 -3 -3 -6 -5 -5 -4 -3 -2 -3 -7 -4 -6 -18 -16 -8 -16 -4 -5 -8 -6 -9 -13 -1545 -6 -215 -6 -5 -6 -3 -45 -31 -5 -2 -2 -4 -3 -3 -2 -5 -4 -3 -5 -7 -7 -4 -5 -8 -5 -4 -749 -2 -31 -9 -11 -2 -11 -5 -4 -4 -7 -9 -11 -4 -5 -4 -7 -3 -4 -6 -2 -15 -3 -4 -3 -4 -3 -5 -2 -13 -5 -5 -3 -3 -23 -4 -4 -5 -7 -4 -13 -2 -4 -3 -4 -2 -6 -2 -7 -3 -5 -5 -3 -29 -5 -4 -4 -3 -10 -2 -3 -79 -16 -6 -6 -7 -7 -3 -5 -5 -7 -4 -3 -7 -9 -5 -6 -5 -9 -6 -3 -6 -4 -17 -2 -10 -9 -3 -6 -2 -3 -21 -22 -5 -11 -4 -2 -17 -2 -224 -2 -14 -3 -4 -4 -2 -4 -4 -4 -4 -5 -3 -4 -4 -10 -2 -6 -3 -3 -5 -7 -2 -7 -5 -6 -3 -218 -2 -2 -5 -2 -6 -3 -5 -222 -14 -6 -33 -3 -2 -5 -3 -3 -3 -9 -5 -3 -3 -2 -7 -4 -3 -4 -3 -5 -6 -5 -26 -4 -13 -9 -7 -3 -221 -3 -3 -4 -4 -4 -4 -2 -18 -5 -3 -7 -9 -6 -8 -3 -10 -3 -11 -9 -5 -4 -17 -5 -5 -6 -6 -3 -2 -4 -12 -17 -6 -7 -218 -4 -2 -4 -10 -3 -5 -15 -3 -9 -4 -3 -3 -6 -29 -3 -3 -4 -5 -5 -3 -8 -5 -6 -6 -7 -5 -3 -5 -3 -29 -2 -31 -5 -15 -24 -16 -5 -207 -4 -3 -3 -2 -15 -4 -4 -13 -5 -5 -4 -6 -10 -2 -7 -8 -4 -6 -20 -5 -3 -4 -3 -12 -12 -5 -17 -7 -3 -3 -3 -6 -10 -3 -5 -25 -80 -4 -9 -3 -2 -11 -3 -3 -2 -3 -8 -7 -5 -5 -19 -5 -3 -3 -12 -11 -2 -6 -5 -5 -5 -3 -3 -3 -4 -209 -14 -3 -2 -5 -19 -4 -4 -3 -4 -14 -5 -6 -4 -13 -9 -7 -4 -7 -10 -2 -9 -5 -7 -2 -8 -4 -6 -5 -5 -222 -8 -7 -12 -5 -216 -3 -4 -4 -6 -3 -14 -8 -7 -13 -4 -3 -3 -3 -3 -17 -5 -4 -3 -33 -6 -6 -33 -7 -5 -3 -8 -7 -5 -2 -9 -4 -2 -233 -24 -7 -4 -8 -10 -3 -4 -15 -2 -16 -3 -3 -13 -12 -7 -5 -4 -207 -4 -2 -4 -27 -15 -2 -5 -2 -25 -6 -5 -5 -6 -13 -6 -18 -6 -4 -12 -225 -10 -7 -5 -2 -2 -11 -4 -14 -21 -8 -10 -3 -5 -4 -232 -2 -5 -5 -3 -7 -17 -11 -6 -6 -23 -4 -6 -3 -5 -4 -2 -17 -3 -6 -5 -8 -3 -2 -2 -14 -9 -4 -4 -2 -5 -5 -3 -7 -6 -12 -6 -10 -3 -6 -2 -2 -19 -5 -4 -4 -9 -2 -4 -13 -3 -5 -6 -3 -6 -5 -4 -9 -6 -3 -5 -7 -3 -6 -6 -4 -3 -10 -6 -3 -221 -3 -5 -3 -6 -4 -8 -5 -3 -6 -4 -4 -2 -54 -5 -6 -11 -3 -3 -4 -4 -4 -3 -7 -3 -11 -11 -7 -10 -6 -13 -223 -213 -15 -231 -7 -3 -7 -228 -2 -3 -4 -4 -5 -6 -7 -4 -13 -3 -4 -5 -3 -6 -4 -6 -7 -2 -4 -3 -4 -3 -3 -6 -3 -7 -3 -5 -18 -5 -6 -8 -10 -3 -3 -3 -2 -4 -2 -4 -4 -5 -6 -6 -4 -10 -13 -3 -12 -5 -12 -16 -8 -4 -19 -11 -2 -4 -5 -6 -8 -5 -6 -4 -18 -10 -4 -2 -216 -6 -6 -6 -2 -4 -12 -8 -3 -11 -5 -6 -14 -5 -3 -13 -4 -5 -4 -5 -3 -28 -6 -3 -7 -219 -3 -9 -7 -3 -10 -6 -3 -4 -19 -5 -7 -11 -6 -15 -19 -4 -13 -11 -3 -7 -5 -10 -2 -8 -11 -2 -6 -4 -6 -24 -6 -3 -3 -3 -3 -6 -18 -4 -11 -4 -2 -5 -10 -8 -3 -9 -5 -3 -4 -5 -6 -2 -5 -7 -4 -4 -14 -6 -4 -4 -5 -5 -7 -2 -4 -3 -7 -3 -3 -6 -4 -5 -4 -4 -4 -3 -3 -3 -3 -8 -14 -2 -3 -5 -3 -2 -4 -5 -3 -7 -3 -3 -18 -3 -4 -4 -5 -7 -3 -3 -3 -13 -5 -4 -8 -211 -5 -5 -3 -5 -2 -5 -4 -2 -655 -6 -3 -5 -11 -2 -5 -3 -12 -9 -15 -11 -5 -12 -217 -2 -6 -17 -3 -3 -207 -5 -5 -4 -5 -9 -3 -2 -8 -5 -4 -3 -2 -5 -12 -4 -14 -5 -4 -2 -13 -5 -8 -4 -225 -4 -3 -4 -5 -4 -3 -3 -6 -23 -9 -2 -6 -7 -233 -4 -4 -6 -18 -3 -4 -6 -3 -4 -4 -2 -3 -7 -4 -13 -227 -4 -3 -5 -4 -2 -12 -9 -17 -3 -7 -14 -6 -4 -5 -21 -4 -8 -9 -2 -9 -25 -16 -3 -6 -4 -7 -8 -5 -2 -3 -5 -4 -3 -3 -5 -3 -3 -3 -2 -3 -19 -2 -4 -3 -4 -2 -3 -4 -4 -2 -4 -3 -3 -3 -2 -6 -3 -17 -5 -6 -4 -3 -13 -5 -3 -3 -3 -4 -9 -4 -2 -14 -12 -4 -5 -24 -4 -3 -37 -12 -11 -21 -3 -4 -3 -13 -4 -2 -3 -15 -4 -11 -4 -4 -3 -8 -3 -4 -4 -12 -8 -5 -3 -3 -4 -2 -220 -3 -5 -223 -3 -3 -3 -10 -3 -15 -4 -241 -9 -7 -3 -6 -6 -23 -4 -13 -7 -3 -4 -7 -4 -9 -3 -3 -4 -10 -5 -5 -1 -5 -24 -2 -4 -5 -5 -6 -14 -3 -8 -2 -3 -5 -13 -13 -3 -5 -2 -3 -15 -3 -4 -2 -10 -4 -4 -4 -5 -5 -3 -5 -3 -4 -7 -4 -27 -3 -6 -4 -15 -3 -5 -6 -6 -5 -4 -8 -3 -9 -2 -6 -3 -4 -3 -7 -4 -18 -3 -11 -3 -3 -8 -9 -7 -24 -3 -219 -7 -10 -4 -5 -9 -12 -2 -5 -4 -4 -4 -3 -3 -19 -5 -8 -16 -8 -6 -22 -3 -23 -3 -242 -9 -4 -3 -3 -5 -7 -3 -3 -5 -8 -3 -7 -5 -14 -8 -10 -3 -4 -3 -7 -4 -6 -7 -4 -10 -4 -3 -11 -3 -7 -10 -3 -13 -6 -8 -12 -10 -5 -7 -9 -3 -4 -7 -7 -10 -8 -30 -9 -19 -4 -3 -19 -15 -4 -13 -3 -215 -223 -4 -7 -4 -8 -17 -16 -3 -7 -6 -5 -5 -4 -12 -3 -7 -4 -4 -13 -4 -5 -2 -5 -6 -5 -6 -6 -7 -10 -18 -23 -9 -3 -3 -6 -5 -2 -4 -2 -7 -3 -3 -2 -5 -5 -14 -10 -224 -6 -3 -4 -3 -7 -5 -9 -3 -6 -4 -2 -5 -11 -4 -3 -3 -2 -8 -4 -7 -4 -10 -7 -3 -3 -18 -18 -17 -3 -3 -3 -4 -5 -3 -3 -4 -12 -7 -3 -11 -13 -5 -4 -7 -13 -5 -4 -11 -3 -12 -3 -6 -4 -4 -21 -4 -6 -9 -5 -3 -10 -8 -4 -6 -4 -4 -6 -5 -4 -8 -6 -4 -6 -4 -4 -5 -9 -6 -3 -4 -2 -9 -3 -18 -2 -4 -3 -13 -3 -6 -6 -8 -7 -9 -3 -2 -16 -3 -4 -6 -3 -2 -33 -22 -14 -4 -9 -12 -4 -5 -6 -3 -23 -9 -4 -3 -5 -5 -3 -4 -5 -3 -5 -3 -10 -4 -5 -5 -8 -4 -4 -6 -8 -5 -4 -3 -4 -6 -3 -3 -3 -5 -9 -12 -6 -5 -9 -3 -5 -3 -2 -2 -2 -18 -3 -2 -21 -2 -5 -4 -6 -4 -5 -10 -3 -9 -3 -2 -10 -7 -3 -6 -6 -4 -4 -8 -12 -7 -3 -7 -3 -3 -9 -3 -4 -5 -4 -4 -5 -5 -10 -15 -4 -4 -14 -6 -227 -3 -14 -5 -216 -22 -5 -4 -2 -2 -6 -3 -4 -2 -9 -9 -4 -3 -28 -13 -11 -4 -5 -3 -3 -2 -3 -3 -5 -3 -4 -3 -5 -23 -26 -3 -4 -5 -6 -4 -6 -3 -5 -5 -3 -4 -3 -2 -2 -2 -7 -14 -3 -6 -7 -17 -2 -2 -15 -14 -16 -4 -6 -7 -13 -6 -4 -5 -6 -16 -3 -3 -28 -3 -6 -15 -3 -9 -2 -4 -6 -3 -3 -22 -4 -12 -6 -7 -2 -5 -4 -10 -3 -16 -6 -9 -2 -5 -12 -7 -5 -5 -5 -5 -2 -11 -9 -17 -4 -3 -11 -7 -3 -5 -15 -4 -3 -4 -211 -8 -7 -5 -4 -7 -6 -7 -6 -3 -6 -5 -6 -5 -3 -4 -4 -26 -4 -6 -10 -4 -4 -3 -2 -3 -3 -4 -5 -9 -3 -9 -4 -4 -5 -5 -8 -2 -4 -2 -3 -8 -4 -11 -19 -5 -8 -6 -3 -5 -6 -12 -3 -2 -4 -16 -12 -3 -4 -4 -8 -6 -5 -6 -6 -219 -8 -222 -6 -16 -3 -13 -19 -5 -4 -3 -11 -6 -10 -4 -7 -7 -12 -5 -3 -3 -5 -6 -10 -3 -8 -2 -5 -4 -7 -2 -4 -4 -2 -12 -9 -6 -4 -2 -40 -2 -4 -10 -4 -223 -4 -2 -20 -6 -7 -24 -5 -4 -5 -2 -20 -16 -6 -5 -13 -2 -3 -3 -19 -3 -2 -4 -5 -6 -7 -11 -12 -5 -6 -7 -7 -3 -5 -3 -5 -3 -14 -3 -4 -4 -2 -11 -1 -7 -3 -9 -6 -11 -12 -5 -8 -6 -221 -4 -2 -12 -4 -3 -15 -4 -5 -226 -7 -218 -7 -5 -4 -5 -18 -4 -5 -9 -4 -4 -2 -9 -18 -18 -9 -5 -6 -6 -3 -3 -7 -3 -5 -4 -4 -4 -12 -3 -6 -31 -5 -4 -7 -3 -6 -5 -6 -5 -11 -2 -2 -11 -11 -6 -7 -5 -8 -7 -10 -5 -23 -7 -4 -3 -5 -34 -2 -5 -23 -7 -3 -6 -8 -4 -4 -4 -2 -5 -3 -8 -5 -4 -8 -25 -2 -3 -17 -8 -3 -4 -8 -7 -3 -15 -6 -5 -7 -21 -9 -5 -6 -6 -5 -3 -2 -3 -10 -3 -6 -3 -14 -7 -4 -4 -8 -7 -8 -2 -6 -12 -4 -213 -6 -5 -21 -8 -2 -5 -23 -3 -11 -2 -3 -6 -25 -2 -3 -6 -7 -6 -6 -4 -4 -6 -3 -17 -9 -7 -6 -4 -3 -10 -7 -2 -3 -3 -3 -11 -8 -3 -7 -6 -4 -14 -36 -3 -4 -3 -3 -22 -13 -21 -4 -2 -7 -4 -4 -17 -15 -3 -7 -11 -2 -4 -7 -6 -209 -6 -3 -2 -2 -24 -4 -9 -4 -3 -3 -3 -29 -2 -2 -4 -3 -3 -5 -4 -6 -3 -3 -2 -4 diff --git a/vendor/github.com/beorn7/perks/quantile/stream.go b/vendor/github.com/beorn7/perks/quantile/stream.go deleted file mode 100644 index d7d14f8eb63d..000000000000 --- a/vendor/github.com/beorn7/perks/quantile/stream.go +++ /dev/null @@ -1,316 +0,0 @@ -// Package quantile computes approximate quantiles over an unbounded data -// stream within low memory and CPU bounds. -// -// A small amount of accuracy is traded to achieve the above properties. -// -// Multiple streams can be merged before calling Query to generate a single set -// of results. This is meaningful when the streams represent the same type of -// data. See Merge and Samples. -// -// For more detailed information about the algorithm used, see: -// -// Effective Computation of Biased Quantiles over Data Streams -// -// http://www.cs.rutgers.edu/~muthu/bquant.pdf -package quantile - -import ( - "math" - "sort" -) - -// Sample holds an observed value and meta information for compression. JSON -// tags have been added for convenience. -type Sample struct { - Value float64 `json:",string"` - Width float64 `json:",string"` - Delta float64 `json:",string"` -} - -// Samples represents a slice of samples. It implements sort.Interface. -type Samples []Sample - -func (a Samples) Len() int { return len(a) } -func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value } -func (a Samples) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -type invariant func(s *stream, r float64) float64 - -// NewLowBiased returns an initialized Stream for low-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the lower ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within (1±Epsilon)*Quantile. -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewLowBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * r - } - return newStream(ƒ) -} - -// NewHighBiased returns an initialized Stream for high-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the higher ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewHighBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * (s.n - r) - } - return newStream(ƒ) -} - -// NewTargeted returns an initialized Stream concerned with a particular set of -// quantile values that are supplied a priori. Knowing these a priori reduces -// space and computation time. The targets map maps the desired quantiles to -// their absolute errors, i.e. the true quantile of a value returned by a query -// is guaranteed to be within (Quantile±Epsilon). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties. -func NewTargeted(targetMap map[float64]float64) *Stream { - // Convert map to slice to avoid slow iterations on a map. - // ƒ is called on the hot path, so converting the map to a slice - // beforehand results in significant CPU savings. - targets := targetMapToSlice(targetMap) - - ƒ := func(s *stream, r float64) float64 { - var m = math.MaxFloat64 - var f float64 - for _, t := range targets { - if t.quantile*s.n <= r { - f = (2 * t.epsilon * r) / t.quantile - } else { - f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile) - } - if f < m { - m = f - } - } - return m - } - return newStream(ƒ) -} - -type target struct { - quantile float64 - epsilon float64 -} - -func targetMapToSlice(targetMap map[float64]float64) []target { - targets := make([]target, 0, len(targetMap)) - - for quantile, epsilon := range targetMap { - t := target{ - quantile: quantile, - epsilon: epsilon, - } - targets = append(targets, t) - } - - return targets -} - -// Stream computes quantiles for a stream of float64s. It is not thread-safe by -// design. Take care when using across multiple goroutines. -type Stream struct { - *stream - b Samples - sorted bool -} - -func newStream(ƒ invariant) *Stream { - x := &stream{ƒ: ƒ} - return &Stream{x, make(Samples, 0, 500), true} -} - -// Insert inserts v into the stream. -func (s *Stream) Insert(v float64) { - s.insert(Sample{Value: v, Width: 1}) -} - -func (s *Stream) insert(sample Sample) { - s.b = append(s.b, sample) - s.sorted = false - if len(s.b) == cap(s.b) { - s.flush() - } -} - -// Query returns the computed qth percentiles value. If s was created with -// NewTargeted, and q is not in the set of quantiles provided a priori, Query -// will return an unspecified result. -func (s *Stream) Query(q float64) float64 { - if !s.flushed() { - // Fast path when there hasn't been enough data for a flush; - // this also yields better accuracy for small sets of data. - l := len(s.b) - if l == 0 { - return 0 - } - i := int(math.Ceil(float64(l) * q)) - if i > 0 { - i -= 1 - } - s.maybeSort() - return s.b[i].Value - } - s.flush() - return s.stream.query(q) -} - -// Merge merges samples into the underlying streams samples. This is handy when -// merging multiple streams from separate threads, database shards, etc. -// -// ATTENTION: This method is broken and does not yield correct results. The -// underlying algorithm is not capable of merging streams correctly. -func (s *Stream) Merge(samples Samples) { - sort.Sort(samples) - s.stream.merge(samples) -} - -// Reset reinitializes and clears the list reusing the samples buffer memory. -func (s *Stream) Reset() { - s.stream.reset() - s.b = s.b[:0] -} - -// Samples returns stream samples held by s. -func (s *Stream) Samples() Samples { - if !s.flushed() { - return s.b - } - s.flush() - return s.stream.samples() -} - -// Count returns the total number of samples observed in the stream -// since initialization. -func (s *Stream) Count() int { - return len(s.b) + s.stream.count() -} - -func (s *Stream) flush() { - s.maybeSort() - s.stream.merge(s.b) - s.b = s.b[:0] -} - -func (s *Stream) maybeSort() { - if !s.sorted { - s.sorted = true - sort.Sort(s.b) - } -} - -func (s *Stream) flushed() bool { - return len(s.stream.l) > 0 -} - -type stream struct { - n float64 - l []Sample - ƒ invariant -} - -func (s *stream) reset() { - s.l = s.l[:0] - s.n = 0 -} - -func (s *stream) insert(v float64) { - s.merge(Samples{{v, 1, 0}}) -} - -func (s *stream) merge(samples Samples) { - // TODO(beorn7): This tries to merge not only individual samples, but - // whole summaries. The paper doesn't mention merging summaries at - // all. Unittests show that the merging is inaccurate. Find out how to - // do merges properly. - var r float64 - i := 0 - for _, sample := range samples { - for ; i < len(s.l); i++ { - c := s.l[i] - if c.Value > sample.Value { - // Insert at position i. - s.l = append(s.l, Sample{}) - copy(s.l[i+1:], s.l[i:]) - s.l[i] = Sample{ - sample.Value, - sample.Width, - math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1), - // TODO(beorn7): How to calculate delta correctly? - } - i++ - goto inserted - } - r += c.Width - } - s.l = append(s.l, Sample{sample.Value, sample.Width, 0}) - i++ - inserted: - s.n += sample.Width - r += sample.Width - } - s.compress() -} - -func (s *stream) count() int { - return int(s.n) -} - -func (s *stream) query(q float64) float64 { - t := math.Ceil(q * s.n) - t += math.Ceil(s.ƒ(s, t) / 2) - p := s.l[0] - var r float64 - for _, c := range s.l[1:] { - r += p.Width - if r+c.Width+c.Delta > t { - return p.Value - } - p = c - } - return p.Value -} - -func (s *stream) compress() { - if len(s.l) < 2 { - return - } - x := s.l[len(s.l)-1] - xi := len(s.l) - 1 - r := s.n - 1 - x.Width - - for i := len(s.l) - 2; i >= 0; i-- { - c := s.l[i] - if c.Width+x.Width+x.Delta <= s.ƒ(s, r) { - x.Width += c.Width - s.l[xi] = x - // Remove element at i. - copy(s.l[i:], s.l[i+1:]) - s.l = s.l[:len(s.l)-1] - xi -= 1 - } else { - x = c - xi = i - } - r -= c.Width - } -} - -func (s *stream) samples() Samples { - samples := make(Samples, len(s.l)) - copy(samples, s.l) - return samples -} diff --git a/vendor/github.com/go-ini/ini/.editorconfig b/vendor/github.com/go-ini/ini/.editorconfig deleted file mode 100644 index 4a2d9180f96f..000000000000 --- a/vendor/github.com/go-ini/ini/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -# http://editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[*_test.go] -trim_trailing_whitespace = false diff --git a/vendor/github.com/go-ini/ini/.gitignore b/vendor/github.com/go-ini/ini/.gitignore deleted file mode 100644 index 588388bda28d..000000000000 --- a/vendor/github.com/go-ini/ini/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -testdata/conf_out.ini -ini.sublime-project -ini.sublime-workspace -testdata/conf_reflect.ini -.idea -/.vscode -.DS_Store diff --git a/vendor/github.com/go-ini/ini/.golangci.yml b/vendor/github.com/go-ini/ini/.golangci.yml deleted file mode 100644 index 631e369254d3..000000000000 --- a/vendor/github.com/go-ini/ini/.golangci.yml +++ /dev/null @@ -1,27 +0,0 @@ -linters-settings: - staticcheck: - checks: [ - "all", - "-SA1019" # There are valid use cases of strings.Title - ] - nakedret: - max-func-lines: 0 # Disallow any unnamed return statement - -linters: - enable: - - deadcode - - errcheck - - gosimple - - govet - - ineffassign - - staticcheck - - structcheck - - typecheck - - unused - - varcheck - - nakedret - - gofmt - - rowserrcheck - - unconvert - - goimports - - unparam diff --git a/vendor/github.com/go-ini/ini/LICENSE b/vendor/github.com/go-ini/ini/LICENSE deleted file mode 100644 index d361bbcdf5c9..000000000000 --- a/vendor/github.com/go-ini/ini/LICENSE +++ /dev/null @@ -1,191 +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: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -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 -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright 2014 Unknwon - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/go-ini/ini/Makefile b/vendor/github.com/go-ini/ini/Makefile deleted file mode 100644 index f3b0dae2d298..000000000000 --- a/vendor/github.com/go-ini/ini/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: build test bench vet coverage - -build: vet bench - -test: - go test -v -cover -race - -bench: - go test -v -cover -test.bench=. -test.benchmem - -vet: - go vet - -coverage: - go test -coverprofile=c.out && go tool cover -html=c.out && rm c.out diff --git a/vendor/github.com/go-ini/ini/README.md b/vendor/github.com/go-ini/ini/README.md deleted file mode 100644 index 30606d9700a8..000000000000 --- a/vendor/github.com/go-ini/ini/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# INI - -[![GitHub Workflow Status](https://img.shields.io/github/checks-status/go-ini/ini/main?logo=github&style=for-the-badge)](https://github.com/go-ini/ini/actions?query=branch%3Amain) -[![codecov](https://img.shields.io/codecov/c/github/go-ini/ini/master?logo=codecov&style=for-the-badge)](https://codecov.io/gh/go-ini/ini) -[![GoDoc](https://img.shields.io/badge/GoDoc-Reference-blue?style=for-the-badge&logo=go)](https://pkg.go.dev/github.com/go-ini/ini?tab=doc) -[![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg?style=for-the-badge&logo=sourcegraph)](https://sourcegraph.com/github.com/go-ini/ini) - -![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200) - -Package ini provides INI file read and write functionality in Go. - -## Features - -- Load from multiple data sources(file, `[]byte`, `io.Reader` and `io.ReadCloser`) with overwrites. -- Read with recursion values. -- Read with parent-child sections. -- Read with auto-increment key names. -- Read with multiple-line values. -- Read with tons of helper methods. -- Read and convert values to Go types. -- Read and **WRITE** comments of sections and keys. -- Manipulate sections, keys and comments with ease. -- Keep sections and keys in order as you parse and save. - -## Installation - -The minimum requirement of Go is **1.13**. - -```sh -$ go get gopkg.in/ini.v1 -``` - -Please add `-u` flag to update in the future. - -## Getting Help - -- [Getting Started](https://ini.unknwon.io/docs/intro/getting_started) -- [API Documentation](https://gowalker.org/gopkg.in/ini.v1) -- 中国大陆镜像:https://ini.unknwon.cn - -## License - -This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text. diff --git a/vendor/github.com/go-ini/ini/codecov.yml b/vendor/github.com/go-ini/ini/codecov.yml deleted file mode 100644 index e02ec84bc05f..000000000000 --- a/vendor/github.com/go-ini/ini/codecov.yml +++ /dev/null @@ -1,16 +0,0 @@ -coverage: - range: "60...95" - status: - project: - default: - threshold: 1% - informational: true - patch: - defualt: - only_pulls: true - informational: true - -comment: - layout: 'diff' - -github_checks: false diff --git a/vendor/github.com/go-ini/ini/data_source.go b/vendor/github.com/go-ini/ini/data_source.go deleted file mode 100644 index c3a541f1d1b5..000000000000 --- a/vendor/github.com/go-ini/ini/data_source.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" -) - -var ( - _ dataSource = (*sourceFile)(nil) - _ dataSource = (*sourceData)(nil) - _ dataSource = (*sourceReadCloser)(nil) -) - -// dataSource is an interface that returns object which can be read and closed. -type dataSource interface { - ReadCloser() (io.ReadCloser, error) -} - -// sourceFile represents an object that contains content on the local file system. -type sourceFile struct { - name string -} - -func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) { - return os.Open(s.name) -} - -// sourceData represents an object that contains content in memory. -type sourceData struct { - data []byte -} - -func (s *sourceData) ReadCloser() (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewReader(s.data)), nil -} - -// sourceReadCloser represents an input stream with Close method. -type sourceReadCloser struct { - reader io.ReadCloser -} - -func (s *sourceReadCloser) ReadCloser() (io.ReadCloser, error) { - return s.reader, nil -} - -func parseDataSource(source interface{}) (dataSource, error) { - switch s := source.(type) { - case string: - return sourceFile{s}, nil - case []byte: - return &sourceData{s}, nil - case io.ReadCloser: - return &sourceReadCloser{s}, nil - case io.Reader: - return &sourceReadCloser{ioutil.NopCloser(s)}, nil - default: - return nil, fmt.Errorf("error parsing data source: unknown type %q", s) - } -} diff --git a/vendor/github.com/go-ini/ini/deprecated.go b/vendor/github.com/go-ini/ini/deprecated.go deleted file mode 100644 index 48b8e66d6d6f..000000000000 --- a/vendor/github.com/go-ini/ini/deprecated.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -var ( - // Deprecated: Use "DefaultSection" instead. - DEFAULT_SECTION = DefaultSection - // Deprecated: AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE. - AllCapsUnderscore = SnackCase -) diff --git a/vendor/github.com/go-ini/ini/error.go b/vendor/github.com/go-ini/ini/error.go deleted file mode 100644 index f66bc94b8b69..000000000000 --- a/vendor/github.com/go-ini/ini/error.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2016 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "fmt" -) - -// ErrDelimiterNotFound indicates the error type of no delimiter is found which there should be one. -type ErrDelimiterNotFound struct { - Line string -} - -// IsErrDelimiterNotFound returns true if the given error is an instance of ErrDelimiterNotFound. -func IsErrDelimiterNotFound(err error) bool { - _, ok := err.(ErrDelimiterNotFound) - return ok -} - -func (err ErrDelimiterNotFound) Error() string { - return fmt.Sprintf("key-value delimiter not found: %s", err.Line) -} - -// ErrEmptyKeyName indicates the error type of no key name is found which there should be one. -type ErrEmptyKeyName struct { - Line string -} - -// IsErrEmptyKeyName returns true if the given error is an instance of ErrEmptyKeyName. -func IsErrEmptyKeyName(err error) bool { - _, ok := err.(ErrEmptyKeyName) - return ok -} - -func (err ErrEmptyKeyName) Error() string { - return fmt.Sprintf("empty key name: %s", err.Line) -} diff --git a/vendor/github.com/go-ini/ini/file.go b/vendor/github.com/go-ini/ini/file.go deleted file mode 100644 index f8b22408be51..000000000000 --- a/vendor/github.com/go-ini/ini/file.go +++ /dev/null @@ -1,541 +0,0 @@ -// Copyright 2017 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "strings" - "sync" -) - -// File represents a combination of one or more INI files in memory. -type File struct { - options LoadOptions - dataSources []dataSource - - // Should make things safe, but sometimes doesn't matter. - BlockMode bool - lock sync.RWMutex - - // To keep data in order. - sectionList []string - // To keep track of the index of a section with same name. - // This meta list is only used with non-unique section names are allowed. - sectionIndexes []int - - // Actual data is stored here. - sections map[string][]*Section - - NameMapper - ValueMapper -} - -// newFile initializes File object with given data sources. -func newFile(dataSources []dataSource, opts LoadOptions) *File { - if len(opts.KeyValueDelimiters) == 0 { - opts.KeyValueDelimiters = "=:" - } - if len(opts.KeyValueDelimiterOnWrite) == 0 { - opts.KeyValueDelimiterOnWrite = "=" - } - if len(opts.ChildSectionDelimiter) == 0 { - opts.ChildSectionDelimiter = "." - } - - return &File{ - BlockMode: true, - dataSources: dataSources, - sections: make(map[string][]*Section), - options: opts, - } -} - -// Empty returns an empty file object. -func Empty(opts ...LoadOptions) *File { - var opt LoadOptions - if len(opts) > 0 { - opt = opts[0] - } - - // Ignore error here, we are sure our data is good. - f, _ := LoadSources(opt, []byte("")) - return f -} - -// NewSection creates a new section. -func (f *File) NewSection(name string) (*Section, error) { - if len(name) == 0 { - return nil, errors.New("empty section name") - } - - if (f.options.Insensitive || f.options.InsensitiveSections) && name != DefaultSection { - name = strings.ToLower(name) - } - - if f.BlockMode { - f.lock.Lock() - defer f.lock.Unlock() - } - - if !f.options.AllowNonUniqueSections && inSlice(name, f.sectionList) { - return f.sections[name][0], nil - } - - f.sectionList = append(f.sectionList, name) - - // NOTE: Append to indexes must happen before appending to sections, - // otherwise index will have off-by-one problem. - f.sectionIndexes = append(f.sectionIndexes, len(f.sections[name])) - - sec := newSection(f, name) - f.sections[name] = append(f.sections[name], sec) - - return sec, nil -} - -// NewRawSection creates a new section with an unparseable body. -func (f *File) NewRawSection(name, body string) (*Section, error) { - section, err := f.NewSection(name) - if err != nil { - return nil, err - } - - section.isRawSection = true - section.rawBody = body - return section, nil -} - -// NewSections creates a list of sections. -func (f *File) NewSections(names ...string) (err error) { - for _, name := range names { - if _, err = f.NewSection(name); err != nil { - return err - } - } - return nil -} - -// GetSection returns section by given name. -func (f *File) GetSection(name string) (*Section, error) { - secs, err := f.SectionsByName(name) - if err != nil { - return nil, err - } - - return secs[0], err -} - -// HasSection returns true if the file contains a section with given name. -func (f *File) HasSection(name string) bool { - section, _ := f.GetSection(name) - return section != nil -} - -// SectionsByName returns all sections with given name. -func (f *File) SectionsByName(name string) ([]*Section, error) { - if len(name) == 0 { - name = DefaultSection - } - if f.options.Insensitive || f.options.InsensitiveSections { - name = strings.ToLower(name) - } - - if f.BlockMode { - f.lock.RLock() - defer f.lock.RUnlock() - } - - secs := f.sections[name] - if len(secs) == 0 { - return nil, fmt.Errorf("section %q does not exist", name) - } - - return secs, nil -} - -// Section assumes named section exists and returns a zero-value when not. -func (f *File) Section(name string) *Section { - sec, err := f.GetSection(name) - if err != nil { - if name == "" { - name = DefaultSection - } - sec, _ = f.NewSection(name) - return sec - } - return sec -} - -// SectionWithIndex assumes named section exists and returns a new section when not. -func (f *File) SectionWithIndex(name string, index int) *Section { - secs, err := f.SectionsByName(name) - if err != nil || len(secs) <= index { - // NOTE: It's OK here because the only possible error is empty section name, - // but if it's empty, this piece of code won't be executed. - newSec, _ := f.NewSection(name) - return newSec - } - - return secs[index] -} - -// Sections returns a list of Section stored in the current instance. -func (f *File) Sections() []*Section { - if f.BlockMode { - f.lock.RLock() - defer f.lock.RUnlock() - } - - sections := make([]*Section, len(f.sectionList)) - for i, name := range f.sectionList { - sections[i] = f.sections[name][f.sectionIndexes[i]] - } - return sections -} - -// ChildSections returns a list of child sections of given section name. -func (f *File) ChildSections(name string) []*Section { - return f.Section(name).ChildSections() -} - -// SectionStrings returns list of section names. -func (f *File) SectionStrings() []string { - list := make([]string, len(f.sectionList)) - copy(list, f.sectionList) - return list -} - -// DeleteSection deletes a section or all sections with given name. -func (f *File) DeleteSection(name string) { - secs, err := f.SectionsByName(name) - if err != nil { - return - } - - for i := 0; i < len(secs); i++ { - // For non-unique sections, it is always needed to remove the first one so - // in the next iteration, the subsequent section continue having index 0. - // Ignoring the error as index 0 never returns an error. - _ = f.DeleteSectionWithIndex(name, 0) - } -} - -// DeleteSectionWithIndex deletes a section with given name and index. -func (f *File) DeleteSectionWithIndex(name string, index int) error { - if !f.options.AllowNonUniqueSections && index != 0 { - return fmt.Errorf("delete section with non-zero index is only allowed when non-unique sections is enabled") - } - - if len(name) == 0 { - name = DefaultSection - } - if f.options.Insensitive || f.options.InsensitiveSections { - name = strings.ToLower(name) - } - - if f.BlockMode { - f.lock.Lock() - defer f.lock.Unlock() - } - - // Count occurrences of the sections - occurrences := 0 - - sectionListCopy := make([]string, len(f.sectionList)) - copy(sectionListCopy, f.sectionList) - - for i, s := range sectionListCopy { - if s != name { - continue - } - - if occurrences == index { - if len(f.sections[name]) <= 1 { - delete(f.sections, name) // The last one in the map - } else { - f.sections[name] = append(f.sections[name][:index], f.sections[name][index+1:]...) - } - - // Fix section lists - f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...) - f.sectionIndexes = append(f.sectionIndexes[:i], f.sectionIndexes[i+1:]...) - - } else if occurrences > index { - // Fix the indices of all following sections with this name. - f.sectionIndexes[i-1]-- - } - - occurrences++ - } - - return nil -} - -func (f *File) reload(s dataSource) error { - r, err := s.ReadCloser() - if err != nil { - return err - } - defer r.Close() - - return f.parse(r) -} - -// Reload reloads and parses all data sources. -func (f *File) Reload() (err error) { - for _, s := range f.dataSources { - if err = f.reload(s); err != nil { - // In loose mode, we create an empty default section for nonexistent files. - if os.IsNotExist(err) && f.options.Loose { - _ = f.parse(bytes.NewBuffer(nil)) - continue - } - return err - } - if f.options.ShortCircuit { - return nil - } - } - return nil -} - -// Append appends one or more data sources and reloads automatically. -func (f *File) Append(source interface{}, others ...interface{}) error { - ds, err := parseDataSource(source) - if err != nil { - return err - } - f.dataSources = append(f.dataSources, ds) - for _, s := range others { - ds, err = parseDataSource(s) - if err != nil { - return err - } - f.dataSources = append(f.dataSources, ds) - } - return f.Reload() -} - -func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { - equalSign := DefaultFormatLeft + f.options.KeyValueDelimiterOnWrite + DefaultFormatRight - - if PrettyFormat || PrettyEqual { - equalSign = fmt.Sprintf(" %s ", f.options.KeyValueDelimiterOnWrite) - } - - // Use buffer to make sure target is safe until finish encoding. - buf := bytes.NewBuffer(nil) - lastSectionIdx := len(f.sectionList) - 1 - for i, sname := range f.sectionList { - sec := f.SectionWithIndex(sname, f.sectionIndexes[i]) - if len(sec.Comment) > 0 { - // Support multiline comments - lines := strings.Split(sec.Comment, LineBreak) - for i := range lines { - if lines[i][0] != '#' && lines[i][0] != ';' { - lines[i] = "; " + lines[i] - } else { - lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) - } - - if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { - return nil, err - } - } - } - - if i > 0 || DefaultHeader || (i == 0 && strings.ToUpper(sec.name) != DefaultSection) { - if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil { - return nil, err - } - } else { - // Write nothing if default section is empty - if len(sec.keyList) == 0 { - continue - } - } - - isLastSection := i == lastSectionIdx - if sec.isRawSection { - if _, err := buf.WriteString(sec.rawBody); err != nil { - return nil, err - } - - if PrettySection && !isLastSection { - // Put a line between sections - if _, err := buf.WriteString(LineBreak); err != nil { - return nil, err - } - } - continue - } - - // Count and generate alignment length and buffer spaces using the - // longest key. Keys may be modified if they contain certain characters so - // we need to take that into account in our calculation. - alignLength := 0 - if PrettyFormat { - for _, kname := range sec.keyList { - keyLength := len(kname) - // First case will surround key by ` and second by """ - if strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters) { - keyLength += 2 - } else if strings.Contains(kname, "`") { - keyLength += 6 - } - - if keyLength > alignLength { - alignLength = keyLength - } - } - } - alignSpaces := bytes.Repeat([]byte(" "), alignLength) - - KeyList: - for _, kname := range sec.keyList { - key := sec.Key(kname) - if len(key.Comment) > 0 { - if len(indent) > 0 && sname != DefaultSection { - buf.WriteString(indent) - } - - // Support multiline comments - lines := strings.Split(key.Comment, LineBreak) - for i := range lines { - if lines[i][0] != '#' && lines[i][0] != ';' { - lines[i] = "; " + strings.TrimSpace(lines[i]) - } else { - lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) - } - - if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { - return nil, err - } - } - } - - if len(indent) > 0 && sname != DefaultSection { - buf.WriteString(indent) - } - - switch { - case key.isAutoIncrement: - kname = "-" - case strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters): - kname = "`" + kname + "`" - case strings.Contains(kname, "`"): - kname = `"""` + kname + `"""` - } - - writeKeyValue := func(val string) (bool, error) { - if _, err := buf.WriteString(kname); err != nil { - return false, err - } - - if key.isBooleanType { - buf.WriteString(LineBreak) - return true, nil - } - - // Write out alignment spaces before "=" sign - if PrettyFormat { - buf.Write(alignSpaces[:alignLength-len(kname)]) - } - - // In case key value contains "\n", "`", "\"", "#" or ";" - if strings.ContainsAny(val, "\n`") { - val = `"""` + val + `"""` - } else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") { - val = "`" + val + "`" - } else if len(strings.TrimSpace(val)) != len(val) { - val = `"` + val + `"` - } - if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil { - return false, err - } - return false, nil - } - - shadows := key.ValueWithShadows() - if len(shadows) == 0 { - if _, err := writeKeyValue(""); err != nil { - return nil, err - } - } - - for _, val := range shadows { - exitLoop, err := writeKeyValue(val) - if err != nil { - return nil, err - } else if exitLoop { - continue KeyList - } - } - - for _, val := range key.nestedValues { - if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil { - return nil, err - } - } - } - - if PrettySection && !isLastSection { - // Put a line between sections - if _, err := buf.WriteString(LineBreak); err != nil { - return nil, err - } - } - } - - return buf, nil -} - -// WriteToIndent writes content into io.Writer with given indention. -// If PrettyFormat has been set to be true, -// it will align "=" sign with spaces under each section. -func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) { - buf, err := f.writeToBuffer(indent) - if err != nil { - return 0, err - } - return buf.WriteTo(w) -} - -// WriteTo writes file content into io.Writer. -func (f *File) WriteTo(w io.Writer) (int64, error) { - return f.WriteToIndent(w, "") -} - -// SaveToIndent writes content to file system with given value indention. -func (f *File) SaveToIndent(filename, indent string) error { - // Note: Because we are truncating with os.Create, - // so it's safer to save to a temporary file location and rename after done. - buf, err := f.writeToBuffer(indent) - if err != nil { - return err - } - - return ioutil.WriteFile(filename, buf.Bytes(), 0666) -} - -// SaveTo writes content to file system. -func (f *File) SaveTo(filename string) error { - return f.SaveToIndent(filename, "") -} diff --git a/vendor/github.com/go-ini/ini/helper.go b/vendor/github.com/go-ini/ini/helper.go deleted file mode 100644 index f9d80a682a55..000000000000 --- a/vendor/github.com/go-ini/ini/helper.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2019 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -func inSlice(str string, s []string) bool { - for _, v := range s { - if str == v { - return true - } - } - return false -} diff --git a/vendor/github.com/go-ini/ini/ini.go b/vendor/github.com/go-ini/ini/ini.go deleted file mode 100644 index 99e7f86511a4..000000000000 --- a/vendor/github.com/go-ini/ini/ini.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -// Package ini provides INI file read and write functionality in Go. -package ini - -import ( - "os" - "regexp" - "runtime" - "strings" -) - -const ( - // Maximum allowed depth when recursively substituing variable names. - depthValues = 99 -) - -var ( - // DefaultSection is the name of default section. You can use this var or the string literal. - // In most of cases, an empty string is all you need to access the section. - DefaultSection = "DEFAULT" - - // LineBreak is the delimiter to determine or compose a new line. - // This variable will be changed to "\r\n" automatically on Windows at package init time. - LineBreak = "\n" - - // Variable regexp pattern: %(variable)s - varPattern = regexp.MustCompile(`%\(([^)]+)\)s`) - - // DefaultHeader explicitly writes default section header. - DefaultHeader = false - - // PrettySection indicates whether to put a line between sections. - PrettySection = true - // PrettyFormat indicates whether to align "=" sign with spaces to produce pretty output - // or reduce all possible spaces for compact format. - PrettyFormat = true - // PrettyEqual places spaces around "=" sign even when PrettyFormat is false. - PrettyEqual = false - // DefaultFormatLeft places custom spaces on the left when PrettyFormat and PrettyEqual are both disabled. - DefaultFormatLeft = "" - // DefaultFormatRight places custom spaces on the right when PrettyFormat and PrettyEqual are both disabled. - DefaultFormatRight = "" -) - -var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") - -func init() { - if runtime.GOOS == "windows" && !inTest { - LineBreak = "\r\n" - } -} - -// LoadOptions contains all customized options used for load data source(s). -type LoadOptions struct { - // Loose indicates whether the parser should ignore nonexistent files or return error. - Loose bool - // Insensitive indicates whether the parser forces all section and key names to lowercase. - Insensitive bool - // InsensitiveSections indicates whether the parser forces all section to lowercase. - InsensitiveSections bool - // InsensitiveKeys indicates whether the parser forces all key names to lowercase. - InsensitiveKeys bool - // IgnoreContinuation indicates whether to ignore continuation lines while parsing. - IgnoreContinuation bool - // IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value. - IgnoreInlineComment bool - // SkipUnrecognizableLines indicates whether to skip unrecognizable lines that do not conform to key/value pairs. - SkipUnrecognizableLines bool - // ShortCircuit indicates whether to ignore other configuration sources after loaded the first available configuration source. - ShortCircuit bool - // AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing. - // This type of keys are mostly used in my.cnf. - AllowBooleanKeys bool - // AllowShadows indicates whether to keep track of keys with same name under same section. - AllowShadows bool - // AllowNestedValues indicates whether to allow AWS-like nested values. - // Docs: http://docs.aws.amazon.com/cli/latest/topic/config-vars.html#nested-values - AllowNestedValues bool - // AllowPythonMultilineValues indicates whether to allow Python-like multi-line values. - // Docs: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure - // Relevant quote: Values can also span multiple lines, as long as they are indented deeper - // than the first line of the value. - AllowPythonMultilineValues bool - // SpaceBeforeInlineComment indicates whether to allow comment symbols (\# and \;) inside value. - // Docs: https://docs.python.org/2/library/configparser.html - // Quote: Comments may appear on their own in an otherwise empty line, or may be entered in lines holding values or section names. - // In the latter case, they need to be preceded by a whitespace character to be recognized as a comment. - SpaceBeforeInlineComment bool - // UnescapeValueDoubleQuotes indicates whether to unescape double quotes inside value to regular format - // when value is surrounded by double quotes, e.g. key="a \"value\"" => key=a "value" - UnescapeValueDoubleQuotes bool - // UnescapeValueCommentSymbols indicates to unescape comment symbols (\# and \;) inside value to regular format - // when value is NOT surrounded by any quotes. - // Note: UNSTABLE, behavior might change to only unescape inside double quotes but may noy necessary at all. - UnescapeValueCommentSymbols bool - // UnparseableSections stores a list of blocks that are allowed with raw content which do not otherwise - // conform to key/value pairs. Specify the names of those blocks here. - UnparseableSections []string - // KeyValueDelimiters is the sequence of delimiters that are used to separate key and value. By default, it is "=:". - KeyValueDelimiters string - // KeyValueDelimiterOnWrite is the delimiter that are used to separate key and value output. By default, it is "=". - KeyValueDelimiterOnWrite string - // ChildSectionDelimiter is the delimiter that is used to separate child sections. By default, it is ".". - ChildSectionDelimiter string - // PreserveSurroundedQuote indicates whether to preserve surrounded quote (single and double quotes). - PreserveSurroundedQuote bool - // DebugFunc is called to collect debug information (currently only useful to debug parsing Python-style multiline values). - DebugFunc DebugFunc - // ReaderBufferSize is the buffer size of the reader in bytes. - ReaderBufferSize int - // AllowNonUniqueSections indicates whether to allow sections with the same name multiple times. - AllowNonUniqueSections bool - // AllowDuplicateShadowValues indicates whether values for shadowed keys should be deduplicated. - AllowDuplicateShadowValues bool -} - -// DebugFunc is the type of function called to log parse events. -type DebugFunc func(message string) - -// LoadSources allows caller to apply customized options for loading from data source(s). -func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) { - sources := make([]dataSource, len(others)+1) - sources[0], err = parseDataSource(source) - if err != nil { - return nil, err - } - for i := range others { - sources[i+1], err = parseDataSource(others[i]) - if err != nil { - return nil, err - } - } - f := newFile(sources, opts) - if err = f.Reload(); err != nil { - return nil, err - } - return f, nil -} - -// Load loads and parses from INI data sources. -// Arguments can be mixed of file name with string type, or raw data in []byte. -// It will return error if list contains nonexistent files. -func Load(source interface{}, others ...interface{}) (*File, error) { - return LoadSources(LoadOptions{}, source, others...) -} - -// LooseLoad has exactly same functionality as Load function -// except it ignores nonexistent files instead of returning error. -func LooseLoad(source interface{}, others ...interface{}) (*File, error) { - return LoadSources(LoadOptions{Loose: true}, source, others...) -} - -// InsensitiveLoad has exactly same functionality as Load function -// except it forces all section and key names to be lowercased. -func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) { - return LoadSources(LoadOptions{Insensitive: true}, source, others...) -} - -// ShadowLoad has exactly same functionality as Load function -// except it allows have shadow keys. -func ShadowLoad(source interface{}, others ...interface{}) (*File, error) { - return LoadSources(LoadOptions{AllowShadows: true}, source, others...) -} diff --git a/vendor/github.com/go-ini/ini/key.go b/vendor/github.com/go-ini/ini/key.go deleted file mode 100644 index a19d9f38ef14..000000000000 --- a/vendor/github.com/go-ini/ini/key.go +++ /dev/null @@ -1,837 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "bytes" - "errors" - "fmt" - "strconv" - "strings" - "time" -) - -// Key represents a key under a section. -type Key struct { - s *Section - Comment string - name string - value string - isAutoIncrement bool - isBooleanType bool - - isShadow bool - shadows []*Key - - nestedValues []string -} - -// newKey simply return a key object with given values. -func newKey(s *Section, name, val string) *Key { - return &Key{ - s: s, - name: name, - value: val, - } -} - -func (k *Key) addShadow(val string) error { - if k.isShadow { - return errors.New("cannot add shadow to another shadow key") - } else if k.isAutoIncrement || k.isBooleanType { - return errors.New("cannot add shadow to auto-increment or boolean key") - } - - if !k.s.f.options.AllowDuplicateShadowValues { - // Deduplicate shadows based on their values. - if k.value == val { - return nil - } - for i := range k.shadows { - if k.shadows[i].value == val { - return nil - } - } - } - - shadow := newKey(k.s, k.name, val) - shadow.isShadow = true - k.shadows = append(k.shadows, shadow) - return nil -} - -// AddShadow adds a new shadow key to itself. -func (k *Key) AddShadow(val string) error { - if !k.s.f.options.AllowShadows { - return errors.New("shadow key is not allowed") - } - return k.addShadow(val) -} - -func (k *Key) addNestedValue(val string) error { - if k.isAutoIncrement || k.isBooleanType { - return errors.New("cannot add nested value to auto-increment or boolean key") - } - - k.nestedValues = append(k.nestedValues, val) - return nil -} - -// AddNestedValue adds a nested value to the key. -func (k *Key) AddNestedValue(val string) error { - if !k.s.f.options.AllowNestedValues { - return errors.New("nested value is not allowed") - } - return k.addNestedValue(val) -} - -// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv -type ValueMapper func(string) string - -// Name returns name of key. -func (k *Key) Name() string { - return k.name -} - -// Value returns raw value of key for performance purpose. -func (k *Key) Value() string { - return k.value -} - -// ValueWithShadows returns raw values of key and its shadows if any. Shadow -// keys with empty values are ignored from the returned list. -func (k *Key) ValueWithShadows() []string { - if len(k.shadows) == 0 { - if k.value == "" { - return []string{} - } - return []string{k.value} - } - - vals := make([]string, 0, len(k.shadows)+1) - if k.value != "" { - vals = append(vals, k.value) - } - for _, s := range k.shadows { - if s.value != "" { - vals = append(vals, s.value) - } - } - return vals -} - -// NestedValues returns nested values stored in the key. -// It is possible returned value is nil if no nested values stored in the key. -func (k *Key) NestedValues() []string { - return k.nestedValues -} - -// transformValue takes a raw value and transforms to its final string. -func (k *Key) transformValue(val string) string { - if k.s.f.ValueMapper != nil { - val = k.s.f.ValueMapper(val) - } - - // Fail-fast if no indicate char found for recursive value - if !strings.Contains(val, "%") { - return val - } - for i := 0; i < depthValues; i++ { - vr := varPattern.FindString(val) - if len(vr) == 0 { - break - } - - // Take off leading '%(' and trailing ')s'. - noption := vr[2 : len(vr)-2] - - // Search in the same section. - // If not found or found the key itself, then search again in default section. - nk, err := k.s.GetKey(noption) - if err != nil || k == nk { - nk, _ = k.s.f.Section("").GetKey(noption) - if nk == nil { - // Stop when no results found in the default section, - // and returns the value as-is. - break - } - } - - // Substitute by new value and take off leading '%(' and trailing ')s'. - val = strings.Replace(val, vr, nk.value, -1) - } - return val -} - -// String returns string representation of value. -func (k *Key) String() string { - return k.transformValue(k.value) -} - -// Validate accepts a validate function which can -// return modifed result as key value. -func (k *Key) Validate(fn func(string) string) string { - return fn(k.String()) -} - -// parseBool returns the boolean value represented by the string. -// -// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On, -// 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off. -// Any other value returns an error. -func parseBool(str string) (value bool, err error) { - switch str { - case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On": - return true, nil - case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off": - return false, nil - } - return false, fmt.Errorf("parsing \"%s\": invalid syntax", str) -} - -// Bool returns bool type value. -func (k *Key) Bool() (bool, error) { - return parseBool(k.String()) -} - -// Float64 returns float64 type value. -func (k *Key) Float64() (float64, error) { - return strconv.ParseFloat(k.String(), 64) -} - -// Int returns int type value. -func (k *Key) Int() (int, error) { - v, err := strconv.ParseInt(k.String(), 0, 64) - return int(v), err -} - -// Int64 returns int64 type value. -func (k *Key) Int64() (int64, error) { - return strconv.ParseInt(k.String(), 0, 64) -} - -// Uint returns uint type valued. -func (k *Key) Uint() (uint, error) { - u, e := strconv.ParseUint(k.String(), 0, 64) - return uint(u), e -} - -// Uint64 returns uint64 type value. -func (k *Key) Uint64() (uint64, error) { - return strconv.ParseUint(k.String(), 0, 64) -} - -// Duration returns time.Duration type value. -func (k *Key) Duration() (time.Duration, error) { - return time.ParseDuration(k.String()) -} - -// TimeFormat parses with given format and returns time.Time type value. -func (k *Key) TimeFormat(format string) (time.Time, error) { - return time.Parse(format, k.String()) -} - -// Time parses with RFC3339 format and returns time.Time type value. -func (k *Key) Time() (time.Time, error) { - return k.TimeFormat(time.RFC3339) -} - -// MustString returns default value if key value is empty. -func (k *Key) MustString(defaultVal string) string { - val := k.String() - if len(val) == 0 { - k.value = defaultVal - return defaultVal - } - return val -} - -// MustBool always returns value without error, -// it returns false if error occurs. -func (k *Key) MustBool(defaultVal ...bool) bool { - val, err := k.Bool() - if len(defaultVal) > 0 && err != nil { - k.value = strconv.FormatBool(defaultVal[0]) - return defaultVal[0] - } - return val -} - -// MustFloat64 always returns value without error, -// it returns 0.0 if error occurs. -func (k *Key) MustFloat64(defaultVal ...float64) float64 { - val, err := k.Float64() - if len(defaultVal) > 0 && err != nil { - k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64) - return defaultVal[0] - } - return val -} - -// MustInt always returns value without error, -// it returns 0 if error occurs. -func (k *Key) MustInt(defaultVal ...int) int { - val, err := k.Int() - if len(defaultVal) > 0 && err != nil { - k.value = strconv.FormatInt(int64(defaultVal[0]), 10) - return defaultVal[0] - } - return val -} - -// MustInt64 always returns value without error, -// it returns 0 if error occurs. -func (k *Key) MustInt64(defaultVal ...int64) int64 { - val, err := k.Int64() - if len(defaultVal) > 0 && err != nil { - k.value = strconv.FormatInt(defaultVal[0], 10) - return defaultVal[0] - } - return val -} - -// MustUint always returns value without error, -// it returns 0 if error occurs. -func (k *Key) MustUint(defaultVal ...uint) uint { - val, err := k.Uint() - if len(defaultVal) > 0 && err != nil { - k.value = strconv.FormatUint(uint64(defaultVal[0]), 10) - return defaultVal[0] - } - return val -} - -// MustUint64 always returns value without error, -// it returns 0 if error occurs. -func (k *Key) MustUint64(defaultVal ...uint64) uint64 { - val, err := k.Uint64() - if len(defaultVal) > 0 && err != nil { - k.value = strconv.FormatUint(defaultVal[0], 10) - return defaultVal[0] - } - return val -} - -// MustDuration always returns value without error, -// it returns zero value if error occurs. -func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration { - val, err := k.Duration() - if len(defaultVal) > 0 && err != nil { - k.value = defaultVal[0].String() - return defaultVal[0] - } - return val -} - -// MustTimeFormat always parses with given format and returns value without error, -// it returns zero value if error occurs. -func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time { - val, err := k.TimeFormat(format) - if len(defaultVal) > 0 && err != nil { - k.value = defaultVal[0].Format(format) - return defaultVal[0] - } - return val -} - -// MustTime always parses with RFC3339 format and returns value without error, -// it returns zero value if error occurs. -func (k *Key) MustTime(defaultVal ...time.Time) time.Time { - return k.MustTimeFormat(time.RFC3339, defaultVal...) -} - -// In always returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) In(defaultVal string, candidates []string) string { - val := k.String() - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// InFloat64 always returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 { - val := k.MustFloat64() - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// InInt always returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) InInt(defaultVal int, candidates []int) int { - val := k.MustInt() - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// InInt64 always returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 { - val := k.MustInt64() - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// InUint always returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) InUint(defaultVal uint, candidates []uint) uint { - val := k.MustUint() - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// InUint64 always returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 { - val := k.MustUint64() - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// InTimeFormat always parses with given format and returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time { - val := k.MustTimeFormat(format) - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// InTime always parses with RFC3339 format and returns value without error, -// it returns default value if error occurs or doesn't fit into candidates. -func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time { - return k.InTimeFormat(time.RFC3339, defaultVal, candidates) -} - -// RangeFloat64 checks if value is in given range inclusively, -// and returns default value if it's not. -func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 { - val := k.MustFloat64() - if val < min || val > max { - return defaultVal - } - return val -} - -// RangeInt checks if value is in given range inclusively, -// and returns default value if it's not. -func (k *Key) RangeInt(defaultVal, min, max int) int { - val := k.MustInt() - if val < min || val > max { - return defaultVal - } - return val -} - -// RangeInt64 checks if value is in given range inclusively, -// and returns default value if it's not. -func (k *Key) RangeInt64(defaultVal, min, max int64) int64 { - val := k.MustInt64() - if val < min || val > max { - return defaultVal - } - return val -} - -// RangeTimeFormat checks if value with given format is in given range inclusively, -// and returns default value if it's not. -func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time { - val := k.MustTimeFormat(format) - if val.Unix() < min.Unix() || val.Unix() > max.Unix() { - return defaultVal - } - return val -} - -// RangeTime checks if value with RFC3339 format is in given range inclusively, -// and returns default value if it's not. -func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time { - return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max) -} - -// Strings returns list of string divided by given delimiter. -func (k *Key) Strings(delim string) []string { - str := k.String() - if len(str) == 0 { - return []string{} - } - - runes := []rune(str) - vals := make([]string, 0, 2) - var buf bytes.Buffer - escape := false - idx := 0 - for { - if escape { - escape = false - if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) { - buf.WriteRune('\\') - } - buf.WriteRune(runes[idx]) - } else { - if runes[idx] == '\\' { - escape = true - } else if strings.HasPrefix(string(runes[idx:]), delim) { - idx += len(delim) - 1 - vals = append(vals, strings.TrimSpace(buf.String())) - buf.Reset() - } else { - buf.WriteRune(runes[idx]) - } - } - idx++ - if idx == len(runes) { - break - } - } - - if buf.Len() > 0 { - vals = append(vals, strings.TrimSpace(buf.String())) - } - - return vals -} - -// StringsWithShadows returns list of string divided by given delimiter. -// Shadows will also be appended if any. -func (k *Key) StringsWithShadows(delim string) []string { - vals := k.ValueWithShadows() - results := make([]string, 0, len(vals)*2) - for i := range vals { - if len(vals) == 0 { - continue - } - - results = append(results, strings.Split(vals[i], delim)...) - } - - for i := range results { - results[i] = k.transformValue(strings.TrimSpace(results[i])) - } - return results -} - -// Float64s returns list of float64 divided by given delimiter. Any invalid input will be treated as zero value. -func (k *Key) Float64s(delim string) []float64 { - vals, _ := k.parseFloat64s(k.Strings(delim), true, false) - return vals -} - -// Ints returns list of int divided by given delimiter. Any invalid input will be treated as zero value. -func (k *Key) Ints(delim string) []int { - vals, _ := k.parseInts(k.Strings(delim), true, false) - return vals -} - -// Int64s returns list of int64 divided by given delimiter. Any invalid input will be treated as zero value. -func (k *Key) Int64s(delim string) []int64 { - vals, _ := k.parseInt64s(k.Strings(delim), true, false) - return vals -} - -// Uints returns list of uint divided by given delimiter. Any invalid input will be treated as zero value. -func (k *Key) Uints(delim string) []uint { - vals, _ := k.parseUints(k.Strings(delim), true, false) - return vals -} - -// Uint64s returns list of uint64 divided by given delimiter. Any invalid input will be treated as zero value. -func (k *Key) Uint64s(delim string) []uint64 { - vals, _ := k.parseUint64s(k.Strings(delim), true, false) - return vals -} - -// Bools returns list of bool divided by given delimiter. Any invalid input will be treated as zero value. -func (k *Key) Bools(delim string) []bool { - vals, _ := k.parseBools(k.Strings(delim), true, false) - return vals -} - -// TimesFormat parses with given format and returns list of time.Time divided by given delimiter. -// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). -func (k *Key) TimesFormat(format, delim string) []time.Time { - vals, _ := k.parseTimesFormat(format, k.Strings(delim), true, false) - return vals -} - -// Times parses with RFC3339 format and returns list of time.Time divided by given delimiter. -// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). -func (k *Key) Times(delim string) []time.Time { - return k.TimesFormat(time.RFC3339, delim) -} - -// ValidFloat64s returns list of float64 divided by given delimiter. If some value is not float, then -// it will not be included to result list. -func (k *Key) ValidFloat64s(delim string) []float64 { - vals, _ := k.parseFloat64s(k.Strings(delim), false, false) - return vals -} - -// ValidInts returns list of int divided by given delimiter. If some value is not integer, then it will -// not be included to result list. -func (k *Key) ValidInts(delim string) []int { - vals, _ := k.parseInts(k.Strings(delim), false, false) - return vals -} - -// ValidInt64s returns list of int64 divided by given delimiter. If some value is not 64-bit integer, -// then it will not be included to result list. -func (k *Key) ValidInt64s(delim string) []int64 { - vals, _ := k.parseInt64s(k.Strings(delim), false, false) - return vals -} - -// ValidUints returns list of uint divided by given delimiter. If some value is not unsigned integer, -// then it will not be included to result list. -func (k *Key) ValidUints(delim string) []uint { - vals, _ := k.parseUints(k.Strings(delim), false, false) - return vals -} - -// ValidUint64s returns list of uint64 divided by given delimiter. If some value is not 64-bit unsigned -// integer, then it will not be included to result list. -func (k *Key) ValidUint64s(delim string) []uint64 { - vals, _ := k.parseUint64s(k.Strings(delim), false, false) - return vals -} - -// ValidBools returns list of bool divided by given delimiter. If some value is not 64-bit unsigned -// integer, then it will not be included to result list. -func (k *Key) ValidBools(delim string) []bool { - vals, _ := k.parseBools(k.Strings(delim), false, false) - return vals -} - -// ValidTimesFormat parses with given format and returns list of time.Time divided by given delimiter. -func (k *Key) ValidTimesFormat(format, delim string) []time.Time { - vals, _ := k.parseTimesFormat(format, k.Strings(delim), false, false) - return vals -} - -// ValidTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter. -func (k *Key) ValidTimes(delim string) []time.Time { - return k.ValidTimesFormat(time.RFC3339, delim) -} - -// StrictFloat64s returns list of float64 divided by given delimiter or error on first invalid input. -func (k *Key) StrictFloat64s(delim string) ([]float64, error) { - return k.parseFloat64s(k.Strings(delim), false, true) -} - -// StrictInts returns list of int divided by given delimiter or error on first invalid input. -func (k *Key) StrictInts(delim string) ([]int, error) { - return k.parseInts(k.Strings(delim), false, true) -} - -// StrictInt64s returns list of int64 divided by given delimiter or error on first invalid input. -func (k *Key) StrictInt64s(delim string) ([]int64, error) { - return k.parseInt64s(k.Strings(delim), false, true) -} - -// StrictUints returns list of uint divided by given delimiter or error on first invalid input. -func (k *Key) StrictUints(delim string) ([]uint, error) { - return k.parseUints(k.Strings(delim), false, true) -} - -// StrictUint64s returns list of uint64 divided by given delimiter or error on first invalid input. -func (k *Key) StrictUint64s(delim string) ([]uint64, error) { - return k.parseUint64s(k.Strings(delim), false, true) -} - -// StrictBools returns list of bool divided by given delimiter or error on first invalid input. -func (k *Key) StrictBools(delim string) ([]bool, error) { - return k.parseBools(k.Strings(delim), false, true) -} - -// StrictTimesFormat parses with given format and returns list of time.Time divided by given delimiter -// or error on first invalid input. -func (k *Key) StrictTimesFormat(format, delim string) ([]time.Time, error) { - return k.parseTimesFormat(format, k.Strings(delim), false, true) -} - -// StrictTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter -// or error on first invalid input. -func (k *Key) StrictTimes(delim string) ([]time.Time, error) { - return k.StrictTimesFormat(time.RFC3339, delim) -} - -// parseBools transforms strings to bools. -func (k *Key) parseBools(strs []string, addInvalid, returnOnInvalid bool) ([]bool, error) { - vals := make([]bool, 0, len(strs)) - parser := func(str string) (interface{}, error) { - val, err := parseBool(str) - return val, err - } - rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) - if err == nil { - for _, val := range rawVals { - vals = append(vals, val.(bool)) - } - } - return vals, err -} - -// parseFloat64s transforms strings to float64s. -func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]float64, error) { - vals := make([]float64, 0, len(strs)) - parser := func(str string) (interface{}, error) { - val, err := strconv.ParseFloat(str, 64) - return val, err - } - rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) - if err == nil { - for _, val := range rawVals { - vals = append(vals, val.(float64)) - } - } - return vals, err -} - -// parseInts transforms strings to ints. -func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) { - vals := make([]int, 0, len(strs)) - parser := func(str string) (interface{}, error) { - val, err := strconv.ParseInt(str, 0, 64) - return val, err - } - rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) - if err == nil { - for _, val := range rawVals { - vals = append(vals, int(val.(int64))) - } - } - return vals, err -} - -// parseInt64s transforms strings to int64s. -func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) { - vals := make([]int64, 0, len(strs)) - parser := func(str string) (interface{}, error) { - val, err := strconv.ParseInt(str, 0, 64) - return val, err - } - - rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) - if err == nil { - for _, val := range rawVals { - vals = append(vals, val.(int64)) - } - } - return vals, err -} - -// parseUints transforms strings to uints. -func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) { - vals := make([]uint, 0, len(strs)) - parser := func(str string) (interface{}, error) { - val, err := strconv.ParseUint(str, 0, 64) - return val, err - } - - rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) - if err == nil { - for _, val := range rawVals { - vals = append(vals, uint(val.(uint64))) - } - } - return vals, err -} - -// parseUint64s transforms strings to uint64s. -func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) { - vals := make([]uint64, 0, len(strs)) - parser := func(str string) (interface{}, error) { - val, err := strconv.ParseUint(str, 0, 64) - return val, err - } - rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) - if err == nil { - for _, val := range rawVals { - vals = append(vals, val.(uint64)) - } - } - return vals, err -} - -type Parser func(str string) (interface{}, error) - -// parseTimesFormat transforms strings to times in given format. -func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) { - vals := make([]time.Time, 0, len(strs)) - parser := func(str string) (interface{}, error) { - val, err := time.Parse(format, str) - return val, err - } - rawVals, err := k.doParse(strs, addInvalid, returnOnInvalid, parser) - if err == nil { - for _, val := range rawVals { - vals = append(vals, val.(time.Time)) - } - } - return vals, err -} - -// doParse transforms strings to different types -func (k *Key) doParse(strs []string, addInvalid, returnOnInvalid bool, parser Parser) ([]interface{}, error) { - vals := make([]interface{}, 0, len(strs)) - for _, str := range strs { - val, err := parser(str) - if err != nil && returnOnInvalid { - return nil, err - } - if err == nil || addInvalid { - vals = append(vals, val) - } - } - return vals, nil -} - -// SetValue changes key value. -func (k *Key) SetValue(v string) { - if k.s.f.BlockMode { - k.s.f.lock.Lock() - defer k.s.f.lock.Unlock() - } - - k.value = v - k.s.keysHash[k.name] = v -} diff --git a/vendor/github.com/go-ini/ini/parser.go b/vendor/github.com/go-ini/ini/parser.go deleted file mode 100644 index 44fc526c2cb6..000000000000 --- a/vendor/github.com/go-ini/ini/parser.go +++ /dev/null @@ -1,520 +0,0 @@ -// Copyright 2015 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "bufio" - "bytes" - "fmt" - "io" - "regexp" - "strconv" - "strings" - "unicode" -) - -const minReaderBufferSize = 4096 - -var pythonMultiline = regexp.MustCompile(`^([\t\f ]+)(.*)`) - -type parserOptions struct { - IgnoreContinuation bool - IgnoreInlineComment bool - AllowPythonMultilineValues bool - SpaceBeforeInlineComment bool - UnescapeValueDoubleQuotes bool - UnescapeValueCommentSymbols bool - PreserveSurroundedQuote bool - DebugFunc DebugFunc - ReaderBufferSize int -} - -type parser struct { - buf *bufio.Reader - options parserOptions - - isEOF bool - count int - comment *bytes.Buffer -} - -func (p *parser) debug(format string, args ...interface{}) { - if p.options.DebugFunc != nil { - p.options.DebugFunc(fmt.Sprintf(format, args...)) - } -} - -func newParser(r io.Reader, opts parserOptions) *parser { - size := opts.ReaderBufferSize - if size < minReaderBufferSize { - size = minReaderBufferSize - } - - return &parser{ - buf: bufio.NewReaderSize(r, size), - options: opts, - count: 1, - comment: &bytes.Buffer{}, - } -} - -// BOM handles header of UTF-8, UTF-16 LE and UTF-16 BE's BOM format. -// http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding -func (p *parser) BOM() error { - mask, err := p.buf.Peek(2) - if err != nil && err != io.EOF { - return err - } else if len(mask) < 2 { - return nil - } - - switch { - case mask[0] == 254 && mask[1] == 255: - fallthrough - case mask[0] == 255 && mask[1] == 254: - _, err = p.buf.Read(mask) - if err != nil { - return err - } - case mask[0] == 239 && mask[1] == 187: - mask, err := p.buf.Peek(3) - if err != nil && err != io.EOF { - return err - } else if len(mask) < 3 { - return nil - } - if mask[2] == 191 { - _, err = p.buf.Read(mask) - if err != nil { - return err - } - } - } - return nil -} - -func (p *parser) readUntil(delim byte) ([]byte, error) { - data, err := p.buf.ReadBytes(delim) - if err != nil { - if err == io.EOF { - p.isEOF = true - } else { - return nil, err - } - } - return data, nil -} - -func cleanComment(in []byte) ([]byte, bool) { - i := bytes.IndexAny(in, "#;") - if i == -1 { - return nil, false - } - return in[i:], true -} - -func readKeyName(delimiters string, in []byte) (string, int, error) { - line := string(in) - - // Check if key name surrounded by quotes. - var keyQuote string - if line[0] == '"' { - if len(line) > 6 && line[0:3] == `"""` { - keyQuote = `"""` - } else { - keyQuote = `"` - } - } else if line[0] == '`' { - keyQuote = "`" - } - - // Get out key name - var endIdx int - if len(keyQuote) > 0 { - startIdx := len(keyQuote) - // FIXME: fail case -> """"""name"""=value - pos := strings.Index(line[startIdx:], keyQuote) - if pos == -1 { - return "", -1, fmt.Errorf("missing closing key quote: %s", line) - } - pos += startIdx - - // Find key-value delimiter - i := strings.IndexAny(line[pos+startIdx:], delimiters) - if i < 0 { - return "", -1, ErrDelimiterNotFound{line} - } - endIdx = pos + i - return strings.TrimSpace(line[startIdx:pos]), endIdx + startIdx + 1, nil - } - - endIdx = strings.IndexAny(line, delimiters) - if endIdx < 0 { - return "", -1, ErrDelimiterNotFound{line} - } - if endIdx == 0 { - return "", -1, ErrEmptyKeyName{line} - } - - return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil -} - -func (p *parser) readMultilines(line, val, valQuote string) (string, error) { - for { - data, err := p.readUntil('\n') - if err != nil { - return "", err - } - next := string(data) - - pos := strings.LastIndex(next, valQuote) - if pos > -1 { - val += next[:pos] - - comment, has := cleanComment([]byte(next[pos:])) - if has { - p.comment.Write(bytes.TrimSpace(comment)) - } - break - } - val += next - if p.isEOF { - return "", fmt.Errorf("missing closing key quote from %q to %q", line, next) - } - } - return val, nil -} - -func (p *parser) readContinuationLines(val string) (string, error) { - for { - data, err := p.readUntil('\n') - if err != nil { - return "", err - } - next := strings.TrimSpace(string(data)) - - if len(next) == 0 { - break - } - val += next - if val[len(val)-1] != '\\' { - break - } - val = val[:len(val)-1] - } - return val, nil -} - -// hasSurroundedQuote check if and only if the first and last characters -// are quotes \" or \'. -// It returns false if any other parts also contain same kind of quotes. -func hasSurroundedQuote(in string, quote byte) bool { - return len(in) >= 2 && in[0] == quote && in[len(in)-1] == quote && - strings.IndexByte(in[1:], quote) == len(in)-2 -} - -func (p *parser) readValue(in []byte, bufferSize int) (string, error) { - - line := strings.TrimLeftFunc(string(in), unicode.IsSpace) - if len(line) == 0 { - if p.options.AllowPythonMultilineValues && len(in) > 0 && in[len(in)-1] == '\n' { - return p.readPythonMultilines(line, bufferSize) - } - return "", nil - } - - var valQuote string - if len(line) > 3 && line[0:3] == `"""` { - valQuote = `"""` - } else if line[0] == '`' { - valQuote = "`" - } else if p.options.UnescapeValueDoubleQuotes && line[0] == '"' { - valQuote = `"` - } - - if len(valQuote) > 0 { - startIdx := len(valQuote) - pos := strings.LastIndex(line[startIdx:], valQuote) - // Check for multi-line value - if pos == -1 { - return p.readMultilines(line, line[startIdx:], valQuote) - } - - if p.options.UnescapeValueDoubleQuotes && valQuote == `"` { - return strings.Replace(line[startIdx:pos+startIdx], `\"`, `"`, -1), nil - } - return line[startIdx : pos+startIdx], nil - } - - lastChar := line[len(line)-1] - // Won't be able to reach here if value only contains whitespace - line = strings.TrimSpace(line) - trimmedLastChar := line[len(line)-1] - - // Check continuation lines when desired - if !p.options.IgnoreContinuation && trimmedLastChar == '\\' { - return p.readContinuationLines(line[:len(line)-1]) - } - - // Check if ignore inline comment - if !p.options.IgnoreInlineComment { - var i int - if p.options.SpaceBeforeInlineComment { - i = strings.Index(line, " #") - if i == -1 { - i = strings.Index(line, " ;") - } - - } else { - i = strings.IndexAny(line, "#;") - } - - if i > -1 { - p.comment.WriteString(line[i:]) - line = strings.TrimSpace(line[:i]) - } - - } - - // Trim single and double quotes - if (hasSurroundedQuote(line, '\'') || - hasSurroundedQuote(line, '"')) && !p.options.PreserveSurroundedQuote { - line = line[1 : len(line)-1] - } else if len(valQuote) == 0 && p.options.UnescapeValueCommentSymbols { - line = strings.ReplaceAll(line, `\;`, ";") - line = strings.ReplaceAll(line, `\#`, "#") - } else if p.options.AllowPythonMultilineValues && lastChar == '\n' { - return p.readPythonMultilines(line, bufferSize) - } - - return line, nil -} - -func (p *parser) readPythonMultilines(line string, bufferSize int) (string, error) { - parserBufferPeekResult, _ := p.buf.Peek(bufferSize) - peekBuffer := bytes.NewBuffer(parserBufferPeekResult) - - for { - peekData, peekErr := peekBuffer.ReadBytes('\n') - if peekErr != nil && peekErr != io.EOF { - p.debug("readPythonMultilines: failed to peek with error: %v", peekErr) - return "", peekErr - } - - p.debug("readPythonMultilines: parsing %q", string(peekData)) - - peekMatches := pythonMultiline.FindStringSubmatch(string(peekData)) - p.debug("readPythonMultilines: matched %d parts", len(peekMatches)) - for n, v := range peekMatches { - p.debug(" %d: %q", n, v) - } - - // Return if not a Python multiline value. - if len(peekMatches) != 3 { - p.debug("readPythonMultilines: end of value, got: %q", line) - return line, nil - } - - // Advance the parser reader (buffer) in-sync with the peek buffer. - _, err := p.buf.Discard(len(peekData)) - if err != nil { - p.debug("readPythonMultilines: failed to skip to the end, returning error") - return "", err - } - - line += "\n" + peekMatches[0] - } -} - -// parse parses data through an io.Reader. -func (f *File) parse(reader io.Reader) (err error) { - p := newParser(reader, parserOptions{ - IgnoreContinuation: f.options.IgnoreContinuation, - IgnoreInlineComment: f.options.IgnoreInlineComment, - AllowPythonMultilineValues: f.options.AllowPythonMultilineValues, - SpaceBeforeInlineComment: f.options.SpaceBeforeInlineComment, - UnescapeValueDoubleQuotes: f.options.UnescapeValueDoubleQuotes, - UnescapeValueCommentSymbols: f.options.UnescapeValueCommentSymbols, - PreserveSurroundedQuote: f.options.PreserveSurroundedQuote, - DebugFunc: f.options.DebugFunc, - ReaderBufferSize: f.options.ReaderBufferSize, - }) - if err = p.BOM(); err != nil { - return fmt.Errorf("BOM: %v", err) - } - - // Ignore error because default section name is never empty string. - name := DefaultSection - if f.options.Insensitive || f.options.InsensitiveSections { - name = strings.ToLower(DefaultSection) - } - section, _ := f.NewSection(name) - - // This "last" is not strictly equivalent to "previous one" if current key is not the first nested key - var isLastValueEmpty bool - var lastRegularKey *Key - - var line []byte - var inUnparseableSection bool - - // NOTE: Iterate and increase `currentPeekSize` until - // the size of the parser buffer is found. - // TODO(unknwon): When Golang 1.10 is the lowest version supported, replace with `parserBufferSize := p.buf.Size()`. - parserBufferSize := 0 - // NOTE: Peek 4kb at a time. - currentPeekSize := minReaderBufferSize - - if f.options.AllowPythonMultilineValues { - for { - peekBytes, _ := p.buf.Peek(currentPeekSize) - peekBytesLength := len(peekBytes) - - if parserBufferSize >= peekBytesLength { - break - } - - currentPeekSize *= 2 - parserBufferSize = peekBytesLength - } - } - - for !p.isEOF { - line, err = p.readUntil('\n') - if err != nil { - return err - } - - if f.options.AllowNestedValues && - isLastValueEmpty && len(line) > 0 { - if line[0] == ' ' || line[0] == '\t' { - err = lastRegularKey.addNestedValue(string(bytes.TrimSpace(line))) - if err != nil { - return err - } - continue - } - } - - line = bytes.TrimLeftFunc(line, unicode.IsSpace) - if len(line) == 0 { - continue - } - - // Comments - if line[0] == '#' || line[0] == ';' { - // Note: we do not care ending line break, - // it is needed for adding second line, - // so just clean it once at the end when set to value. - p.comment.Write(line) - continue - } - - // Section - if line[0] == '[' { - // Read to the next ']' (TODO: support quoted strings) - closeIdx := bytes.LastIndexByte(line, ']') - if closeIdx == -1 { - return fmt.Errorf("unclosed section: %s", line) - } - - name := string(line[1:closeIdx]) - section, err = f.NewSection(name) - if err != nil { - return err - } - - comment, has := cleanComment(line[closeIdx+1:]) - if has { - p.comment.Write(comment) - } - - section.Comment = strings.TrimSpace(p.comment.String()) - - // Reset auto-counter and comments - p.comment.Reset() - p.count = 1 - // Nested values can't span sections - isLastValueEmpty = false - - inUnparseableSection = false - for i := range f.options.UnparseableSections { - if f.options.UnparseableSections[i] == name || - ((f.options.Insensitive || f.options.InsensitiveSections) && strings.EqualFold(f.options.UnparseableSections[i], name)) { - inUnparseableSection = true - continue - } - } - continue - } - - if inUnparseableSection { - section.isRawSection = true - section.rawBody += string(line) - continue - } - - kname, offset, err := readKeyName(f.options.KeyValueDelimiters, line) - if err != nil { - switch { - // Treat as boolean key when desired, and whole line is key name. - case IsErrDelimiterNotFound(err): - switch { - case f.options.AllowBooleanKeys: - kname, err := p.readValue(line, parserBufferSize) - if err != nil { - return err - } - key, err := section.NewBooleanKey(kname) - if err != nil { - return err - } - key.Comment = strings.TrimSpace(p.comment.String()) - p.comment.Reset() - continue - - case f.options.SkipUnrecognizableLines: - continue - } - case IsErrEmptyKeyName(err) && f.options.SkipUnrecognizableLines: - continue - } - return err - } - - // Auto increment. - isAutoIncr := false - if kname == "-" { - isAutoIncr = true - kname = "#" + strconv.Itoa(p.count) - p.count++ - } - - value, err := p.readValue(line[offset:], parserBufferSize) - if err != nil { - return err - } - isLastValueEmpty = len(value) == 0 - - key, err := section.NewKey(kname, value) - if err != nil { - return err - } - key.isAutoIncrement = isAutoIncr - key.Comment = strings.TrimSpace(p.comment.String()) - p.comment.Reset() - lastRegularKey = key - } - return nil -} diff --git a/vendor/github.com/go-ini/ini/section.go b/vendor/github.com/go-ini/ini/section.go deleted file mode 100644 index a3615d820b7a..000000000000 --- a/vendor/github.com/go-ini/ini/section.go +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "errors" - "fmt" - "strings" -) - -// Section represents a config section. -type Section struct { - f *File - Comment string - name string - keys map[string]*Key - keyList []string - keysHash map[string]string - - isRawSection bool - rawBody string -} - -func newSection(f *File, name string) *Section { - return &Section{ - f: f, - name: name, - keys: make(map[string]*Key), - keyList: make([]string, 0, 10), - keysHash: make(map[string]string), - } -} - -// Name returns name of Section. -func (s *Section) Name() string { - return s.name -} - -// Body returns rawBody of Section if the section was marked as unparseable. -// It still follows the other rules of the INI format surrounding leading/trailing whitespace. -func (s *Section) Body() string { - return strings.TrimSpace(s.rawBody) -} - -// SetBody updates body content only if section is raw. -func (s *Section) SetBody(body string) { - if !s.isRawSection { - return - } - s.rawBody = body -} - -// NewKey creates a new key to given section. -func (s *Section) NewKey(name, val string) (*Key, error) { - if len(name) == 0 { - return nil, errors.New("error creating new key: empty key name") - } else if s.f.options.Insensitive || s.f.options.InsensitiveKeys { - name = strings.ToLower(name) - } - - if s.f.BlockMode { - s.f.lock.Lock() - defer s.f.lock.Unlock() - } - - if inSlice(name, s.keyList) { - if s.f.options.AllowShadows { - if err := s.keys[name].addShadow(val); err != nil { - return nil, err - } - } else { - s.keys[name].value = val - s.keysHash[name] = val - } - return s.keys[name], nil - } - - s.keyList = append(s.keyList, name) - s.keys[name] = newKey(s, name, val) - s.keysHash[name] = val - return s.keys[name], nil -} - -// NewBooleanKey creates a new boolean type key to given section. -func (s *Section) NewBooleanKey(name string) (*Key, error) { - key, err := s.NewKey(name, "true") - if err != nil { - return nil, err - } - - key.isBooleanType = true - return key, nil -} - -// GetKey returns key in section by given name. -func (s *Section) GetKey(name string) (*Key, error) { - if s.f.BlockMode { - s.f.lock.RLock() - } - if s.f.options.Insensitive || s.f.options.InsensitiveKeys { - name = strings.ToLower(name) - } - key := s.keys[name] - if s.f.BlockMode { - s.f.lock.RUnlock() - } - - if key == nil { - // Check if it is a child-section. - sname := s.name - for { - if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 { - sname = sname[:i] - sec, err := s.f.GetSection(sname) - if err != nil { - continue - } - return sec.GetKey(name) - } - break - } - return nil, fmt.Errorf("error when getting key of section %q: key %q not exists", s.name, name) - } - return key, nil -} - -// HasKey returns true if section contains a key with given name. -func (s *Section) HasKey(name string) bool { - key, _ := s.GetKey(name) - return key != nil -} - -// Deprecated: Use "HasKey" instead. -func (s *Section) Haskey(name string) bool { - return s.HasKey(name) -} - -// HasValue returns true if section contains given raw value. -func (s *Section) HasValue(value string) bool { - if s.f.BlockMode { - s.f.lock.RLock() - defer s.f.lock.RUnlock() - } - - for _, k := range s.keys { - if value == k.value { - return true - } - } - return false -} - -// Key assumes named Key exists in section and returns a zero-value when not. -func (s *Section) Key(name string) *Key { - key, err := s.GetKey(name) - if err != nil { - // It's OK here because the only possible error is empty key name, - // but if it's empty, this piece of code won't be executed. - key, _ = s.NewKey(name, "") - return key - } - return key -} - -// Keys returns list of keys of section. -func (s *Section) Keys() []*Key { - keys := make([]*Key, len(s.keyList)) - for i := range s.keyList { - keys[i] = s.Key(s.keyList[i]) - } - return keys -} - -// ParentKeys returns list of keys of parent section. -func (s *Section) ParentKeys() []*Key { - var parentKeys []*Key - sname := s.name - for { - if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 { - sname = sname[:i] - sec, err := s.f.GetSection(sname) - if err != nil { - continue - } - parentKeys = append(parentKeys, sec.Keys()...) - } else { - break - } - - } - return parentKeys -} - -// KeyStrings returns list of key names of section. -func (s *Section) KeyStrings() []string { - list := make([]string, len(s.keyList)) - copy(list, s.keyList) - return list -} - -// KeysHash returns keys hash consisting of names and values. -func (s *Section) KeysHash() map[string]string { - if s.f.BlockMode { - s.f.lock.RLock() - defer s.f.lock.RUnlock() - } - - hash := make(map[string]string, len(s.keysHash)) - for key, value := range s.keysHash { - hash[key] = value - } - return hash -} - -// DeleteKey deletes a key from section. -func (s *Section) DeleteKey(name string) { - if s.f.BlockMode { - s.f.lock.Lock() - defer s.f.lock.Unlock() - } - - for i, k := range s.keyList { - if k == name { - s.keyList = append(s.keyList[:i], s.keyList[i+1:]...) - delete(s.keys, name) - delete(s.keysHash, name) - return - } - } -} - -// ChildSections returns a list of child sections of current section. -// For example, "[parent.child1]" and "[parent.child12]" are child sections -// of section "[parent]". -func (s *Section) ChildSections() []*Section { - prefix := s.name + s.f.options.ChildSectionDelimiter - children := make([]*Section, 0, 3) - for _, name := range s.f.sectionList { - if strings.HasPrefix(name, prefix) { - children = append(children, s.f.sections[name]...) - } - } - return children -} diff --git a/vendor/github.com/go-ini/ini/struct.go b/vendor/github.com/go-ini/ini/struct.go deleted file mode 100644 index a486b2fe0fdc..000000000000 --- a/vendor/github.com/go-ini/ini/struct.go +++ /dev/null @@ -1,747 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "strings" - "time" - "unicode" -) - -// NameMapper represents a ini tag name mapper. -type NameMapper func(string) string - -// Built-in name getters. -var ( - // SnackCase converts to format SNACK_CASE. - SnackCase NameMapper = func(raw string) string { - newstr := make([]rune, 0, len(raw)) - for i, chr := range raw { - if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { - if i > 0 { - newstr = append(newstr, '_') - } - } - newstr = append(newstr, unicode.ToUpper(chr)) - } - return string(newstr) - } - // TitleUnderscore converts to format title_underscore. - TitleUnderscore NameMapper = func(raw string) string { - newstr := make([]rune, 0, len(raw)) - for i, chr := range raw { - if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { - if i > 0 { - newstr = append(newstr, '_') - } - chr -= 'A' - 'a' - } - newstr = append(newstr, chr) - } - return string(newstr) - } -) - -func (s *Section) parseFieldName(raw, actual string) string { - if len(actual) > 0 { - return actual - } - if s.f.NameMapper != nil { - return s.f.NameMapper(raw) - } - return raw -} - -func parseDelim(actual string) string { - if len(actual) > 0 { - return actual - } - return "," -} - -var reflectTime = reflect.TypeOf(time.Now()).Kind() - -// setSliceWithProperType sets proper values to slice based on its type. -func setSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error { - var strs []string - if allowShadow { - strs = key.StringsWithShadows(delim) - } else { - strs = key.Strings(delim) - } - - numVals := len(strs) - if numVals == 0 { - return nil - } - - var vals interface{} - var err error - - sliceOf := field.Type().Elem().Kind() - switch sliceOf { - case reflect.String: - vals = strs - case reflect.Int: - vals, err = key.parseInts(strs, true, false) - case reflect.Int64: - vals, err = key.parseInt64s(strs, true, false) - case reflect.Uint: - vals, err = key.parseUints(strs, true, false) - case reflect.Uint64: - vals, err = key.parseUint64s(strs, true, false) - case reflect.Float64: - vals, err = key.parseFloat64s(strs, true, false) - case reflect.Bool: - vals, err = key.parseBools(strs, true, false) - case reflectTime: - vals, err = key.parseTimesFormat(time.RFC3339, strs, true, false) - default: - return fmt.Errorf("unsupported type '[]%s'", sliceOf) - } - if err != nil && isStrict { - return err - } - - slice := reflect.MakeSlice(field.Type(), numVals, numVals) - for i := 0; i < numVals; i++ { - switch sliceOf { - case reflect.String: - slice.Index(i).Set(reflect.ValueOf(vals.([]string)[i])) - case reflect.Int: - slice.Index(i).Set(reflect.ValueOf(vals.([]int)[i])) - case reflect.Int64: - slice.Index(i).Set(reflect.ValueOf(vals.([]int64)[i])) - case reflect.Uint: - slice.Index(i).Set(reflect.ValueOf(vals.([]uint)[i])) - case reflect.Uint64: - slice.Index(i).Set(reflect.ValueOf(vals.([]uint64)[i])) - case reflect.Float64: - slice.Index(i).Set(reflect.ValueOf(vals.([]float64)[i])) - case reflect.Bool: - slice.Index(i).Set(reflect.ValueOf(vals.([]bool)[i])) - case reflectTime: - slice.Index(i).Set(reflect.ValueOf(vals.([]time.Time)[i])) - } - } - field.Set(slice) - return nil -} - -func wrapStrictError(err error, isStrict bool) error { - if isStrict { - return err - } - return nil -} - -// setWithProperType sets proper value to field based on its type, -// but it does not return error for failing parsing, -// because we want to use default value that is already assigned to struct. -func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error { - vt := t - isPtr := t.Kind() == reflect.Ptr - if isPtr { - vt = t.Elem() - } - switch vt.Kind() { - case reflect.String: - stringVal := key.String() - if isPtr { - field.Set(reflect.ValueOf(&stringVal)) - } else if len(stringVal) > 0 { - field.SetString(key.String()) - } - case reflect.Bool: - boolVal, err := key.Bool() - if err != nil { - return wrapStrictError(err, isStrict) - } - if isPtr { - field.Set(reflect.ValueOf(&boolVal)) - } else { - field.SetBool(boolVal) - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - // ParseDuration will not return err for `0`, so check the type name - if vt.Name() == "Duration" { - durationVal, err := key.Duration() - if err != nil { - if intVal, err := key.Int64(); err == nil { - field.SetInt(intVal) - return nil - } - return wrapStrictError(err, isStrict) - } - if isPtr { - field.Set(reflect.ValueOf(&durationVal)) - } else if int64(durationVal) > 0 { - field.Set(reflect.ValueOf(durationVal)) - } - return nil - } - - intVal, err := key.Int64() - if err != nil { - return wrapStrictError(err, isStrict) - } - if isPtr { - pv := reflect.New(t.Elem()) - pv.Elem().SetInt(intVal) - field.Set(pv) - } else { - field.SetInt(intVal) - } - // byte is an alias for uint8, so supporting uint8 breaks support for byte - case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: - durationVal, err := key.Duration() - // Skip zero value - if err == nil && uint64(durationVal) > 0 { - if isPtr { - field.Set(reflect.ValueOf(&durationVal)) - } else { - field.Set(reflect.ValueOf(durationVal)) - } - return nil - } - - uintVal, err := key.Uint64() - if err != nil { - return wrapStrictError(err, isStrict) - } - if isPtr { - pv := reflect.New(t.Elem()) - pv.Elem().SetUint(uintVal) - field.Set(pv) - } else { - field.SetUint(uintVal) - } - - case reflect.Float32, reflect.Float64: - floatVal, err := key.Float64() - if err != nil { - return wrapStrictError(err, isStrict) - } - if isPtr { - pv := reflect.New(t.Elem()) - pv.Elem().SetFloat(floatVal) - field.Set(pv) - } else { - field.SetFloat(floatVal) - } - case reflectTime: - timeVal, err := key.Time() - if err != nil { - return wrapStrictError(err, isStrict) - } - if isPtr { - field.Set(reflect.ValueOf(&timeVal)) - } else { - field.Set(reflect.ValueOf(timeVal)) - } - case reflect.Slice: - return setSliceWithProperType(key, field, delim, allowShadow, isStrict) - default: - return fmt.Errorf("unsupported type %q", t) - } - return nil -} - -func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool, allowNonUnique bool, extends bool) { - opts := strings.SplitN(tag, ",", 5) - rawName = opts[0] - for _, opt := range opts[1:] { - omitEmpty = omitEmpty || (opt == "omitempty") - allowShadow = allowShadow || (opt == "allowshadow") - allowNonUnique = allowNonUnique || (opt == "nonunique") - extends = extends || (opt == "extends") - } - return rawName, omitEmpty, allowShadow, allowNonUnique, extends -} - -// mapToField maps the given value to the matching field of the given section. -// The sectionIndex is the index (if non unique sections are enabled) to which the value should be added. -func (s *Section) mapToField(val reflect.Value, isStrict bool, sectionIndex int, sectionName string) error { - if val.Kind() == reflect.Ptr { - val = val.Elem() - } - typ := val.Type() - - for i := 0; i < typ.NumField(); i++ { - field := val.Field(i) - tpField := typ.Field(i) - - tag := tpField.Tag.Get("ini") - if tag == "-" { - continue - } - - rawName, _, allowShadow, allowNonUnique, extends := parseTagOptions(tag) - fieldName := s.parseFieldName(tpField.Name, rawName) - if len(fieldName) == 0 || !field.CanSet() { - continue - } - - isStruct := tpField.Type.Kind() == reflect.Struct - isStructPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct - isAnonymousPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous - if isAnonymousPtr { - field.Set(reflect.New(tpField.Type.Elem())) - } - - if extends && (isAnonymousPtr || (isStruct && tpField.Anonymous)) { - if isStructPtr && field.IsNil() { - field.Set(reflect.New(tpField.Type.Elem())) - } - fieldSection := s - if rawName != "" { - sectionName = s.name + s.f.options.ChildSectionDelimiter + rawName - if secs, err := s.f.SectionsByName(sectionName); err == nil && sectionIndex < len(secs) { - fieldSection = secs[sectionIndex] - } - } - if err := fieldSection.mapToField(field, isStrict, sectionIndex, sectionName); err != nil { - return fmt.Errorf("map to field %q: %v", fieldName, err) - } - } else if isAnonymousPtr || isStruct || isStructPtr { - if secs, err := s.f.SectionsByName(fieldName); err == nil { - if len(secs) <= sectionIndex { - return fmt.Errorf("there are not enough sections (%d <= %d) for the field %q", len(secs), sectionIndex, fieldName) - } - // Only set the field to non-nil struct value if we have a section for it. - // Otherwise, we end up with a non-nil struct ptr even though there is no data. - if isStructPtr && field.IsNil() { - field.Set(reflect.New(tpField.Type.Elem())) - } - if err = secs[sectionIndex].mapToField(field, isStrict, sectionIndex, fieldName); err != nil { - return fmt.Errorf("map to field %q: %v", fieldName, err) - } - continue - } - } - - // Map non-unique sections - if allowNonUnique && tpField.Type.Kind() == reflect.Slice { - newField, err := s.mapToSlice(fieldName, field, isStrict) - if err != nil { - return fmt.Errorf("map to slice %q: %v", fieldName, err) - } - - field.Set(newField) - continue - } - - if key, err := s.GetKey(fieldName); err == nil { - delim := parseDelim(tpField.Tag.Get("delim")) - if err = setWithProperType(tpField.Type, key, field, delim, allowShadow, isStrict); err != nil { - return fmt.Errorf("set field %q: %v", fieldName, err) - } - } - } - return nil -} - -// mapToSlice maps all sections with the same name and returns the new value. -// The type of the Value must be a slice. -func (s *Section) mapToSlice(secName string, val reflect.Value, isStrict bool) (reflect.Value, error) { - secs, err := s.f.SectionsByName(secName) - if err != nil { - return reflect.Value{}, err - } - - typ := val.Type().Elem() - for i, sec := range secs { - elem := reflect.New(typ) - if err = sec.mapToField(elem, isStrict, i, sec.name); err != nil { - return reflect.Value{}, fmt.Errorf("map to field from section %q: %v", secName, err) - } - - val = reflect.Append(val, elem.Elem()) - } - return val, nil -} - -// mapTo maps a section to object v. -func (s *Section) mapTo(v interface{}, isStrict bool) error { - typ := reflect.TypeOf(v) - val := reflect.ValueOf(v) - if typ.Kind() == reflect.Ptr { - typ = typ.Elem() - val = val.Elem() - } else { - return errors.New("not a pointer to a struct") - } - - if typ.Kind() == reflect.Slice { - newField, err := s.mapToSlice(s.name, val, isStrict) - if err != nil { - return err - } - - val.Set(newField) - return nil - } - - return s.mapToField(val, isStrict, 0, s.name) -} - -// MapTo maps section to given struct. -func (s *Section) MapTo(v interface{}) error { - return s.mapTo(v, false) -} - -// StrictMapTo maps section to given struct in strict mode, -// which returns all possible error including value parsing error. -func (s *Section) StrictMapTo(v interface{}) error { - return s.mapTo(v, true) -} - -// MapTo maps file to given struct. -func (f *File) MapTo(v interface{}) error { - return f.Section("").MapTo(v) -} - -// StrictMapTo maps file to given struct in strict mode, -// which returns all possible error including value parsing error. -func (f *File) StrictMapTo(v interface{}) error { - return f.Section("").StrictMapTo(v) -} - -// MapToWithMapper maps data sources to given struct with name mapper. -func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error { - cfg, err := Load(source, others...) - if err != nil { - return err - } - cfg.NameMapper = mapper - return cfg.MapTo(v) -} - -// StrictMapToWithMapper maps data sources to given struct with name mapper in strict mode, -// which returns all possible error including value parsing error. -func StrictMapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error { - cfg, err := Load(source, others...) - if err != nil { - return err - } - cfg.NameMapper = mapper - return cfg.StrictMapTo(v) -} - -// MapTo maps data sources to given struct. -func MapTo(v, source interface{}, others ...interface{}) error { - return MapToWithMapper(v, nil, source, others...) -} - -// StrictMapTo maps data sources to given struct in strict mode, -// which returns all possible error including value parsing error. -func StrictMapTo(v, source interface{}, others ...interface{}) error { - return StrictMapToWithMapper(v, nil, source, others...) -} - -// reflectSliceWithProperType does the opposite thing as setSliceWithProperType. -func reflectSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow bool) error { - slice := field.Slice(0, field.Len()) - if field.Len() == 0 { - return nil - } - sliceOf := field.Type().Elem().Kind() - - if allowShadow { - var keyWithShadows *Key - for i := 0; i < field.Len(); i++ { - var val string - switch sliceOf { - case reflect.String: - val = slice.Index(i).String() - case reflect.Int, reflect.Int64: - val = fmt.Sprint(slice.Index(i).Int()) - case reflect.Uint, reflect.Uint64: - val = fmt.Sprint(slice.Index(i).Uint()) - case reflect.Float64: - val = fmt.Sprint(slice.Index(i).Float()) - case reflect.Bool: - val = fmt.Sprint(slice.Index(i).Bool()) - case reflectTime: - val = slice.Index(i).Interface().(time.Time).Format(time.RFC3339) - default: - return fmt.Errorf("unsupported type '[]%s'", sliceOf) - } - - if i == 0 { - keyWithShadows = newKey(key.s, key.name, val) - } else { - _ = keyWithShadows.AddShadow(val) - } - } - *key = *keyWithShadows - return nil - } - - var buf bytes.Buffer - for i := 0; i < field.Len(); i++ { - switch sliceOf { - case reflect.String: - buf.WriteString(slice.Index(i).String()) - case reflect.Int, reflect.Int64: - buf.WriteString(fmt.Sprint(slice.Index(i).Int())) - case reflect.Uint, reflect.Uint64: - buf.WriteString(fmt.Sprint(slice.Index(i).Uint())) - case reflect.Float64: - buf.WriteString(fmt.Sprint(slice.Index(i).Float())) - case reflect.Bool: - buf.WriteString(fmt.Sprint(slice.Index(i).Bool())) - case reflectTime: - buf.WriteString(slice.Index(i).Interface().(time.Time).Format(time.RFC3339)) - default: - return fmt.Errorf("unsupported type '[]%s'", sliceOf) - } - buf.WriteString(delim) - } - key.SetValue(buf.String()[:buf.Len()-len(delim)]) - return nil -} - -// reflectWithProperType does the opposite thing as setWithProperType. -func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow bool) error { - switch t.Kind() { - case reflect.String: - key.SetValue(field.String()) - case reflect.Bool: - key.SetValue(fmt.Sprint(field.Bool())) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - key.SetValue(fmt.Sprint(field.Int())) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - key.SetValue(fmt.Sprint(field.Uint())) - case reflect.Float32, reflect.Float64: - key.SetValue(fmt.Sprint(field.Float())) - case reflectTime: - key.SetValue(fmt.Sprint(field.Interface().(time.Time).Format(time.RFC3339))) - case reflect.Slice: - return reflectSliceWithProperType(key, field, delim, allowShadow) - case reflect.Ptr: - if !field.IsNil() { - return reflectWithProperType(t.Elem(), key, field.Elem(), delim, allowShadow) - } - default: - return fmt.Errorf("unsupported type %q", t) - } - return nil -} - -// CR: copied from encoding/json/encode.go with modifications of time.Time support. -// TODO: add more test coverage. -func isEmptyValue(v reflect.Value) bool { - switch v.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - return v.Len() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - case reflectTime: - t, ok := v.Interface().(time.Time) - return ok && t.IsZero() - } - return false -} - -// StructReflector is the interface implemented by struct types that can extract themselves into INI objects. -type StructReflector interface { - ReflectINIStruct(*File) error -} - -func (s *Section) reflectFrom(val reflect.Value) error { - if val.Kind() == reflect.Ptr { - val = val.Elem() - } - typ := val.Type() - - for i := 0; i < typ.NumField(); i++ { - if !val.Field(i).CanInterface() { - continue - } - - field := val.Field(i) - tpField := typ.Field(i) - - tag := tpField.Tag.Get("ini") - if tag == "-" { - continue - } - - rawName, omitEmpty, allowShadow, allowNonUnique, extends := parseTagOptions(tag) - if omitEmpty && isEmptyValue(field) { - continue - } - - if r, ok := field.Interface().(StructReflector); ok { - return r.ReflectINIStruct(s.f) - } - - fieldName := s.parseFieldName(tpField.Name, rawName) - if len(fieldName) == 0 || !field.CanSet() { - continue - } - - if extends && tpField.Anonymous && (tpField.Type.Kind() == reflect.Ptr || tpField.Type.Kind() == reflect.Struct) { - if err := s.reflectFrom(field); err != nil { - return fmt.Errorf("reflect from field %q: %v", fieldName, err) - } - continue - } - - if (tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct) || - (tpField.Type.Kind() == reflect.Struct && tpField.Type.Name() != "Time") { - // Note: The only error here is section doesn't exist. - sec, err := s.f.GetSection(fieldName) - if err != nil { - // Note: fieldName can never be empty here, ignore error. - sec, _ = s.f.NewSection(fieldName) - } - - // Add comment from comment tag - if len(sec.Comment) == 0 { - sec.Comment = tpField.Tag.Get("comment") - } - - if err = sec.reflectFrom(field); err != nil { - return fmt.Errorf("reflect from field %q: %v", fieldName, err) - } - continue - } - - if allowNonUnique && tpField.Type.Kind() == reflect.Slice { - slice := field.Slice(0, field.Len()) - if field.Len() == 0 { - return nil - } - sliceOf := field.Type().Elem().Kind() - - for i := 0; i < field.Len(); i++ { - if sliceOf != reflect.Struct && sliceOf != reflect.Ptr { - return fmt.Errorf("field %q is not a slice of pointer or struct", fieldName) - } - - sec, err := s.f.NewSection(fieldName) - if err != nil { - return err - } - - // Add comment from comment tag - if len(sec.Comment) == 0 { - sec.Comment = tpField.Tag.Get("comment") - } - - if err := sec.reflectFrom(slice.Index(i)); err != nil { - return fmt.Errorf("reflect from field %q: %v", fieldName, err) - } - } - continue - } - - // Note: Same reason as section. - key, err := s.GetKey(fieldName) - if err != nil { - key, _ = s.NewKey(fieldName, "") - } - - // Add comment from comment tag - if len(key.Comment) == 0 { - key.Comment = tpField.Tag.Get("comment") - } - - delim := parseDelim(tpField.Tag.Get("delim")) - if err = reflectWithProperType(tpField.Type, key, field, delim, allowShadow); err != nil { - return fmt.Errorf("reflect field %q: %v", fieldName, err) - } - - } - return nil -} - -// ReflectFrom reflects section from given struct. It overwrites existing ones. -func (s *Section) ReflectFrom(v interface{}) error { - typ := reflect.TypeOf(v) - val := reflect.ValueOf(v) - - if s.name != DefaultSection && s.f.options.AllowNonUniqueSections && - (typ.Kind() == reflect.Slice || typ.Kind() == reflect.Ptr) { - // Clear sections to make sure none exists before adding the new ones - s.f.DeleteSection(s.name) - - if typ.Kind() == reflect.Ptr { - sec, err := s.f.NewSection(s.name) - if err != nil { - return err - } - return sec.reflectFrom(val.Elem()) - } - - slice := val.Slice(0, val.Len()) - sliceOf := val.Type().Elem().Kind() - if sliceOf != reflect.Ptr { - return fmt.Errorf("not a slice of pointers") - } - - for i := 0; i < slice.Len(); i++ { - sec, err := s.f.NewSection(s.name) - if err != nil { - return err - } - - err = sec.reflectFrom(slice.Index(i)) - if err != nil { - return fmt.Errorf("reflect from %dth field: %v", i, err) - } - } - - return nil - } - - if typ.Kind() == reflect.Ptr { - val = val.Elem() - } else { - return errors.New("not a pointer to a struct") - } - - return s.reflectFrom(val) -} - -// ReflectFrom reflects file from given struct. -func (f *File) ReflectFrom(v interface{}) error { - return f.Section("").ReflectFrom(v) -} - -// ReflectFromWithMapper reflects data sources from given struct with name mapper. -func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error { - cfg.NameMapper = mapper - return cfg.ReflectFrom(v) -} - -// ReflectFrom reflects data sources from given struct. -func ReflectFrom(cfg *File, v interface{}) error { - return ReflectFromWithMapper(cfg, v, nil) -} diff --git a/vendor/github.com/lestrrat-go/httprc/v3/Changes b/vendor/github.com/lestrrat-go/httprc/v3/Changes index 4dc6f9f4b104..6a5eb8064a48 100644 --- a/vendor/github.com/lestrrat-go/httprc/v3/Changes +++ b/vendor/github.com/lestrrat-go/httprc/v3/Changes @@ -1,6 +1,10 @@ Changes ======= +v3.0.2 05 Dev 2025 +* Code changes mainly due to upgraded linter. +* github.com/lestrrat-go/option upgraded to v2 + v3.0.1 18 Aug 2025 * Refresh() no longer requires the resource to be ready. diff --git a/vendor/github.com/lestrrat-go/httprc/v3/client.go b/vendor/github.com/lestrrat-go/httprc/v3/client.go index 75ac3fc188c5..05dfbb43f398 100644 --- a/vendor/github.com/lestrrat-go/httprc/v3/client.go +++ b/vendor/github.com/lestrrat-go/httprc/v3/client.go @@ -51,6 +51,9 @@ type Client struct { // By default ALL urls are allowed. This may not be suitable for you if // are using this in a production environment. You are encouraged to specify // a whitelist using the `WithWhitelist` option. +// +// NOTE: In future versions, this function signature should be changed to +// return an error to properly handle option parsing failures. func NewClient(options ...NewClientOption) *Client { //nolint:staticcheck var errSink ErrorSink = errsink.NewNop() @@ -63,19 +66,18 @@ func NewClient(options ...NewClientOption) *Client { defaultMaxInterval := DefaultMaxInterval numWorkers := DefaultWorkers - //nolint:forcetypeassert for _, option := range options { switch option.Ident() { case identHTTPClient{}: - httpcl = option.Value().(HTTPClient) + _ = option.Value(&httpcl) case identWorkers{}: - numWorkers = option.Value().(int) + _ = option.Value(&numWorkers) case identErrorSink{}: - errSink = option.Value().(ErrorSink) + _ = option.Value(&errSink) case identTraceSink{}: - traceSink = option.Value().(TraceSink) + _ = option.Value(&traceSink) case identWhitelist{}: - wl = option.Value().(Whitelist) + _ = option.Value(&wl) } } diff --git a/vendor/github.com/lestrrat-go/httprc/v3/controller.go b/vendor/github.com/lestrrat-go/httprc/v3/controller.go index ae2eb218e426..1ad9d7b6c642 100644 --- a/vendor/github.com/lestrrat-go/httprc/v3/controller.go +++ b/vendor/github.com/lestrrat-go/httprc/v3/controller.go @@ -123,11 +123,12 @@ func (c *controller) Add(ctx context.Context, r Resource, options ...AddOption) c.traceSink.Put(ctx, fmt.Sprintf("httprc controller: START Add(%q)", r.URL())) defer c.traceSink.Put(ctx, fmt.Sprintf("httprc controller: END Add(%q)", r.URL())) waitReady := true - //nolint:forcetypeassert for _, option := range options { switch option.Ident() { case identWaitReady{}: - waitReady = option.(addOption).Value().(bool) + if err := option.Value(&waitReady); err != nil { + return fmt.Errorf(`httprc.Controller.Add: failed to parse WaitReady option: %w`, err) + } } } diff --git a/vendor/github.com/lestrrat-go/httprc/v3/options.go b/vendor/github.com/lestrrat-go/httprc/v3/options.go index 3f07b5671ca2..40cf891b15c3 100644 --- a/vendor/github.com/lestrrat-go/httprc/v3/options.go +++ b/vendor/github.com/lestrrat-go/httprc/v3/options.go @@ -3,7 +3,7 @@ package httprc import ( "time" - "github.com/lestrrat-go/option" + "github.com/lestrrat-go/option/v2" ) type NewClientOption interface { diff --git a/vendor/github.com/lestrrat-go/httprc/v3/resource.go b/vendor/github.com/lestrrat-go/httprc/v3/resource.go index e637f791fcc8..0f0d140d276a 100644 --- a/vendor/github.com/lestrrat-go/httprc/v3/resource.go +++ b/vendor/github.com/lestrrat-go/httprc/v3/resource.go @@ -41,17 +41,24 @@ func NewResource[T any](s string, transformer Transformer[T], options ...NewReso var interval time.Duration minInterval := DefaultMinInterval maxInterval := DefaultMaxInterval - //nolint:forcetypeassert for _, option := range options { switch option.Ident() { case identHTTPClient{}: - httpcl = option.Value().(HTTPClient) + if err := option.Value(&httpcl); err != nil { + return nil, fmt.Errorf(`httprc.NewResource: failed to parse HTTPClient option: %w`, err) + } case identMinimumInterval{}: - minInterval = option.Value().(time.Duration) + if err := option.Value(&minInterval); err != nil { + return nil, fmt.Errorf(`httprc.NewResource: failed to parse MinimumInterval option: %w`, err) + } case identMaximumInterval{}: - maxInterval = option.Value().(time.Duration) + if err := option.Value(&maxInterval); err != nil { + return nil, fmt.Errorf(`httprc.NewResource: failed to parse MaximumInterval option: %w`, err) + } case identConstantInterval{}: - interval = option.Value().(time.Duration) + if err := option.Value(&interval); err != nil { + return nil, fmt.Errorf(`httprc.NewResource: failed to parse ConstantInterval option: %w`, err) + } } } if transformer == nil { @@ -109,7 +116,7 @@ func (r *ResourceBase[T]) Ready(ctx context.Context) error { // returns `A` or `B` depending on the type of the resource. When accessing the // resource through the `httprc.Resource` interface, use this method to obtain the // stored value. -func (r *ResourceBase[T]) Get(dst interface{}) error { +func (r *ResourceBase[T]) Get(dst any) error { return blackmagic.AssignIfCompatible(dst, r.Resource()) } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/.golangci.yml b/vendor/github.com/lestrrat-go/jwx/v3/.golangci.yml index 214a9edaa833..30dc4c519bcb 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/.golangci.yml +++ b/vendor/github.com/lestrrat-go/jwx/v3/.golangci.yml @@ -106,6 +106,9 @@ linters: - revive path: jwt/internal/types/ text: "var-naming: avoid meaningless package names" + - linters: + - godoclint + path: (^|/)internal/ paths: - third_party$ - builtin$ diff --git a/vendor/github.com/lestrrat-go/jwx/v3/Changes b/vendor/github.com/lestrrat-go/jwx/v3/Changes index 29910bf35cb3..4df33b756cfe 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/Changes +++ b/vendor/github.com/lestrrat-go/jwx/v3/Changes @@ -4,6 +4,56 @@ Changes v3 has many incompatibilities with v2. To see the full list of differences between v2 and v3, please read the Changes-v3.md file (https://github.com/lestrrat-go/jwx/blob/develop/v3/Changes-v3.md) +v3.0.13 12 Jan 2026 + * [jwt] The `jwt.WithContext()` option is now properly being passed to `jws.Verify()` from + `jwt.Parse()`. + * [jwx] github.com/lestrrat-go/httprc/v3 has been upgraded to remove dependency on + github.com/lestrrat-go/option (v1) + * [jwk] `jwk.Clone()` has been fixed to properly work with private fields. + +v3.0.12 20 Oct 2025 + * [jwe] As part of the next change, now per-recipient headers that are empty + are no longer serialized in flattened JSON serialization. + + * [jwe] Introduce `jwe.WithLegacyHeaderMerging(bool)` option to control header + merging behavior in during JWE encryption. This only applies to flattened + JSON serialization. + + Previously, when using flattened JSON serialization (i.e. you specified + JSON serialization via `jwe.WithJSON()` and only supplied one key), per-recipient + headers were merged into the protected headers during encryption, and then + were left to be included in the final serialization as-is. This caused duplicate + headers to be present in both the protected headers and the per-recipient headers. + + Since there may be users who rely on this behavior already, instead of changing the + default behavior to fix this duplication, a new option to `jwe.Encrypt()` was added + to allow clearing the per-recipient headers after merging to leave the `"headers"` + field empty. This in effect makes the flattened JSON serialization more similar to + the compact serialization, where there are no per-recipient headers present, and + leaves the headers disjoint. + + Note that in compact mode, there are no per-recipient headers and thus the + headers need to be merged regardless. In full JSON serialization, we never + merge the headers, so it is left up to the user to keep the headers disjoint. + + * [jws] Calling the deprecated `jws.NewSigner()` function for the first time will cause + legacy signers to be loaded automatically. Previously, you had to explicitly + call `jws.Settings(jws.WithLegacySigners(true))` to enable legacy signers. + + We incorrectly assumed that users would not be using `jws.NewSigner()`, and thus + disabled legacy signers by default. However, it turned out that some users + were using `jws.NewSigner()` in their code, which lead to breakages in + existing code. In hindsight we should have known that any API made public before will + be used by _somebody_. + + As a side effect, jws.Settings(jws.WithLegacySigners(...)) is now a no-op. + + However, please do note that jws.Signer (and similar) objects were always intended to be + used for _registering_ new signing/verifying algorithms, and not for end users to actually + use them directly. If you are using them for other purposes, please consider changing + your code, as it is more than likely that we will somehow deprecate/remove/discouraged + their use in the future. + v3.0.11 14 Sep 2025 * [jwk] Add `(jwk.Cache).Shutdown()` method that delegates to the httprc controller object, to shutdown the cache. diff --git a/vendor/github.com/lestrrat-go/jwx/v3/MODULE.bazel b/vendor/github.com/lestrrat-go/jwx/v3/MODULE.bazel index 167e9b5c89d1..c9bdc9b730de 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/MODULE.bazel +++ b/vendor/github.com/lestrrat-go/jwx/v3/MODULE.bazel @@ -9,9 +9,9 @@ bazel_dep(name = "rules_go", version = "0.55.1") bazel_dep(name = "gazelle", version = "0.44.0") bazel_dep(name = "aspect_bazel_lib", version = "2.11.0") -# Go SDK setup - using Go 1.24.4 to match the toolchain in go.mod +# Go SDK setup from go.mod go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.24.4") +go_sdk.from_file(go_mod = "//:go.mod") # Go dependencies from go.mod go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") diff --git a/vendor/github.com/lestrrat-go/jwx/v3/formatkind_string_gen.go b/vendor/github.com/lestrrat-go/jwx/v3/formatkind_string_gen.go index 38abd1bc4751..ab7287214f48 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/formatkind_string_gen.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/formatkind_string_gen.go @@ -22,8 +22,9 @@ const _FormatKind_name = "InvalidFormatUnknownFormatJWEJWSJWKJWKSJWT" var _FormatKind_index = [...]uint8{0, 13, 26, 29, 32, 35, 39, 42} func (i FormatKind) String() string { - if i < 0 || i >= FormatKind(len(_FormatKind_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_FormatKind_index)-1 { return "FormatKind(" + strconv.FormatInt(int64(i), 10) + ")" } - return _FormatKind_name[_FormatKind_index[i]:_FormatKind_index[i+1]] + return _FormatKind_name[_FormatKind_index[idx]:_FormatKind_index[idx+1]] } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/internal/json/goccy.go b/vendor/github.com/lestrrat-go/jwx/v3/internal/json/goccy.go index e70a3c1edc22..9c99c098bcde 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/internal/json/goccy.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/internal/json/goccy.go @@ -1,5 +1,4 @@ //go:build jwx_goccy -// +build jwx_goccy package json diff --git a/vendor/github.com/lestrrat-go/jwx/v3/internal/json/stdlib.go b/vendor/github.com/lestrrat-go/jwx/v3/internal/json/stdlib.go index 6f416ec89a9e..9e51fa7fe97d 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/internal/json/stdlib.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/internal/json/stdlib.go @@ -1,6 +1,6 @@ //go:build !jwx_goccy -// +build !jwx_goccy +//nolint:revive package json import ( diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwa/secp2561k.go b/vendor/github.com/lestrrat-go/jwx/v3/jwa/secp2561k.go index e7a6be754ddb..9ce6ad4d0578 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwa/secp2561k.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwa/secp2561k.go @@ -1,5 +1,4 @@ //go:build jwx_es256k -// +build jwx_es256k package jwa diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/aescbc/aescbc.go b/vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/aescbc/aescbc.go index b572674e2dd1..4f08c4936fd9 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/aescbc/aescbc.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/aescbc/aescbc.go @@ -72,9 +72,7 @@ func extractPadding(payload []byte) (toRemove int, good byte) { // The maximum possible padding length plus the actual length field toCheck := 256 // The length of the padded data is public, so we can use an if here - if toCheck > len(payload) { - toCheck = len(payload) - } + toCheck = min(toCheck, len(payload)) for i := 1; i <= toCheck; i++ { t := uint(paddingLen) - uint(i) diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwe/jwe.go b/vendor/github.com/lestrrat-go/jwx/v3/jwe/jwe.go index 5728021ec7d8..5b9c92771ab3 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwe/jwe.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwe/jwe.go @@ -99,15 +99,20 @@ func (b *recipientBuilder) Build(r Recipient, cek []byte, calg jwa.ContentEncryp rawKey = raw } - // Extract ECDH-ES specific parameters if needed + // Extract ECDH-ES specific parameters if needed. var apu, apv []byte - if b.headers != nil { - if val, ok := b.headers.AgreementPartyUInfo(); ok { - apu = val - } - if val, ok := b.headers.AgreementPartyVInfo(); ok { - apv = val - } + + hdr := b.headers + if hdr == nil { + hdr = NewHeaders() + } + + if val, ok := hdr.AgreementPartyUInfo(); ok { + apu = val + } + + if val, ok := hdr.AgreementPartyVInfo(); ok { + apv = val } // Create the encrypter using the new jwebb pattern @@ -116,20 +121,20 @@ func (b *recipientBuilder) Build(r Recipient, cek []byte, calg jwa.ContentEncryp return nil, fmt.Errorf(`jwe.Encrypt: recipientBuilder: failed to create encrypter: %w`, err) } - if hdrs := b.headers; hdrs != nil { - _ = r.SetHeaders(hdrs) - } + _ = r.SetHeaders(hdr) - if err := r.Headers().Set(AlgorithmKey, b.alg); err != nil { + // Populate headers with stuff that we automatically set + if err := hdr.Set(AlgorithmKey, b.alg); err != nil { return nil, fmt.Errorf(`failed to set header: %w`, err) } if keyID != "" { - if err := r.Headers().Set(KeyIDKey, keyID); err != nil { + if err := hdr.Set(KeyIDKey, keyID); err != nil { return nil, fmt.Errorf(`failed to set header: %w`, err) } } + // Handle the encrypted key var rawCEK []byte enckey, err := enc.EncryptKey(cek) if err != nil { @@ -143,8 +148,9 @@ func (b *recipientBuilder) Build(r Recipient, cek []byte, calg jwa.ContentEncryp } } + // finally, anything specific should go here if hp, ok := enckey.(populater); ok { - if err := hp.Populate(r.Headers()); err != nil { + if err := hp.Populate(hdr); err != nil { return nil, fmt.Errorf(`failed to populate: %w`, err) } } @@ -154,7 +160,9 @@ func (b *recipientBuilder) Build(r Recipient, cek []byte, calg jwa.ContentEncryp // Encrypt generates a JWE message for the given payload and returns // it in serialized form, which can be in either compact or -// JSON format. Default is compact. +// JSON format. Default is compact. When JSON format is specified and +// there is only one recipient, the resulting serialization is +// automatically converted to flattened JSON serialization format. // // You must pass at least one key to `jwe.Encrypt()` by using `jwe.WithKey()` // option. @@ -172,6 +180,10 @@ func (b *recipientBuilder) Build(r Recipient, cek []byte, calg jwa.ContentEncryp // // Look for options that return `jwe.EncryptOption` or `jws.EncryptDecryptOption` // for a complete list of options that can be passed to this function. +// +// As of v3.0.12, users can specify `jwe.WithLegacyHeaderMerging()` to +// disable header merging behavior that was the default prior to v3.0.12. +// Read the documentation for `jwe.WithLegacyHeaderMerging()` for more information. func Encrypt(payload []byte, options ...EncryptOption) ([]byte, error) { ec := encryptContextPool.Get() defer encryptContextPool.Put(ec) @@ -410,10 +422,26 @@ func (dc *decryptContext) decryptContent(msg *Message, alg jwa.KeyEncryptionAlgo Tag(msg.tag). CEK(dc.cek) - if v, ok := recipient.Headers().Algorithm(); !ok || v != alg { - // algorithms don't match + // The "alg" header can be in either protected/unprotected headers. + // prefer per-recipient headers (as it might be the case that the algorithm differs + // by each recipient), then look at protected headers. + var algMatched bool + for _, hdr := range []Headers{recipient.Headers(), protectedHeaders} { + v, ok := hdr.Algorithm() + if !ok { + continue + } + + if v == alg { + algMatched = true + break + } + // if we found something but didn't match, it's a failure return nil, fmt.Errorf(`jwe.Decrypt: key (%q) and recipient (%q) algorithms do not match`, alg, v) } + if !algMatched { + return nil, fmt.Errorf(`jwe.Decrypt: failed to find "alg" header in either protected or per-recipient headers`) + } h2, err := protectedHeaders.Clone() if err != nil { @@ -534,11 +562,12 @@ func (dc *decryptContext) decryptContent(msg *Message, alg jwa.KeyEncryptionAlgo // encryptContext holds the state during JWE encryption, similar to JWS signContext type encryptContext struct { - calg jwa.ContentEncryptionAlgorithm - compression jwa.CompressionAlgorithm - format int - builders []*recipientBuilder - protected Headers + calg jwa.ContentEncryptionAlgorithm + compression jwa.CompressionAlgorithm + format int + builders []*recipientBuilder + protected Headers + legacyHeaderMerging bool } var encryptContextPool = pool.New(allocEncryptContext, freeEncryptContext) @@ -561,6 +590,7 @@ func freeEncryptContext(ec *encryptContext) *encryptContext { } func (ec *encryptContext) ProcessOptions(options []EncryptOption) error { + ec.legacyHeaderMerging = true var mergeProtected bool var useRawCEK bool for _, option := range options { @@ -577,7 +607,11 @@ func (ec *encryptContext) ProcessOptions(options []EncryptOption) error { if v == jwa.DIRECT() || v == jwa.ECDH_ES() { useRawCEK = true } - ec.builders = append(ec.builders, &recipientBuilder{alg: v, key: wk.key, headers: wk.headers}) + ec.builders = append(ec.builders, &recipientBuilder{ + alg: v, + key: wk.key, + headers: wk.headers, + }) case identContentEncryptionAlgorithm{}: var c jwa.ContentEncryptionAlgorithm if err := option.Value(&c); err != nil { @@ -616,6 +650,12 @@ func (ec *encryptContext) ProcessOptions(options []EncryptOption) error { return err } ec.format = fmtOpt + case identLegacyHeaderMerging{}: + var v bool + if err := option.Value(&v); err != nil { + return err + } + ec.legacyHeaderMerging = v } } @@ -732,7 +772,8 @@ func (ec *encryptContext) EncryptMessage(payload []byte, cek []byte) ([]byte, er } } - recipients := recipientSlicePool.GetCapacity(len(ec.builders)) + lbuilders := len(ec.builders) + recipients := recipientSlicePool.GetCapacity(lbuilders) defer recipientSlicePool.Put(recipients) for i, builder := range ec.builders { @@ -767,14 +808,55 @@ func (ec *encryptContext) EncryptMessage(payload []byte, cek []byte) ([]byte, er } } - // If there's only one recipient, you want to include that in the - // protected header - if len(recipients) == 1 { + // fmtCompact does not have per-recipient headers, nor a "header" field. + // In this mode, we're going to have to merge everything to the protected + // header. + if ec.format == fmtCompact { + // We have already established that the number of builders is 1 in + // ec.ProcessOptions(). But we're going to be pedantic + if lbuilders != 1 { + return nil, fmt.Errorf(`internal error: expected exactly one recipient builder (got %d)`, lbuilders) + } + + // when we're using compact format, we can safely merge per-recipient + // headers into the protected header, if any h, err := protected.Merge(recipients[0].Headers()) if err != nil { - return nil, fmt.Errorf(`failed to merge protected headers: %w`, err) + return nil, fmt.Errorf(`failed to merge protected headers for compact serialization: %w`, err) } protected = h + // per-recipient headers, if any, will be ignored in compact format + } else { + // If it got here, it's JSON (could be pretty mode, too). + if lbuilders == 1 { + // If it got here, then we're doing flattened JSON serialization. + // In this mode, we should merge per-recipient headers into the protected header, + // but we also need to make sure that the "header" field is reset so that + // it does not contain the same fields as the protected header. + // + // However, old behavior was to merge per-recipient headers into the + // protected header when there was only one recipient, AND leave the + // original "header" field as is, so we need to support that for backwards compatibility. + // + // The legacy merging only takes effect when there is exactly one recipient. + // + // This behavior can be disabled by passing jwe.WithLegacyHeaderMerging(false) + // If the user has explicitly asked for merging, do it + h, err := protected.Merge(recipients[0].Headers()) + if err != nil { + return nil, fmt.Errorf(`failed to merge protected headers for flattenend JSON format: %w`, err) + } + protected = h + + if !ec.legacyHeaderMerging { + // Clear per-recipient headers, since they have been merged. + // But we only do it when legacy merging is disabled. + // Note: we should probably introduce a Reset() method in v4 + if err := recipients[0].SetHeaders(NewHeaders()); err != nil { + return nil, fmt.Errorf(`failed to clear per-recipient headers after merging: %w`, err) + } + } + } } aad, err := protected.Encode() diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwe/message.go b/vendor/github.com/lestrrat-go/jwx/v3/jwe/message.go index 13cf3dec8302..7aad833f2624 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwe/message.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwe/message.go @@ -265,14 +265,23 @@ func (m *Message) MarshalJSON() ([]byte, error) { if recipients := m.Recipients(); len(recipients) > 0 { if len(recipients) == 1 { // Use flattened format if hdrs := recipients[0].Headers(); hdrs != nil { - buf.Reset() - if err := enc.Encode(hdrs); err != nil { - return nil, fmt.Errorf(`failed to encode %s field: %w`, HeadersKey, err) + var skipHeaders bool + if zeroer, ok := hdrs.(isZeroer); ok { + if zeroer.isZero() { + skipHeaders = true + } + } + + if !skipHeaders { + buf.Reset() + if err := enc.Encode(hdrs); err != nil { + return nil, fmt.Errorf(`failed to encode %s field: %w`, HeadersKey, err) + } + fields = append(fields, jsonKV{ + Key: HeadersKey, + Value: strings.TrimSpace(buf.String()), + }) } - fields = append(fields, jsonKV{ - Key: HeadersKey, - Value: strings.TrimSpace(buf.String()), - }) } if ek := recipients[0].EncryptedKey(); len(ek) > 0 { @@ -369,13 +378,18 @@ func (m *Message) UnmarshalJSON(buf []byte) error { // field. TODO: do both of these conditions need to meet, or just one? if proxy.Headers != nil || len(proxy.EncryptedKey) > 0 { recipient := NewRecipient() - hdrs := NewHeaders() - if err := json.Unmarshal(proxy.Headers, hdrs); err != nil { - return fmt.Errorf(`failed to decode headers field: %w`, err) - } - if err := recipient.SetHeaders(hdrs); err != nil { - return fmt.Errorf(`failed to set new headers: %w`, err) + // `"heders"` could be empty. If that's the case, just skip the + // following unmarshaling step + if proxy.Headers != nil { + hdrs := NewHeaders() + if err := json.Unmarshal(proxy.Headers, hdrs); err != nil { + return fmt.Errorf(`failed to decode headers field: %w`, err) + } + + if err := recipient.SetHeaders(hdrs); err != nil { + return fmt.Errorf(`failed to set new headers: %w`, err) + } } if v := proxy.EncryptedKey; len(v) > 0 { diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.go b/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.go index c9137eecf4a3..0437ea8733d6 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.go @@ -6,8 +6,9 @@ import ( "github.com/lestrrat-go/option/v2" ) -// Specify contents of the protected header. Some fields such as -// "enc" and "zip" will be overwritten when encryption is performed. +// WithProtectedHeaders is used to specify contents of the protected header. +// Some fields such as "enc" and "zip" will be overwritten when encryption is +// performed. // // There is no equivalent for unprotected headers in this implementation func WithProtectedHeaders(h Headers) EncryptOption { diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.yaml b/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.yaml index b7fb0262deb1..359d80944dab 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.yaml +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwe/options.yaml @@ -169,4 +169,42 @@ options: If set to an invalid value, the default value is used. In v2, this option was called MaxBufferSize. - This option has a global effect. \ No newline at end of file + This option has a global effect. + - ident: LegacyHeaderMerging + interface: EncryptOption + argument_type: bool + option_name: WithLegacyHeaderMerging + comment: | + WithLegacyHeaderMerging specifies whether to perform legacy header merging + when encrypting a JWE message in JSON serialization, when there is a single recipient. + This behavior is enabled by default for backwards compatibility. + + When a JWE message is encrypted in JSON serialization, and there is only + one recipient, this library automatically serializes the message in + flattened JSON serialization format. In older versions of this library, + the protected headers and the per-recipient headers were merged together + before computing the AAD (Additional Authenticated Data), but the per-recipient + headers were kept as-is in the `header` field of the recipient object. + + This behavior is not compliant with the JWE specification, which states that + the headers must be disjoint. + + Passing this option with a value of `false` disables this legacy behavior, + and while the per-recipient headers and protected headers are still merged + for the purpose of computing AAD, the per-recipient headers are cleared + after merging, so that the resulting JWE message is compliant with the + specification. + + This option has no effect when there are multiple recipients, or when + the serialization format is compact serialization. For multiple recipients + (i.e. full JSON serialization), the protected headers and per-recipient + headers are never merged, and it is the caller's responsibility to ensure + that the headers are disjoint. In compact serialization, there are no per-recipient + headers; in fact, the protected headers are the only headers that exist, + and therefore there is no possibility of header collision after merging + (note: while per-recipient headers do not make sense in compact serialization, + this library does not prevent you from setting them -- they are all just + merged into the protected headers). + + In future versions, the new behavior will be the default. New users are + encouraged to set this option to `false` now to avoid future issues. \ No newline at end of file diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwe/options_gen.go b/vendor/github.com/lestrrat-go/jwx/v3/jwe/options_gen.go index 2a15c141b42a..2d28eecb442e 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwe/options_gen.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwe/options_gen.go @@ -147,6 +147,7 @@ type identFS struct{} type identKey struct{} type identKeyProvider struct{} type identKeyUsed struct{} +type identLegacyHeaderMerging struct{} type identMaxDecompressBufferSize struct{} type identMaxPBES2Count struct{} type identMergeProtectedHeaders struct{} @@ -193,6 +194,10 @@ func (identKeyUsed) String() string { return "WithKeyUsed" } +func (identLegacyHeaderMerging) String() string { + return "WithLegacyHeaderMerging" +} + func (identMaxDecompressBufferSize) String() string { return "WithMaxDecompressBufferSize" } @@ -292,6 +297,43 @@ func WithKeyUsed(v any) DecryptOption { return &decryptOption{option.New(identKeyUsed{}, v)} } +// WithLegacyHeaderMerging specifies whether to perform legacy header merging +// when encrypting a JWE message in JSON serialization, when there is a single recipient. +// This behavior is enabled by default for backwards compatibility. +// +// When a JWE message is encrypted in JSON serialization, and there is only +// one recipient, this library automatically serializes the message in +// flattened JSON serialization format. In older versions of this library, +// the protected headers and the per-recipient headers were merged together +// before computing the AAD (Additional Authenticated Data), but the per-recipient +// headers were kept as-is in the `header` field of the recipient object. +// +// This behavior is not compliant with the JWE specification, which states that +// the headers must be disjoint. +// +// Passing this option with a value of `false` disables this legacy behavior, +// and while the per-recipient headers and protected headers are still merged +// for the purpose of computing AAD, the per-recipient headers are cleared +// after merging, so that the resulting JWE message is compliant with the +// specification. +// +// This option has no effect when there are multiple recipients, or when +// the serialization format is compact serialization. For multiple recipients +// (i.e. full JSON serialization), the protected headers and per-recipient +// headers are never merged, and it is the caller's responsibility to ensure +// that the headers are disjoint. In compact serialization, there are no per-recipient +// headers; in fact, the protected headers are the only headers that exist, +// and therefore there is no possibility of header collision after merging +// (note: while per-recipient headers do not make sense in compact serialization, +// this library does not prevent you from setting them -- they are all just +// merged into the protected headers). +// +// In future versions, the new behavior will be the default. New users are +// encouraged to set this option to `false` now to avoid future issues. +func WithLegacyHeaderMerging(v bool) EncryptOption { + return &encryptOption{option.New(identLegacyHeaderMerging{}, v)} +} + // WithMaxDecompressBufferSize specifies the maximum buffer size for used when // decompressing the payload of a JWE message. If a compressed JWE payload // exceeds this amount when decompressed, jwe.Decrypt will return an error. diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/cache.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/cache.go index b83b56c79081..6d5b00f05667 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/cache.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/cache.go @@ -270,7 +270,7 @@ func (cs *cachedSet) cached() (Set, error) { return cs.r.Resource(), nil } -// Add is a no-op for `jwk.CachedSet`, as the `jwk.Set` should be treated read-only +// AddKey is a no-op for `jwk.CachedSet`, as the `jwk.Set` should be treated read-only func (*cachedSet) AddKey(_ Key) error { return fmt.Errorf(`(jwk.Cachedset).AddKey: jwk.CachedSet is immutable`) } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa.go index 3dcd33bb1f47..8f76d0508e7f 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa.go @@ -141,8 +141,8 @@ func buildECDHPrivateKey(alg jwa.EllipticCurveAlgorithm, dbuf []byte) (*ecdh.Pri } var ecdsaConvertibleTypes = []reflect.Type{ - reflect.TypeOf((*ECDSAPrivateKey)(nil)).Elem(), - reflect.TypeOf((*ECDSAPublicKey)(nil)).Elem(), + reflect.TypeFor[ECDSAPrivateKey](), + reflect.TypeFor[ECDSAPublicKey](), } func ecdsaJWKToRaw(keyif Key, hint any) (any, error) { diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/es256k.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/es256k.go index 48114bbaeeb7..293988db4bb5 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/es256k.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/es256k.go @@ -1,5 +1,4 @@ //go:build jwx_es256k -// +build jwx_es256k package jwk diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/fetch.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/fetch.go index 910a2101d490..2c80a369dc16 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/fetch.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/fetch.go @@ -40,7 +40,7 @@ type CachedFetcher struct { cache *Cache } -// Creates a new `jwk.CachedFetcher` object. +// NewCachedFetcher creates a new `jwk.CachedFetcher` object. func NewCachedFetcher(cache *Cache) *CachedFetcher { return &CachedFetcher{cache} } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/interface.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/interface.go index c157c2362cbc..c5a22a43fbd6 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/interface.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/interface.go @@ -92,9 +92,14 @@ type Set interface { Len() int // LookupKeyID returns the first key matching the given key id. + // // The second return value is false if there are no keys matching the key id. // The set *may* contain multiple keys with the same key id. If you - // need all of them, use `Iterate()` + // need all of them, Len() and Key(int) + // + // This method is meant to be used to lookup a key with a unique ID. + // Bacauseof this, you cannot use this method to lookup keys with an empty key ID + // (i.e. `kid` is not specified, or is an empty string). LookupKeyID(string) (Key, bool) // RemoveKey removes the key from the set. diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/jwk.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/jwk.go index 785feaf94c12..22d4950d8f4c 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/jwk.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/jwk.go @@ -13,6 +13,7 @@ import ( "io" "math/big" "reflect" + "slices" "github.com/lestrrat-go/jwx/v3/internal/base64" "github.com/lestrrat-go/jwx/v3/internal/json" @@ -30,14 +31,14 @@ func bigIntToBytes(n *big.Int) ([]byte, error) { func init() { if err := RegisterProbeField(reflect.StructField{ Name: "Kty", - Type: reflect.TypeOf(""), + Type: reflect.TypeFor[string](), Tag: `json:"kty"`, }); err != nil { panic(fmt.Errorf("failed to register mandatory probe for 'kty' field: %w", err)) } if err := RegisterProbeField(reflect.StructField{ Name: "D", - Type: reflect.TypeOf(json.RawMessage(nil)), + Type: reflect.TypeFor[json.RawMessage](), Tag: `json:"d,omitempty"`, }); err != nil { panic(fmt.Errorf("failed to register mandatory probe for 'kty' field: %w", err)) @@ -665,10 +666,10 @@ func extractEmbeddedKey(keyif Key, concretTypes []reflect.Type) (Key, error) { rv := reflect.ValueOf(keyif) // If the value can be converted to one of the concrete types, then we're done - for _, t := range concretTypes { - if rv.Type().ConvertibleTo(t) { - return keyif, nil - } + if slices.ContainsFunc(concretTypes, func(t reflect.Type) bool { + return rv.Type().ConvertibleTo(t) + }) { + return keyif, nil } // When a struct implements the Key interface via embedding, you unfortunately diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/okp.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/okp.go index 773734b660db..7cbf66c2d8e1 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/okp.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/okp.go @@ -141,8 +141,8 @@ func buildOKPPrivateKey(alg jwa.EllipticCurveAlgorithm, xbuf []byte, dbuf []byte } var okpConvertibleKeys = []reflect.Type{ - reflect.TypeOf((*OKPPrivateKey)(nil)).Elem(), - reflect.TypeOf((*OKPPublicKey)(nil)).Elem(), + reflect.TypeFor[OKPPrivateKey](), + reflect.TypeFor[OKPPublicKey](), } // This is half baked. I think it will blow up if we used ecdh.* keys and/or x25519 keys diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/rsa.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/rsa.go index bcd7d05c026c..ca2768158736 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/rsa.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/rsa.go @@ -115,8 +115,8 @@ func buildRSAPublicKey(key *rsa.PublicKey, n, e []byte) { } var rsaConvertibleKeys = []reflect.Type{ - reflect.TypeOf((*RSAPrivateKey)(nil)).Elem(), - reflect.TypeOf((*RSAPublicKey)(nil)).Elem(), + reflect.TypeFor[RSAPrivateKey](), + reflect.TypeFor[RSAPublicKey](), } func rsaJWKToRaw(key Key, hint any) (any, error) { diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/set.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/set.go index 89d8646874aa..6f339649a886 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/set.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/set.go @@ -3,6 +3,7 @@ package jwk import ( "bytes" "fmt" + "maps" "reflect" "sort" @@ -14,13 +15,17 @@ import ( const keysKey = `keys` // appease linter -// NewSet creates and empty `jwk.Set` object -func NewSet() Set { +func newSet() *set { return &set{ privateParams: make(map[string]any), } } +// NewSet creates and empty `jwk.Set` object +func NewSet() Set { + return newSet() +} + func (s *set) Set(n string, v any) error { s.mu.RLock() defer s.mu.RUnlock() @@ -300,12 +305,15 @@ func (s *set) SetDecodeCtx(dc DecodeCtx) { } func (s *set) Clone() (Set, error) { - s2 := &set{} + s2 := newSet() s.mu.RLock() defer s.mu.RUnlock() s2.keys = make([]Key, len(s.keys)) copy(s2.keys, s.keys) + + maps.Copy(s2.privateParams, s.privateParams) + return s2, nil } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/symmetric.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/symmetric.go index 16427ff86f18..7db5e1591ada 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/symmetric.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/symmetric.go @@ -27,7 +27,7 @@ func (k *symmetricKey) Import(rawKey []byte) error { } var symmetricConvertibleKeys = []reflect.Type{ - reflect.TypeOf((*SymmetricKey)(nil)).Elem(), + reflect.TypeFor[SymmetricKey](), } func octetSeqToRaw(key Key, hint any) (any, error) { diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwk/x509.go b/vendor/github.com/lestrrat-go/jwx/v3/jwk/x509.go index c0a7c4c4d941..f06063c6ed52 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwk/x509.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwk/x509.go @@ -118,7 +118,7 @@ func NewPEMDecoder() PEMDecoder { type pemDecoder struct{} -// DecodePEM decodes a key in PEM encoded ASN.1 DER format. +// Decode decodes a key in PEM encoded ASN.1 DER format. // and returns a raw key. func (pemDecoder) Decode(src []byte) (any, []byte, error) { block, rest := pem.Decode(src) diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/es256k.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/es256k.go index 3b68c4614405..28ebd2ea0ebd 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/es256k.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/es256k.go @@ -1,5 +1,4 @@ //go:build jwx_es256k -// +build jwx_es256k package jws diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/jws.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/jws.go index 1fa77438b9a4..f09e40db2d29 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/jws.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/jws.go @@ -535,12 +535,12 @@ var rawKeyToKeyType = make(map[reflect.Type]jwa.KeyType) var keyTypeToAlgorithms = make(map[jwa.KeyType][]jwa.SignatureAlgorithm) func init() { - rawKeyToKeyType[reflect.TypeOf([]byte(nil))] = jwa.OctetSeq() - rawKeyToKeyType[reflect.TypeOf(ed25519.PublicKey(nil))] = jwa.OKP() - rawKeyToKeyType[reflect.TypeOf(rsa.PublicKey{})] = jwa.RSA() - rawKeyToKeyType[reflect.TypeOf((*rsa.PublicKey)(nil))] = jwa.RSA() - rawKeyToKeyType[reflect.TypeOf(ecdsa.PublicKey{})] = jwa.EC() - rawKeyToKeyType[reflect.TypeOf((*ecdsa.PublicKey)(nil))] = jwa.EC() + rawKeyToKeyType[reflect.TypeFor[[]byte]()] = jwa.OctetSeq() + rawKeyToKeyType[reflect.TypeFor[ed25519.PublicKey]()] = jwa.OKP() + rawKeyToKeyType[reflect.TypeFor[rsa.PublicKey]()] = jwa.RSA() + rawKeyToKeyType[reflect.TypeFor[*rsa.PublicKey]()] = jwa.RSA() + rawKeyToKeyType[reflect.TypeFor[ecdsa.PublicKey]()] = jwa.EC() + rawKeyToKeyType[reflect.TypeFor[*ecdsa.PublicKey]()] = jwa.EC() addAlgorithmForKeyType(jwa.OKP(), jwa.EdDSA()) for _, alg := range []jwa.SignatureAlgorithm{jwa.HS256(), jwa.HS384(), jwa.HS512()} { @@ -586,11 +586,14 @@ func AlgorithmsForKey(key any) ([]jwa.SignatureAlgorithm, error) { return algs, nil } +// Settings allows you to set global settings for this JWS operations. +// +// Currently, the only setting available is `jws.WithLegacySigners()`, +// which for various reason is now a no-op. func Settings(options ...GlobalOption) { for _, option := range options { switch option.Ident() { case identLegacySigners{}: - enableLegacySigners() } } } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/header.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/header.go index d50c38eeb132..cac3987ea55d 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/header.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/header.go @@ -26,7 +26,7 @@ func (e headerNotFoundError) Is(target error) bool { } } -// ErrHeaderdNotFound returns an error that can be passed to `errors.Is` to check if the error is +// ErrHeaderNotFound returns an error that can be passed to `errors.Is` to check if the error is // the result of the field not being found func ErrHeaderNotFound() error { return headerNotFoundError{} diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy.go index a6687d68cb38..767ad723a3af 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy.go @@ -2,11 +2,14 @@ package jws import ( "fmt" + "sync" "github.com/lestrrat-go/jwx/v3/jwa" "github.com/lestrrat-go/jwx/v3/jws/legacy" ) +var enableLegacySignersOnce = &sync.Once{} + func enableLegacySigners() { for _, alg := range []jwa.SignatureAlgorithm{jwa.HS256(), jwa.HS384(), jwa.HS512()} { if err := RegisterSigner(alg, func(alg jwa.SignatureAlgorithm) SignerFactory { @@ -74,7 +77,7 @@ func legacySignerFor(alg jwa.SignatureAlgorithm) (Signer, error) { muSigner.Lock() s, ok := signers[alg] if !ok { - v, err := NewSigner(alg) + v, err := newLegacySigner(alg) if err != nil { muSigner.Unlock() return nil, fmt.Errorf(`failed to create payload signer: %w`, err) diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/legacy.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/legacy.go index 84a252742812..fe69b55e05bf 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/legacy.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/legacy.go @@ -23,7 +23,7 @@ type Signer interface { Algorithm() jwa.SignatureAlgorithm } -// This is for legacy support only. +// Verifier is for legacy support only. type Verifier interface { // Verify checks whether the payload and signature are valid for // the given key. diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/options.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/options.go index 729e561936bc..4c217c348368 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/options.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/options.go @@ -38,7 +38,7 @@ type withKey struct { public Headers } -// This exists as an escape hatch to modify the header values after the fact +// Protected exists as an escape hatch to modify the header values after the fact func (w *withKey) Protected(v Headers) Headers { if w.protected == nil && v != nil { w.protected = v @@ -221,7 +221,7 @@ type withInsecureNoSignature struct { protected Headers } -// This exists as an escape hatch to modify the header values after the fact +// Protected exists as an escape hatch to modify the header values after the fact func (w *withInsecureNoSignature) Protected(v Headers) Headers { if w.protected == nil && v != nil { w.protected = v diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/options.yaml b/vendor/github.com/lestrrat-go/jwx/v3/jws/options.yaml index 303ab3a32e9e..79dbb7250084 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/options.yaml +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/options.yaml @@ -227,8 +227,4 @@ options: interface: GlobalOption constant_value: true comment: | - WithLegacySigners specifies whether the JWS package should use legacy - signers for signing JWS messages. - - Usually there's no need to use this option, as the new signers and - verifiers are loaded by default. + WithLegacySigners is a no-op option that exists only for backwards compatibility. diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/options_gen.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/options_gen.go index b97cf7e8dd9d..7013e86bd78d 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/options_gen.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/options_gen.go @@ -356,11 +356,7 @@ func WithKeyUsed(v any) VerifyOption { return &verifyOption{option.New(identKeyUsed{}, v)} } -// WithLegacySigners specifies whether the JWS package should use legacy -// signers for signing JWS messages. -// -// Usually there's no need to use this option, as the new signers and -// verifiers are loaded by default. +// WithLegacySigners is a no-op option that exists only for backwards compatibility. func WithLegacySigners() GlobalOption { return &globalOption{option.New(identLegacySigners{}, true)} } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jws/signer.go b/vendor/github.com/lestrrat-go/jwx/v3/jws/signer.go index 340666931f51..99005e859a0b 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jws/signer.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jws/signer.go @@ -2,6 +2,7 @@ package jws import ( "fmt" + "strings" "sync" "github.com/lestrrat-go/jwx/v3/jwa" @@ -33,6 +34,19 @@ func (fn SignerFactoryFn) Create() (Signer, error) { return fn() } +func init() { + // register the signers using jwsbb. These will be used by default. + for _, alg := range jwa.SignatureAlgorithms() { + if alg == jwa.NoSignature() { + continue + } + + if err := RegisterSigner(alg, defaultSigner{alg: alg}); err != nil { + panic(fmt.Sprintf("RegisterSigner failed: %v", err)) + } + } +} + // SignerFor returns a Signer2 for the given signature algorithm. // // Currently, this function will never fail. It will always return a @@ -43,6 +57,9 @@ func (fn SignerFactoryFn) Create() (Signer, error) { // 3. If no Signer2 or legacy Signer(Factory) is registered, it will return a // default signer that uses jwsbb.Sign. // +// 1 and 2 will take care of 99% of the cases. The only time 3 will happen is +// when you are using a custom algorithm that is not supported out of the box. +// // jwsbb.Sign knows how to handle a static set of algorithms, so if the // algorithm is not supported, it will return an error when you call // `Sign` on the default signer. @@ -80,6 +97,14 @@ var signerDB = make(map[jwa.SignatureAlgorithm]SignerFactory) // Unlike the `UnregisterSigner` function, this function automatically // calls `jwa.RegisterSignatureAlgorithm` to register the algorithm // in this module's algorithm database. +// +// For backwards compatibility, this function also accepts +// `SignerFactory` implementations, but this usage is deprecated. +// You should use `Signer2` implementations instead. +// +// If you want to completely remove an algorithm, you must call +// `jwa.UnregisterSignatureAlgorithm` yourself after calling +// `UnregisterSigner`. func RegisterSigner(alg jwa.SignatureAlgorithm, f any) error { jwa.RegisterSignatureAlgorithm(alg) switch s := f.(type) { @@ -87,22 +112,10 @@ func RegisterSigner(alg jwa.SignatureAlgorithm, f any) error { muSigner2DB.Lock() signer2DB[alg] = s muSigner2DB.Unlock() - - // delete the other signer, if there was one - muSignerDB.Lock() - delete(signerDB, alg) - muSignerDB.Unlock() case SignerFactory: muSignerDB.Lock() signerDB[alg] = s muSignerDB.Unlock() - - // Remove previous signer, if there was one - removeSigner(alg) - - muSigner2DB.Lock() - delete(signer2DB, alg) - muSigner2DB.Unlock() default: return fmt.Errorf(`jws.RegisterSigner: unsupported type %T for algorithm %q`, f, alg) } @@ -132,11 +145,25 @@ func UnregisterSigner(alg jwa.SignatureAlgorithm) { } // NewSigner creates a signer that signs payloads using the given signature algorithm. -// This function is deprecated. You should use `SignerFor()` instead. +// This function is deprecated, and will either be removed to re-purposed using +// a different signature. // -// This function only exists for backwards compatibility, but will not work -// unless you enable the legacy support mode by calling jws.Settings(jws.WithLegacySigners(true)). +// When you want to load a Signer object, you should use `SignerFor()` instead. func NewSigner(alg jwa.SignatureAlgorithm) (Signer, error) { + s, err := newLegacySigner(alg) + if err == nil { + return s, nil + } + + if strings.HasPrefix(err.Error(), `jws.NewSigner: unsupported signature algorithm`) { + // When newLegacySigner fails, automatically trigger to enable signers + enableLegacySignersOnce.Do(enableLegacySigners) + return newLegacySigner(alg) + } + return nil, err +} + +func newLegacySigner(alg jwa.SignatureAlgorithm) (Signer, error) { muSignerDB.RLock() f, ok := signerDB[alg] muSignerDB.RUnlock() diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/errors/errors.go b/vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/errors/errors.go index a1dca0d5a3bb..179763a50d03 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/errors/errors.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/errors/errors.go @@ -2,6 +2,8 @@ // // It's internal because we don't want to expose _anything_ about these errors // so users absolutely cannot do anything other than use them as opaque errors. +// +//nolint:revive package errors import ( diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwt/jwt.go b/vendor/github.com/lestrrat-go/jwx/v3/jwt/jwt.go index 43e382987aa3..99b5ef37a675 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwt/jwt.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwt/jwt.go @@ -211,7 +211,12 @@ func parseBytes(data []byte, options ...ParseOption) (Token, error) { for _, o := range options { if v, ok := o.(ValidateOption); ok { ctx.validateOpts = append(ctx.validateOpts, v) - continue + // context is used for both verification and validation, so we can't just continue + switch o.Ident() { + case identContext{}: + default: + continue + } } switch o.Ident() { @@ -228,7 +233,7 @@ func parseBytes(data []byte, options ...ParseOption) (Token, error) { } } verifyOpts = append(verifyOpts, o) - case identKeySet{}, identVerifyAuto{}, identKeyProvider{}, identBase64Encoder{}: + case identKeySet{}, identVerifyAuto{}, identKeyProvider{}, identBase64Encoder{}, identContext{}: verifyOpts = append(verifyOpts, o) case identToken{}: var token Token diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwt/options.go b/vendor/github.com/lestrrat-go/jwx/v3/jwt/options.go index cadf163b1511..4a7cfd3e5d24 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwt/options.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwt/options.go @@ -1,7 +1,9 @@ package jwt import ( + "context" "fmt" + "strings" "time" "github.com/lestrrat-go/jwx/v3/jwa" @@ -137,6 +139,14 @@ func toVerifyOptions(options ...Option) ([]jws.VerifyOption, error) { return nil, fmt.Errorf(`failed to decode Base64Encoder: %w`, err) } voptions = append(voptions, jws.WithBase64Encoder(enc)) + case identContext{}: + var ctx context.Context + if err := option.Value(&ctx); err != nil { + return nil, fmt.Errorf(`failed to decode Context: %w`, err) + } + voptions = append(voptions, jws.WithContext(ctx)) + default: + return nil, fmt.Errorf(`invalid jws.VerifyOption %q passed`, `With`+strings.TrimPrefix(fmt.Sprintf(`%T`, option.Ident()), `jws.ident`)) } } return voptions, nil diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options.go b/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options.go index 0f54e056118c..088c4263be36 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options.go @@ -66,7 +66,7 @@ func (o *TokenOptionSet) Enable(flag TokenOption) { *o = TokenOptionSet(o.Value() | uint64(flag)) } -// Enable sets the appropriate value to disable the option in the +// Disable sets the appropriate value to disable the option in the // option set func (o *TokenOptionSet) Disable(flag TokenOption) { *o = TokenOptionSet(o.Value() & ^uint64(flag)) diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options_gen.go b/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options_gen.go index 7e7cbf14aad2..c1f333d13bcc 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options_gen.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options_gen.go @@ -17,9 +17,9 @@ const _TokenOption_name = "FlattenAudienceMaxPerTokenOption" var _TokenOption_index = [...]uint8{0, 15, 32} func (i TokenOption) String() string { - i -= 1 - if i >= TokenOption(len(_TokenOption_index)-1) { - return "TokenOption(" + strconv.FormatInt(int64(i+1), 10) + ")" + idx := int(i) - 1 + if i < 1 || idx >= len(_TokenOption_index)-1 { + return "TokenOption(" + strconv.FormatInt(int64(i), 10) + ")" } - return _TokenOption_name[_TokenOption_index[i]:_TokenOption_index[i+1]] + return _TokenOption_name[_TokenOption_index[idx]:_TokenOption_index[idx+1]] } diff --git a/vendor/github.com/lestrrat-go/jwx/v3/jwt/validate.go b/vendor/github.com/lestrrat-go/jwx/v3/jwt/validate.go index dbc43edbc263..af46868d8b97 100644 --- a/vendor/github.com/lestrrat-go/jwx/v3/jwt/validate.go +++ b/vendor/github.com/lestrrat-go/jwx/v3/jwt/validate.go @@ -3,6 +3,7 @@ package jwt import ( "context" "fmt" + "slices" "strconv" "time" @@ -344,12 +345,10 @@ func (ccs claimContainsString) Validate(_ context.Context, t Token) error { return ccs.makeErr(`claim %q does not exist or is not a []string: %w`, ccs.name, err) } - for _, v := range list { - if v == ccs.value { - return nil - } + if !slices.Contains(list, ccs.value) { + return ccs.makeErr(`%q not satisfied`, ccs.name) } - return ccs.makeErr(`%q not satisfied`, ccs.name) + return nil } // audienceClaimContainsString can be used to check if the audience claim, which is diff --git a/vendor/github.com/lestrrat-go/option/.gitignore b/vendor/github.com/lestrrat-go/option/.gitignore deleted file mode 100644 index 66fd13c903ca..000000000000 --- a/vendor/github.com/lestrrat-go/option/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ diff --git a/vendor/github.com/lestrrat-go/option/LICENSE b/vendor/github.com/lestrrat-go/option/LICENSE deleted file mode 100644 index 188ea7685c64..000000000000 --- a/vendor/github.com/lestrrat-go/option/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 lestrrat-go - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/lestrrat-go/option/README.md b/vendor/github.com/lestrrat-go/option/README.md deleted file mode 100644 index cab0044ed3fa..000000000000 --- a/vendor/github.com/lestrrat-go/option/README.md +++ /dev/null @@ -1,245 +0,0 @@ -# option - -Base object for the "Optional Parameters Pattern". - -# DESCRIPTION - -The beauty of this pattern is that you can achieve a method that can -take the following simple calling style - -```go -obj.Method(mandatory1, mandatory2) -``` - -or the following, if you want to modify its behavior with optional parameters - -```go -obj.Method(mandatory1, mandatory2, optional1, optional2, optional3) -``` - -Instead of the more clunky zero value for optionals style - -```go -obj.Method(mandatory1, mandatory2, nil, "", 0) -``` - -or the equally clunky config object style, which requires you to create a -struct with `NamesThatLookReallyLongBecauseItNeedsToIncludeMethodNamesConfig - -```go -cfg := &ConfigForMethod{ - Optional1: ..., - Optional2: ..., - Optional3: ..., -} -obj.Method(mandatory1, mandatory2, &cfg) -``` - -# SYNOPSIS - -Create an "identifier" for the option. We recommend using an unexported empty struct, -because - -1. It is uniquely identifiable globally -1. Takes minimal space -1. Since it's unexported, you do not have to worry about it leaking elsewhere or having it changed by consumers - -```go -// an unexported empty struct -type identFeatureX struct{} -``` - -Then define a method to create an option using this identifier. Here we assume -that the option will be a boolean option. - -```go -// this is optional, but for readability we usually use a wrapper -// around option.Interface, or a type alias. -type Option -func WithFeatureX(v bool) Option { - // use the constructor to create a new option - return option.New(identFeatureX{}, v) -} -``` - -Now you can create an option, which essentially a two element tuple consisting -of an identifier and its associated value. - -To consume this, you will need to create a function with variadic parameters, -and iterate over the list looking for a particular identifier: - -```go -func MyAwesomeFunc( /* mandatory parameters omitted */, options ...[]Option) { - var enableFeatureX bool - // The nolint directive is recommended if you are using linters such - // as golangci-lint - //nolint:forcetypeassert - for _, option := range options { - switch option.Ident() { - case identFeatureX{}: - enableFeatureX = option.Value().(bool) - // other cases omitted - } - } - if enableFeatureX { - .... - } -} -``` - -# Option objects - -Option objects take two arguments, its identifier and the value it contains. - -The identifier can be anything, but it's usually better to use a an unexported -empty struct so that only you have the ability to generate said option: - -```go -type identOptionalParamOne struct{} -type identOptionalParamTwo struct{} -type identOptionalParamThree struct{} - -func WithOptionOne(v ...) Option { - return option.New(identOptionalParamOne{}, v) -} -``` - -Then you can call the method we described above as - -```go -obj.Method(m1, m2, WithOptionOne(...), WithOptionTwo(...), WithOptionThree(...)) -``` - -Options should be parsed in a code that looks somewhat like this - -```go -func (obj *Object) Method(m1 Type1, m2 Type2, options ...Option) { - paramOne := defaultValueParamOne - for _, option := range options { - switch option.Ident() { - case identOptionalParamOne{}: - paramOne = option.Value().(...) - } - } - ... -} -``` - -The loop requires a bit of boilerplate, and admittedly, this is the main downside -of this module. However, if you think you want use the Option as a Function pattern, -please check the FAQ below for rationale. - -# Simple usage - -Most of the times all you need to do is to declare the Option type as an alias -in your code: - -```go -package myawesomepkg - -import "github.com/lestrrat-go/option" - -type Option = option.Interface -``` - -Then you can start defining options like they are described in the SYNOPSIS section. - -# Differentiating Options - -When you have multiple methods and options, and those options can only be passed to -each one the methods, it's hard to see which options should be passed to which method. - -```go -func WithX() Option { ... } -func WithY() Option { ... } - -// Now, which of WithX/WithY go to which method? -func (*Obj) Method1(options ...Option) {} -func (*Obj) Method2(options ...Option) {} -``` - -In this case the easiest way to make it obvious is to put an extra layer around -the options so that they have different types - -```go -type Method1Option interface { - Option - method1Option() -} - -type method1Option struct { Option } -func (*method1Option) method1Option() {} - -func WithX() Method1Option { - return &methodOption{option.New(...)} -} - -func (*Obj) Method1(options ...Method1Option) {} -``` - -This way the compiler knows if an option can be passed to a given method. - -# FAQ - -## Why aren't these function-based? - -Using a base option type like `type Option func(ctx interface{})` is certainly one way to achieve the same goal. In this case, you are giving the option itself the ability to "configure" the main object. For example: - -```go -type Foo struct { - optionaValue bool -} - -type Option func(*Foo) error - -func WithOptionalValue(v bool) Option { - return Option(func(f *Foo) error { - f.optionalValue = v - return nil - }) -} - -func NewFoo(options ...Option) (*Foo, error) { - var f Foo - for _, o := range options { - if err := o(&f); err != nil { - return nil, err - } - } - return &f -} -``` - -This in itself is fine, but we think there are a few problems: - -### 1. It's hard to create a reusable "Option" type - -We create many libraries using this optional pattern. We would like to provide a default base object. However, this function based approach is not reusuable because each "Option" type requires that it has a context-specific input type. For example, if the "Option" type in the previous example was `func(interface{}) error`, then its usability will significantly decrease because of the type conversion. - -This is not to say that this library's approach is better as it also requires type conversion to convert the _value_ of the option. However, part of the beauty of the original function based approach was the ease of its use, and we claim that this significantly decreases the merits of the function based approach. - -### 2. The receiver requires exported fields - -Part of the appeal for a function-based option pattern is by giving the option itself the ability to do what it wants, you open up the possibility of allowing third-parties to create options that do things that the library authors did not think about. - -```go -package thirdparty -, but when I read drum sheet music, I kind of get thrown off b/c many times it says to hit the bass drum where I feel like it's a snare hit. -func WithMyAwesomeOption( ... ) mypkg.Option { - return mypkg.Option(func(f *mypkg) error { - f.X = ... - f.Y = ... - f.Z = ... - return nil - }) -} -``` - -However, for any third party code to access and set field values, these fields (`X`, `Y`, `Z`) must be exported. Basically you will need an "open" struct. - -Exported fields are absolutely no problem when you have a struct that represents data alone (i.e., API calls that refer or change state information) happen, but we think that casually expose fields for a library struct is a sure way to maintenance hell in the future. What happens when you want to change the API? What happens when you realize that you want to use the field as state (i.e. use it for more than configuration)? What if they kept referring to that field, and then you have concurrent code accessing it? - -Giving third parties complete access to exported fields is like handing out a loaded weapon to the users, and you are at their mercy. - -Of course, providing public APIs for everything so you can validate and control concurrency is an option, but then ... it's a lot of work, and you may have to provide APIs _only_ so that users can refer it in the option-configuration phase. That sounds like a lot of extra work. - diff --git a/vendor/github.com/lestrrat-go/option/option.go b/vendor/github.com/lestrrat-go/option/option.go deleted file mode 100644 index bfdbb118c0d9..000000000000 --- a/vendor/github.com/lestrrat-go/option/option.go +++ /dev/null @@ -1,38 +0,0 @@ -package option - -import "fmt" - -// Interface defines the minimum interface that an option must fulfill -type Interface interface { - // Ident returns the "identity" of this option, a unique identifier that - // can be used to differentiate between options - Ident() interface{} - - // Value returns the corresponding value. - Value() interface{} -} - -type pair struct { - ident interface{} - value interface{} -} - -// New creates a new Option -func New(ident, value interface{}) Interface { - return &pair{ - ident: ident, - value: value, - } -} - -func (p *pair) Ident() interface{} { - return p.ident -} - -func (p *pair) Value() interface{} { - return p.value -} - -func (p *pair) String() string { - return fmt.Sprintf(`%v(%v)`, p.ident, p.value) -} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/capabilities.go b/vendor/github.com/open-policy-agent/opa/capabilities/capabilities.go index ba32cf977e5b..5482720f7cfb 100644 --- a/vendor/github.com/open-policy-agent/opa/capabilities/capabilities.go +++ b/vendor/github.com/open-policy-agent/opa/capabilities/capabilities.go @@ -2,9 +2,6 @@ // 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 ( diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.10.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.11.0.json similarity index 99% rename from vendor/github.com/open-policy-agent/opa/capabilities/v1.10.1.json rename to vendor/github.com/open-policy-agent/opa/capabilities/v1.11.0.json index 0a37621d0c5d..d58fc6760ffe 100644 --- a/vendor/github.com/open-policy-agent/opa/capabilities/v1.10.1.json +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.11.0.json @@ -40,7 +40,8 @@ "type": "boolean" }, "type": "function" - } + }, + "deprecated": true }, { "name": "and", @@ -95,7 +96,8 @@ "type": "boolean" }, "type": "function" - } + }, + "deprecated": true }, { "name": "array.concat", @@ -385,7 +387,8 @@ "type": "array" }, "type": "function" - } + }, + "deprecated": true }, { "name": "cast_boolean", @@ -399,7 +402,8 @@ "type": "boolean" }, "type": "function" - } + }, + "deprecated": true }, { "name": "cast_null", @@ -413,7 +417,8 @@ "type": "null" }, "type": "function" - } + }, + "deprecated": true }, { "name": "cast_object", @@ -435,7 +440,8 @@ "type": "object" }, "type": "function" - } + }, + "deprecated": true }, { "name": "cast_set", @@ -452,7 +458,8 @@ "type": "set" }, "type": "function" - } + }, + "deprecated": true }, { "name": "cast_string", @@ -466,7 +473,8 @@ "type": "string" }, "type": "function" - } + }, + "deprecated": true }, { "name": "ceil", @@ -2975,7 +2983,8 @@ "type": "boolean" }, "type": "function" - } + }, + "deprecated": true }, { "name": "net.lookup_ip_addr", @@ -3493,7 +3502,8 @@ "type": "boolean" }, "type": "function" - } + }, + "deprecated": true }, { "name": "regex.find_all_string_submatch_n", @@ -3808,7 +3818,8 @@ "type": "set" }, "type": "function" - } + }, + "deprecated": true }, { "name": "sort", diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.11.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.11.1.json new file mode 100644 index 000000000000..d58fc6760ffe --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.11.1.json @@ -0,0 +1,4878 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.0.json new file mode 100644 index 000000000000..e4bf21abf3ef --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.0.json @@ -0,0 +1,4896 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.1.json new file mode 100644 index 000000000000..e4bf21abf3ef --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.1.json @@ -0,0 +1,4896 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.2.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.2.json new file mode 100644 index 000000000000..e4bf21abf3ef --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.2.json @@ -0,0 +1,4896 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.3.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.3.json new file mode 100644 index 000000000000..e4bf21abf3ef --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.12.3.json @@ -0,0 +1,4896 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.0.json new file mode 100644 index 000000000000..9eb82c29687f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.0.json @@ -0,0 +1,4916 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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.flatten", + "decl": { + "args": [ + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.1.json new file mode 100644 index 000000000000..9eb82c29687f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.1.json @@ -0,0 +1,4916 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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.flatten", + "decl": { + "args": [ + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.2.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.2.json new file mode 100644 index 000000000000..9eb82c29687f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.13.2.json @@ -0,0 +1,4916 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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.flatten", + "decl": { + "args": [ + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.14.0.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.14.0.json new file mode 100644 index 000000000000..9eb82c29687f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.14.0.json @@ -0,0 +1,4916 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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.flatten", + "decl": { + "args": [ + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/capabilities/v1.14.1.json b/vendor/github.com/open-policy-agent/opa/capabilities/v1.14.1.json new file mode 100644 index 000000000000..9eb82c29687f --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/capabilities/v1.14.1.json @@ -0,0 +1,4916 @@ +{ + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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.flatten", + "decl": { + "args": [ + { + "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" + }, + "deprecated": true + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "deprecated": true + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "deprecated": true + }, + { + "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.template_string", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "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_eddsa", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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" + }, + "deprecated": true + }, + { + "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": [ + "keywords_in_refs", + "rego_v1", + "template_strings" + ] +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv index 473497abbdad..10dc4d482eca 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv +++ b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/callgraph.csv @@ -111,6 +111,9 @@ opa_arith_rem,opa_bf_to_number opa_array_concat,opa_value_type opa_array_concat,opa_array_with_cap opa_array_concat,opa_array_append +opa_array_flatten,opa_value_type +opa_array_flatten,opa_array_with_cap +opa_array_flatten,opa_array_append opa_array_slice,opa_value_type opa_array_slice,opa_number_try_int opa_array_slice,opa_array_with_cap @@ -194,7 +197,9 @@ opa_cidr_contains,parse_ip opa_cidr_contains,opa_boolean parse_cidr,parse_ip parse_cidr,opa_atoi64 +parse_ip,inet_pton4 parse_ip,memchr +inet_pton4,memchr opa_cidr_intersects,opa_value_type opa_cidr_intersects,parse_cidr opa_cidr_intersects,opa_boolean @@ -347,15 +352,15 @@ opa_value_dump,opa_json_writer_write move_freelists,opa_abort opa_heap_blocks_stash,move_freelists opa_heap_blocks_restore,move_freelists -opa_malloc,opa_free_bulk_commit +opa_malloc,merge_sort_blocks +opa_malloc,merge_blocks opa_malloc,opa_abort -opa_free_bulk_commit,merge_sort_blocks +merge_sort_blocks,merge_sort_blocks +merge_sort_blocks,merge_blocks opa_realloc,opa_malloc opa_realloc,memcpy -opa_realloc,opa_free opa_builtin_cache_get,opa_abort opa_builtin_cache_set,opa_abort -merge_sort_blocks,merge_sort_blocks opa_memoize_init,opa_malloc opa_memoize_init,opa_object opa_memoize_push,opa_malloc @@ -583,6 +588,8 @@ opa_sets_union,opa_value_type opa_sets_union,opa_set opa_sets_union,opa_set_add opa_sets_union,opa_value_free_shallow +opa_strlen,strlen +opa_itoa,strlen opa_strings_any_prefix_match,opa_value_type opa_strings_any_prefix_match,opa_value_iter opa_strings_any_prefix_match,opa_value_get @@ -719,6 +726,18 @@ opa_strings_upper,opa_abort opa_strings_upper,opa_unicode_to_upper opa_strings_upper,opa_realloc opa_strings_upper,opa_unicode_encode_utf8 +to_string,opa_value_type +to_string,opa_string_terminated +to_string,opa_value_dump +to_string,opa_strlen +to_string,opa_string_allocated +opa_template_string,opa_value_type +opa_template_string,opa_array_with_cap +opa_template_string,to_string +opa_template_string,opa_array_append +opa_template_string,opa_malloc +opa_template_string,memcpy +opa_template_string,opa_string_allocated opa_types_is_number,opa_value_type opa_types_is_number,opa_boolean opa_types_is_string,opa_value_type @@ -789,8 +808,8 @@ opa_object_keys,opa_value_compare opa_object_keys,opa_value_compare_number opa_object_keys,opa_strncmp opa_object_keys,opa_value_compare_object -opa_object_keys,opa_abort opa_object_keys,opa_value_compare_set +opa_object_keys,opa_abort opa_array_free,__opa_value_free opa_array_free,opa_free opa_array_free,opa_free_bulk @@ -836,17 +855,16 @@ opa_number_ref,opa_malloc opa_number_int,opa_malloc opa_string,opa_malloc opa_value_shallow_copy_object,opa_malloc +opa_value_shallow_copy_object,memset opa_value_shallow_copy_object,opa_value_iter opa_value_shallow_copy_object,opa_value_get opa_value_shallow_copy_object,__opa_object_insert -opa_value_shallow_copy_set,opa_malloc -opa_value_shallow_copy_set,opa_value_iter -opa_value_shallow_copy_set,opa_set_add opa_set_add,opa_value_hash opa_set_add,opa_value_compare opa_set_add,__opa_set_grow opa_set_add,opa_malloc __opa_set_grow,opa_malloc +__opa_set_grow,memset __opa_set_grow,opa_value_hash __opa_set_grow,opa_value_compare_number __opa_set_grow,opa_strncmp @@ -857,7 +875,9 @@ __opa_set_grow,opa_abort __opa_set_grow,opa_free opa_value_shallow_copy,opa_malloc opa_value_shallow_copy,opa_value_shallow_copy_object -opa_value_shallow_copy,opa_value_shallow_copy_set +opa_value_shallow_copy,memset +opa_value_shallow_copy,opa_set_add +opa_value_shallow_copy,opa_value_iter opa_value_shallow_copy,opa_abort opa_value_transitive_closure,opa_malloc opa_value_transitive_closure,__opa_value_transitive_closure @@ -881,7 +901,9 @@ opa_array_with_cap,opa_free opa_object,opa_malloc opa_set,opa_malloc opa_set_with_cap,opa_malloc +opa_set_with_cap,memset __opa_object_grow,opa_malloc +__opa_object_grow,memset __opa_object_grow,opa_value_hash __opa_object_grow,opa_value_compare_number __opa_object_grow,opa_strncmp @@ -908,170 +930,191 @@ opa_lookup,opa_abort opa_lookup,opa_atoi64 opa_mapping_init,opa_json_parse opa_mapping_lookup,opa_lookup -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29 -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29 -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,operator\20delete\28void*\29 -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\29 -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,escape\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,operator\20new\28unsigned\20long\29 -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,memcpy -node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,abort -escape\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::push_back\28char\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,operator\20new\28unsigned\20long\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,lexer::lexer\28char\20const*\2c\20unsigned\20long\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,glob_parse\28lexer*\2c\20node**\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,lexer::~lexer\28\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,operator\20delete\28void*\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,opa_unicode_decode_utf8 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,escape\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,node::re2\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,node::~node\28\29 -lexer::~lexer\28\29,operator\20delete\28void*\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::assign\28char\20const*\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::push_back\28char\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,operator\20new\28unsigned\20long\29 +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,memmove +node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,operator\20new\28unsigned\20long\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,lexer::lexer\28char\20const*\2c\20unsigned\20long\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,glob_parse\28lexer*\2c\20node**\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,lexer::~lexer\28\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::assign\28char\20const*\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,opa_unicode_decode_utf8 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::push_back\28char\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,node::re2\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29 +glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,node::~node\28\29 +std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29,std::_LIBCPP_ABI_NAMESPACE::__libcpp_verbose_abort\28char\20const*\2c\20...\29 +lexer::~lexer\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 lexer::next\28token*\29,strlen lexer::next\28token*\29,operator\20new\28unsigned\20long\29 -lexer::next\28token*\29,memcpy -lexer::next\28token*\29,operator\20delete\28void*\29 -lexer::next\28token*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -lexer::next\28token*\29,abort +lexer::next\28token*\29,memmove +lexer::next\28token*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +lexer::next\28token*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::operator=\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29 +lexer::next\28token*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 lexer::next\28token*\29,lexer::fetch_item\28\29 lexer::fetch_item\28\29,opa_unicode_decode_utf8 lexer::fetch_item\28\29,operator\20new\28unsigned\20long\29 -lexer::fetch_item\28\29,memcpy -lexer::fetch_item\28\29,operator\20delete\28void*\29 +lexer::fetch_item\28\29,memmove +lexer::fetch_item\28\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29 lexer::fetch_item\28\29,lexer::fetch_range\28\29 lexer::fetch_item\28\29,lexer::fetch_text\28int\20const*\29 -lexer::fetch_item\28\29,abort +lexer::fetch_item\28\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 lexer::fetch_range\28\29,opa_unicode_decode_utf8 lexer::fetch_range\28\29,operator\20new\28unsigned\20long\29 -lexer::fetch_range\28\29,memcpy -lexer::fetch_range\28\29,operator\20delete\28void*\29 +lexer::fetch_range\28\29,memmove +lexer::fetch_range\28\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29 lexer::fetch_range\28\29,lexer::fetch_text\28int\20const*\29 -lexer::fetch_range\28\29,abort +lexer::fetch_range\28\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 lexer::fetch_text\28int\20const*\29,opa_unicode_decode_utf8 lexer::fetch_text\28int\20const*\29,operator\20new\28unsigned\20long\29 lexer::fetch_text\28int\20const*\29,memcpy -lexer::fetch_text\28int\20const*\29,operator\20delete\28void*\29 +lexer::fetch_text\28int\20const*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +lexer::fetch_text\28int\20const*\29,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__throw_length_error\5babi:nn210108\5d\28\29 +lexer::fetch_text\28int\20const*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 lexer::fetch_text\28int\20const*\29,opa_malloc +lexer::fetch_text\28int\20const*\29,memmove +lexer::fetch_text\28int\20const*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28token*&&\29 lexer::fetch_text\28int\20const*\29,opa_free -lexer::fetch_text\28int\20const*\29,abort +lexer::fetch_text\28int\20const*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 +std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__libcpp_verbose_abort\28char\20const*\2c\20...\29 +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 node::~node\28\29,node::~node\28\29 -node::~node\28\29,operator\20delete\28void*\29 -node::insert\28node*\29,operator\20new\28unsigned\20long\29 -node::insert\28node*\29,memcpy -node::insert\28node*\29,operator\20delete\28void*\29 -node::insert\28node*\29,abort +node::~node\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28node*\20const&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28node*\20const&\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28node*\20const&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28node*\20const&\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28node*\20const&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 glob_parse\28lexer*\2c\20node**\29,operator\20new\28unsigned\20long\29 -glob_parse\28lexer*\2c\20node**\29,std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const +glob_parse\28lexer*\2c\20node**\29,operator\20delete\28void*\2c\20unsigned\20long\29 glob_parse\28lexer*\2c\20node**\29,node::~node\28\29 -glob_parse\28lexer*\2c\20node**\29,operator\20delete\28void*\29 -glob_parse\28lexer*\2c\20node**\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 +glob_parse\28lexer*\2c\20node**\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29 parser_main\28state*\2c\20lexer*\29,lexer::next\28token*\29 -parser_main\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 +parser_main\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::operator=\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29 parser_main\28state*\2c\20lexer*\29,operator\20new\28unsigned\20long\29 -parser_main\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -parser_main\28state*\2c\20lexer*\29,node::insert\28node*\29 -parser_main\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29 -parser_main\28state*\2c\20lexer*\29,operator\20delete\28void*\29 +parser_main\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29 +parser_main\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28node*\20const&\29 +parser_main\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::assign\28char\20const*\29 +parser_main\28state*\2c\20lexer*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29,memmove +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 parser_range\28state*\2c\20lexer*\29,lexer::next\28token*\29 -parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29 -parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 +parser_range\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::assign\28char\20const*\29 +parser_range\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::operator=\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29 parser_range\28state*\2c\20lexer*\29,opa_unicode_decode_utf8 parser_range\28state*\2c\20lexer*\29,memcmp -parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const parser_range\28state*\2c\20lexer*\29,operator\20new\28unsigned\20long\29 -parser_range\28state*\2c\20lexer*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -parser_range\28state*\2c\20lexer*\29,node::insert\28node*\29 -parser_range\28state*\2c\20lexer*\29,operator\20delete\28void*\29 +parser_range\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29 +parser_range\28state*\2c\20lexer*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28node*\20const&\29 +parser_range\28state*\2c\20lexer*\29,operator\20delete\28void*\2c\20unsigned\20long\29 opa_glob_match,opa_value_type opa_glob_match,opa_value_iter opa_glob_match,opa_value_get opa_glob_match,operator\20new\28unsigned\20long\29 -opa_glob_match,memcpy -opa_glob_match,operator\20delete\28void*\29 -opa_glob_match,void\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>::__push_back_slow_path\2c\20std::__1::allocator\20>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>&&\29 +opa_glob_match,memmove +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::push_back\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&&\29 +opa_glob_match,operator\20delete\28void*\2c\20unsigned\20long\29 opa_glob_match,opa_builtin_cache_get opa_glob_match,opa_builtin_cache_set -opa_glob_match,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -opa_glob_match,std::__1::__hash_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::find\28cache_key\20const&\29 -opa_glob_match,std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -opa_glob_match,glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20const&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29 -opa_glob_match,std::__1::unordered_map\2c\20std::__1::allocator\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::erase\28std::__1::__hash_map_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\20>\29 -opa_glob_match,std::__1::pair\2c\20std::__1::allocator\20>\20>::pair\2c\20std::__1::allocator\20>&\2c\20false>\28cache_key&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>&\29 -opa_glob_match,std::__1::pair\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\20>\20>\28cache_key\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\20>&&\29 +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29 +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::find\28cache_key\20const&\29 +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::operator=\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29 +opa_glob_match,glob_translate\28char\20const*\2c\20unsigned\20long\2c\20std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29 +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::unordered_map\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::erase\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::__hash_map_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>>\29 +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::pair\5babi:nn210108\5d\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\2c\200>\28cache_key&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\29 +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\28cache_key\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>&&\29 opa_glob_match,opa_string opa_glob_match,opa_regex_match -opa_glob_match,abort -void\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>::__push_back_slow_path\2c\20std::__1::allocator\20>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>&&\29,operator\20new\28unsigned\20long\29 -void\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>::__push_back_slow_path\2c\20std::__1::allocator\20>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>&&\29,operator\20delete\28void*\29 -void\20std::__1::vector\2c\20std::__1::allocator\20>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>::__push_back_slow_path\2c\20std::__1::allocator\20>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>&&\29,abort -std::__1::__hash_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::find\28cache_key\20const&\29,std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>::operator\28\29\28cache_key\20const&\29\20const -std::__1::__hash_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::find\28cache_key\20const&\29,std::__1::equal_to::operator\28\29\28cache_key\20const&\2c\20cache_key\20const&\29\20const -std::__1::unordered_map\2c\20std::__1::allocator\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::erase\28std::__1::__hash_map_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\20>\29,std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::remove\28std::__1::__hash_const_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\29 -std::__1::unordered_map\2c\20std::__1::allocator\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::erase\28std::__1::__hash_map_iterator\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\20>\29,std::__1::unique_ptr\2c\20std::__1::allocator\20>\20>\2c\20void*>\2c\20std::__1::__hash_node_destructor\2c\20std::__1::allocator\20>\20>\2c\20void*>\20>\20>\20>::~unique_ptr\28\29 -std::__1::pair\2c\20std::__1::allocator\20>\20>::pair\2c\20std::__1::allocator\20>&\2c\20false>\28cache_key&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -std::__1::pair\2c\20std::__1::allocator\20>\20>::pair\2c\20std::__1::allocator\20>&\2c\20false>\28cache_key&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>&\29,operator\20new\28unsigned\20long\29 -std::__1::pair\2c\20std::__1::allocator\20>\20>::pair\2c\20std::__1::allocator\20>&\2c\20false>\28cache_key&\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>&\29,abort -std::__1::pair\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\20>\20>\28cache_key\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\20>&&\29,std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>::operator\28\29\28cache_key\20const&\29\20const -std::__1::pair\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\20>\20>\28cache_key\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\20>&&\29,std::__1::equal_to::operator\28\29\28cache_key\20const&\2c\20cache_key\20const&\29\20const -std::__1::pair\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\20>\20>\28cache_key\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\20>&&\29,operator\20new\28unsigned\20long\29 -std::__1::pair\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\20>\20>\28cache_key\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\20>&&\29,std::__1::__next_prime\28unsigned\20long\29 -std::__1::pair\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\20>\20>\28cache_key\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\20>&&\29,std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__rehash\28unsigned\20long\29 -std::__1::pair\2c\20std::__1::allocator\20>\20>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\20>\20>\28cache_key\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\20>&&\29,std::__1::unique_ptr\2c\20std::__1::allocator\20>\20>\2c\20void*>\2c\20std::__1::__hash_node_destructor\2c\20std::__1::allocator\20>\20>\2c\20void*>\20>\20>\20>::~unique_ptr\28\29 -std::__1::unique_ptr\2c\20std::__1::allocator\20>\20>\2c\20void*>\2c\20std::__1::__hash_node_destructor\2c\20std::__1::allocator\20>\20>\2c\20void*>\20>\20>\20>::~unique_ptr\28\29,operator\20delete\28void*\29 -std::__1::equal_to::operator\28\29\28cache_key\20const&\2c\20cache_key\20const&\29\20const,memcmp -std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 -std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__rehash\28unsigned\20long\29,operator\20delete\28void*\29 -std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__rehash\28unsigned\20long\29,memcmp -std::__1::__hash_table\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::__rehash\28unsigned\20long\29,abort +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +opa_glob_match,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::push_back\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::push_back\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&&\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::push_back\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::push_back\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&&\29,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::push_back\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::find\28cache_key\20const&\29,std::_LIBCPP_ABI_NAMESPACE::__hash_memory\28void\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::find\28cache_key\20const&\29,cache_key::operator==\28cache_key\20const&\29\20const +std::_LIBCPP_ABI_NAMESPACE::unordered_map\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::erase\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::__hash_map_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>>\29,std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::remove\28std::_LIBCPP_ABI_NAMESPACE::__hash_const_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\29 +std::_LIBCPP_ABI_NAMESPACE::unordered_map\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::erase\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::__hash_map_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>>\29,void\20std::_LIBCPP_ABI_NAMESPACE::__destroy_at\5babi:nn210108\5d\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\200>\28std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>*\29 +std::_LIBCPP_ABI_NAMESPACE::unordered_map\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::erase\5babi:nn210108\5d\28std::_LIBCPP_ABI_NAMESPACE::__hash_map_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>>\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::pair\5babi:nn210108\5d\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\2c\200>\28cache_key&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::pair\5babi:nn210108\5d\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\2c\200>\28cache_key&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::pair\5babi:nn210108\5d\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\2c\200>\28cache_key&\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\29,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\28cache_key\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>&&\29,std::_LIBCPP_ABI_NAMESPACE::__hash_memory\28void\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\28cache_key\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>&&\29,cache_key::operator==\28cache_key\20const&\29\20const +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\28cache_key\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>&&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\28cache_key\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>&&\29,std::_LIBCPP_ABI_NAMESPACE::__next_prime\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>\28cache_key\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>&&\29,void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__do_rehash\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__destroy_at\5babi:nn210108\5d\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\200>\28std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +cache_key::operator==\28cache_key\20const&\29\20const,memcmp +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__do_rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__do_rehash\28unsigned\20long\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__do_rehash\28unsigned\20long\29,memset +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::__do_rehash\28unsigned\20long\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 opa_regex_is_valid,opa_value_type opa_regex_is_valid,opa_boolean opa_regex_is_valid,operator\20new\28unsigned\20long\29 -opa_regex_is_valid,memcpy +opa_regex_is_valid,memmove opa_regex_is_valid,re2::RE2::RE2\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29 opa_regex_is_valid,re2::RE2::~RE2\28\29 -opa_regex_is_valid,operator\20delete\28void*\29 -opa_regex_is_valid,abort +opa_regex_is_valid,operator\20delete\28void*\2c\20unsigned\20long\29 +opa_regex_is_valid,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 opa_regex_match,opa_value_type opa_regex_match,operator\20new\28unsigned\20long\29 -opa_regex_match,memcpy +opa_regex_match,memmove opa_regex_match,compile\28char\20const*\29 opa_regex_match,re2::RE2::PartialMatchN\28re2::StringPiece\20const&\2c\20re2::RE2\20const&\2c\20re2::RE2::Arg\20const*\20const*\2c\20int\29 opa_regex_match,reuse\28re2::RE2*\29 opa_regex_match,opa_boolean -opa_regex_match,operator\20delete\28void*\29 -opa_regex_match,abort +opa_regex_match,operator\20delete\28void*\2c\20unsigned\20long\29 +opa_regex_match,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 compile\28char\20const*\29,opa_builtin_cache_get compile\28char\20const*\29,operator\20new\28unsigned\20long\29 compile\28char\20const*\29,opa_builtin_cache_set compile\28char\20const*\29,strlen compile\28char\20const*\29,memcpy -compile\28char\20const*\29,std::__1::__hash_iterator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::find\2c\20std::__1::allocator\20>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -compile\28char\20const*\29,operator\20delete\28void*\29 +compile\28char\20const*\29,std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::find\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29 +compile\28char\20const*\29,operator\20delete\28void*\2c\20unsigned\20long\29 compile\28char\20const*\29,re2::RE2::RE2\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29 compile\28char\20const*\29,re2::RE2::~RE2\28\29 -compile\28char\20const*\29,abort +compile\28char\20const*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 reuse\28re2::RE2*\29,opa_builtin_cache_get reuse\28re2::RE2*\29,operator\20new\28unsigned\20long\29 reuse\28re2::RE2*\29,opa_builtin_cache_set reuse\28re2::RE2*\29,re2::RE2::~RE2\28\29 -reuse\28re2::RE2*\29,operator\20delete\28void*\29 -reuse\28re2::RE2*\29,std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::remove\28std::__1::__hash_const_iterator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\29 -reuse\28re2::RE2*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29 -reuse\28re2::RE2*\29,std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>&&\29 -std::__1::__hash_iterator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::find\2c\20std::__1::allocator\20>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,memcmp -std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>&&\29,memcmp -std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>&&\29,operator\20new\28unsigned\20long\29 -std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>&&\29,std::__1::__next_prime\28unsigned\20long\29 -std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__emplace_unique_key_args\2c\20std::__1::allocator\20>\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\2c\20std::__1::pair\2c\20std::__1::allocator\20>\2c\20re2::RE2*>&&\29,std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__rehash\28unsigned\20long\29 +reuse\28re2::RE2*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +reuse\28re2::RE2*\29,std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::remove\28std::_LIBCPP_ABI_NAMESPACE::__hash_const_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\29 +reuse\28re2::RE2*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__init_copy_ctor_external\28char\20const*\2c\20unsigned\20long\29 +reuse\28re2::RE2*\29,std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>&&\29 +std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::find\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::__hash_memory\28void\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::find\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,memcmp +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>&&\29,std::_LIBCPP_ABI_NAMESPACE::__hash_memory\28void\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>&&\29,memcmp +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>&&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>&&\29,std::_LIBCPP_ABI_NAMESPACE::__next_prime\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>>\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>&&\29,void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__do_rehash\28unsigned\20long\29 opa_regex_find_all_string_submatch,opa_value_type opa_regex_find_all_string_submatch,opa_number_try_int opa_regex_find_all_string_submatch,operator\20new\28unsigned\20long\29 -opa_regex_find_all_string_submatch,memcpy +opa_regex_find_all_string_submatch,memmove opa_regex_find_all_string_submatch,compile\28char\20const*\29 opa_regex_find_all_string_submatch,opa_array opa_regex_find_all_string_submatch,memset @@ -1079,16 +1122,19 @@ opa_regex_find_all_string_submatch,re2::RE2::Match\28re2::StringPiece\20const&\2 opa_regex_find_all_string_submatch,fullrune opa_regex_find_all_string_submatch,chartorune opa_regex_find_all_string_submatch,opa_array_with_cap +opa_regex_find_all_string_submatch,reuse\28re2::RE2*\29 opa_regex_find_all_string_submatch,opa_malloc +opa_regex_find_all_string_submatch,memcpy opa_regex_find_all_string_submatch,opa_string_allocated opa_regex_find_all_string_submatch,opa_array_append -opa_regex_find_all_string_submatch,reuse\28re2::RE2*\29 -opa_regex_find_all_string_submatch,operator\20delete\28void*\29 -opa_regex_find_all_string_submatch,abort -std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 -std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__rehash\28unsigned\20long\29,operator\20delete\28void*\29 -std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__rehash\28unsigned\20long\29,memcmp -std::__1::__hash_table\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::allocator\20>\2c\20std::__1::__hash_value_type\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\2c\20std::__1::equal_to\2c\20std::__1::allocator\20>\20>\2c\20std::__1::hash\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20re2::RE2*>\20>\20>::__rehash\28unsigned\20long\29,abort +opa_regex_find_all_string_submatch,operator\20delete\28void*\2c\20unsigned\20long\29 +opa_regex_find_all_string_submatch,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +opa_regex_find_all_string_submatch,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__do_rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__do_rehash\28unsigned\20long\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__do_rehash\28unsigned\20long\29,memset +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20re2::RE2*>>>::__do_rehash\28unsigned\20long\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 snprintf_,_vsnprintf _vsnprintf,_ntoa_format _vsnprintf,_ftoa @@ -1311,14 +1357,14 @@ mpd_qplus,opa_abort mpd_qplus,mpd_qfinalize mpd_qadd,mpd_qcopy mpd_qadd,_mpd_fix_nan -mpd_qadd,opa_abort -mpd_qadd,mpd_realloc +mpd_qadd,_mpd_qaddsub_inf mpd_qadd,_mpd_qaddsub mpd_qadd,mpd_qfinalize +_mpd_qaddsub_inf,opa_abort +_mpd_qaddsub_inf,mpd_realloc mpd_qsub,mpd_qcopy mpd_qsub,_mpd_fix_nan -mpd_qsub,opa_abort -mpd_qsub,mpd_realloc +mpd_qsub,_mpd_qaddsub_inf mpd_qsub,_mpd_qaddsub mpd_qsub,mpd_qfinalize mpd_qdiv,_mpd_qdiv @@ -1349,15 +1395,15 @@ _mpd_base_ndivmod,_mpd_qmul_exact _mpd_base_ndivmod,mpd_qshiftr _mpd_base_ndivmod,_mpd_qmul _mpd_base_ndivmod,mpd_qfinalize -_mpd_base_ndivmod,mpd_qsub -_mpd_base_ndivmod,mpd_realloc +_mpd_base_ndivmod,_mpd_qsub_exact _mpd_base_ndivmod,_mpd_qround_to_integral +_mpd_base_ndivmod,_mpd_cmp +_mpd_base_ndivmod,_mpd_qadd_exact _mpd_base_ndivmod,fprintf _mpd_base_ndivmod,fwrite _mpd_base_ndivmod,fputc -_mpd_base_ndivmod,_mpd_cmp -_mpd_base_ndivmod,mpd_qadd _mpd_base_ndivmod,mpd_qcopy +_mpd_base_ndivmod,mpd_realloc _mpd_qdivmod,opa_abort _mpd_qdivmod,mpd_qcopy _mpd_qdivmod,_settriple @@ -1373,43 +1419,37 @@ _mpd_qmul,mpd_qcopy _mpd_qmul,_mpd_fix_nan _mpd_qmul,opa_abort _mpd_qmul,mpd_realloc -_mpd_qmul,_mpd_mul_2_le2 _mpd_qmul,memset _mpd_qmul,_mpd_shortmul _mpd_qmul,_mpd_basemul -_mpd_qmul,mpd_switch_to_dyn -_mpd_qmul,mpd_realloc_dyn _mpd_qmul,mpd_calloc _mpd_qmul,_mpd_kmul _mpd_qmul,_mpd_fntmul _mpd_qmul,_mpd_kmul_fnt _mpd_qmul,mpd_seterror +_mpd_qmul,_mpd_mul_2_le2 +_mpd_qmul,mpd_switch_to_dyn +_mpd_qmul,mpd_realloc_dyn _mpd_kmul,opa_abort +_mpd_kmul,_kmul_resultsize _mpd_kmul,mpd_calloc _mpd_kmul,_kmul_worksize _mpd_kmul,_karatsuba_rec -_mpd_kmul,fprintf -_mpd_kmul,fwrite -_mpd_kmul,fputc -_mpd_kmul,abort _mpd_fntmul,opa_abort -_mpd_fntmul,fprintf -_mpd_fntmul,fwrite -_mpd_fntmul,fputc -_mpd_fntmul,abort _mpd_fntmul,mpd_calloc _mpd_fntmul,memcpy _mpd_fntmul,fnt_autoconvolute _mpd_fntmul,fnt_convolute _mpd_fntmul,memset _mpd_fntmul,crt3 +_mpd_fntmul,fprintf +_mpd_fntmul,fwrite +_mpd_fntmul,fputc +_mpd_fntmul,abort _mpd_kmul_fnt,opa_abort +_mpd_kmul_fnt,_kmul_resultsize _mpd_kmul_fnt,mpd_calloc _mpd_kmul_fnt,_kmul_worksize -_mpd_kmul_fnt,fprintf -_mpd_kmul_fnt,fwrite -_mpd_kmul_fnt,fputc -_mpd_kmul_fnt,abort _mpd_kmul_fnt,_karatsuba_rec_fnt mpd_qmul,_mpd_qmul mpd_qmul,mpd_qfinalize @@ -1435,6 +1475,9 @@ mpd_qround_to_intx,_mpd_qround_to_integral mpd_qtrunc,_mpd_qround_to_integral mpd_qfloor,_mpd_qround_to_integral mpd_qceil,_mpd_qround_to_integral +_mpd_qadd_exact,mpd_qadd +_mpd_qadd_exact,opa_abort +_mpd_qadd_exact,mpd_realloc mpd_sizeinbase,opa_abort mpd_sizeinbase,log10 mpd_qexport_u16,opa_abort @@ -1454,6 +1497,13 @@ mpd_qimport_u16,_mpd_shortmul_c mpd_qimport_u16,_mpd_shortadd mpd_qimport_u16,mpd_qfinalize _mpd_basecmp,opa_abort +_mpd_qsub_exact,mpd_qsub +_mpd_qsub_exact,opa_abort +_mpd_qsub_exact,mpd_realloc +_kmul_resultsize,fprintf +_kmul_resultsize,fwrite +_kmul_resultsize,fputc +_kmul_resultsize,abort _kmul_worksize,_kmul_worksize _kmul_worksize,fprintf _kmul_worksize,fwrite @@ -1502,78 +1552,79 @@ swap_halfrows_pow2,fprintf swap_halfrows_pow2,fwrite swap_halfrows_pow2,fputc swap_halfrows_pow2,abort -std::__1::__next_prime\28unsigned\20long\29,abort +std::_LIBCPP_ABI_NAMESPACE::__next_prime\28unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::__throw_overflow_error\5babi:nn210108\5d\28char\20const*\29 +std::_LIBCPP_ABI_NAMESPACE::__throw_overflow_error\5babi:nn210108\5d\28char\20const*\29,std::_LIBCPP_ABI_NAMESPACE::__libcpp_verbose_abort\28char\20const*\2c\20...\29 operator\20new\28unsigned\20long\29,opa_malloc -operator\20delete\28void*\29,opa_free +operator\20delete\28void*\2c\20unsigned\20long\29,opa_free operator\20new\5b\5d\28unsigned\20long\29,opa_malloc operator\20delete\5b\5d\28void*\29,opa_free __cxa_pure_virtual,opa_abort -std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,opa_malloc -std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,memcpy -std::__1::basic_string\2c\20std::__1::allocator\20>::basic_string\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,abort -std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,memcpy -std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,opa_malloc -std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,opa_free -std::__1::basic_string\2c\20std::__1::allocator\20>::operator=\28std::__1::basic_string\2c\20std::__1::allocator\20>\20const&\29,abort -std::__1::basic_string\2c\20std::__1::allocator\20>::resize\28unsigned\20long\2c\20char\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28unsigned\20long\2c\20char\29 -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28unsigned\20long\2c\20char\29,opa_malloc -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28unsigned\20long\2c\20char\29,memcpy -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28unsigned\20long\2c\20char\29,opa_free -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28unsigned\20long\2c\20char\29,memset -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28unsigned\20long\2c\20char\29,abort -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29,memcpy -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29,opa_malloc -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29,opa_free -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29,abort -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\29,strlen -std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29 -std::__1::basic_string\2c\20std::__1::allocator\20>::push_back\28char\29,opa_malloc -std::__1::basic_string\2c\20std::__1::allocator\20>::push_back\28char\29,memcpy -std::__1::basic_string\2c\20std::__1::allocator\20>::push_back\28char\29,opa_free -std::__1::basic_string\2c\20std::__1::allocator\20>::push_back\28char\29,abort -std::__1::basic_string\2c\20std::__1::allocator\20>::__assign_external\28char\20const*\2c\20unsigned\20long\29,memmove -std::__1::basic_string\2c\20std::__1::allocator\20>::__assign_external\28char\20const*\2c\20unsigned\20long\29,opa_malloc -std::__1::basic_string\2c\20std::__1::allocator\20>::__assign_external\28char\20const*\2c\20unsigned\20long\29,memcpy -std::__1::basic_string\2c\20std::__1::allocator\20>::__assign_external\28char\20const*\2c\20unsigned\20long\29,opa_free -std::__1::basic_string\2c\20std::__1::allocator\20>::__assign_external\28char\20const*\2c\20unsigned\20long\29,abort -std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\2c\20unsigned\20long\29,std::__1::basic_string\2c\20std::__1::allocator\20>::__assign_external\28char\20const*\2c\20unsigned\20long\29 -std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29,strlen -std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::__assign_external\28char\20const*\2c\20unsigned\20long\29 -std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const,memcmp -std::__1::basic_string\2c\20std::__1::allocator\20>::compare\28unsigned\20long\2c\20unsigned\20long\2c\20char\20const*\2c\20unsigned\20long\29\20const,abort -void\20std::__1::__sort&\2c\20int*>\28int*\2c\20int*\2c\20std::__1::__less&\29,unsigned\20int\20std::__1::__sort5&\2c\20int*>\28int*\2c\20int*\2c\20int*\2c\20int*\2c\20int*\2c\20std::__1::__less&\29 -void\20std::__1::__sort&\2c\20int*>\28int*\2c\20int*\2c\20std::__1::__less&\29,bool\20std::__1::__insertion_sort_incomplete&\2c\20int*>\28int*\2c\20int*\2c\20std::__1::__less&\29 -void\20std::__1::__sort&\2c\20int*>\28int*\2c\20int*\2c\20std::__1::__less&\29,void\20std::__1::__sort&\2c\20int*>\28int*\2c\20int*\2c\20std::__1::__less&\29 -bool\20std::__1::__insertion_sort_incomplete&\2c\20int*>\28int*\2c\20int*\2c\20std::__1::__less&\29,unsigned\20int\20std::__1::__sort5&\2c\20int*>\28int*\2c\20int*\2c\20int*\2c\20int*\2c\20int*\2c\20std::__1::__less&\29 +std::_LIBCPP_ABI_NAMESPACE::__libcpp_verbose_abort\28char\20const*\2c\20...\29,opa_abort +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::operator=\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::operator=\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,memmove +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,opa_malloc +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,opa_free +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,memmove +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,opa_malloc +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>&\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_no_alias\28char\20const*\2c\20unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::resize\28unsigned\20long\2c\20char\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28unsigned\20long\2c\20char\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28unsigned\20long\2c\20char\29,opa_malloc +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28unsigned\20long\2c\20char\29,memmove +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28unsigned\20long\2c\20char\29,opa_free +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28unsigned\20long\2c\20char\29,memset +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28unsigned\20long\2c\20char\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29,memmove +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29,opa_malloc +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29,opa_free +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\29,strlen +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::push_back\28char\29,opa_malloc +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::push_back\28char\29,memmove +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::push_back\28char\29,opa_free +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\2c\20unsigned\20long\29,memmove +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\2c\20unsigned\20long\29,opa_malloc +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\2c\20unsigned\20long\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\2c\20unsigned\20long\29,opa_free +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\2c\20unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::assign\28char\20const*\2c\20unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::assign\28char\20const*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\29 +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\29,strlen +std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__assign_external\28char\20const*\2c\20unsigned\20long\29 re2::BitState::Push\28int\2c\20char\20const*\29,operator\20new\28unsigned\20long\29 re2::BitState::Push\28int\2c\20char\20const*\29,memmove -re2::BitState::Push\28int\2c\20char\20const*\29,operator\20delete\28void*\29 -re2::BitState::Push\28int\2c\20char\20const*\29,abort +re2::BitState::Push\28int\2c\20char\20const*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::BitState::Push\28int\2c\20char\20const*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::BitState::TrySearch\28int\2c\20char\20const*\29,re2::BitState::Push\28int\2c\20char\20const*\29 re2::BitState::TrySearch\28int\2c\20char\20const*\29,opa_abort re2::BitState::TrySearch\28int\2c\20char\20const*\29,re2::Prog::EmptyFlags\28re2::StringPiece\20const&\2c\20char\20const*\29 re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,operator\20new\28unsigned\20long\29 -re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,operator\20delete\28void*\29 +re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,memset re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,re2::BitState::TrySearch\28int\2c\20char\20const*\29 re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,memchr re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,re2::Prog::PrefixAccel_FrontAndBack\28void\20const*\2c\20unsigned\20long\29 -re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,abort +re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::Prog::SearchBitState\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,re2::BitState::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29 -re2::Prog::SearchBitState\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,operator\20delete\28void*\29 +re2::Prog::SearchBitState\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Compiler::AllocInst\28int\29,operator\20new\28unsigned\20long\29 re2::Compiler::AllocInst\28int\29,memset re2::Compiler::AllocInst\28int\29,memmove -re2::Compiler::AllocInst\28int\29,operator\20delete\28void*\29 -re2::Compiler::AllocInst\28int\29,abort +re2::Compiler::AllocInst\28int\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Compiler::AllocInst\28int\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::Compiler::~Compiler\28\29,re2::Prog::~Prog\28\29 -re2::Compiler::~Compiler\28\29,operator\20delete\28void*\29 +re2::Compiler::~Compiler\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Compiler::~Compiler\28\29,re2::Regexp::Walker::~Walker\28\29 re2::Regexp::Walker::~Walker\28\29,operator\20delete\5b\5d\28void*\29 -re2::Regexp::Walker::~Walker\28\29,operator\20delete\28void*\29 -re2::Regexp::Walker::~Walker\28\29,std::__1::__deque_base\2c\20std::__1::allocator\20>\20>::~__deque_base\28\29 -re2::Compiler::~Compiler\28\29.1,re2::Compiler::~Compiler\28\29 -re2::Compiler::~Compiler\28\29.1,operator\20delete\28void*\29 +re2::Regexp::Walker::~Walker\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Regexp::Walker::~Walker\28\29,std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::~deque\5babi:nn210108\5d\28\29 +re2::Compiler::~Compiler\28\29_479,re2::Compiler::~Compiler\28\29 +re2::Compiler::~Compiler\28\29_479,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Compiler::Cat\28re2::Frag\2c\20re2::Frag\29,opa_abort re2::Compiler::Star\28re2::Frag\2c\20bool\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::Star\28re2::Frag\2c\20bool\29,re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29 @@ -1583,45 +1634,40 @@ re2::Compiler::Quest\28re2::Frag\2c\20bool\29,re2::Prog::Inst::InitNop\28unsigne re2::Compiler::Quest\28re2::Frag\2c\20bool\29,re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29 re2::Compiler::Nop\28\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::Nop\28\29,re2::Prog::Inst::InitNop\28unsigned\20int\29 -re2::Compiler::ByteRange\28int\2c\20int\2c\20bool\29,re2::Compiler::AllocInst\28int\29 -re2::Compiler::ByteRange\28int\2c\20int\2c\20bool\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 -re2::Compiler::Match\28int\29,re2::Compiler::AllocInst\28int\29 -re2::Compiler::Match\28int\29,re2::Prog::Inst::InitMatch\28int\29 re2::Compiler::EmptyWidth\28re2::EmptyOp\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::EmptyWidth\28re2::EmptyOp\29,re2::Prog::Inst::InitEmptyWidth\28re2::EmptyOp\2c\20unsigned\20int\29 re2::Compiler::Capture\28re2::Frag\2c\20int\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::Capture\28re2::Frag\2c\20int\29,re2::Prog::Inst::InitCapture\28int\2c\20unsigned\20int\29 re2::Compiler::Capture\28re2::Frag\2c\20int\29,opa_abort -re2::Compiler::BeginRange\28\29,operator\20delete\28void*\29 +re2::Compiler::BeginRange\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Compiler::BeginRange\28\29,memset re2::Compiler::UncachedRuneByteSuffix\28unsigned\20char\2c\20unsigned\20char\2c\20bool\2c\20int\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::UncachedRuneByteSuffix\28unsigned\20char\2c\20unsigned\20char\2c\20bool\2c\20int\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 re2::Compiler::UncachedRuneByteSuffix\28unsigned\20char\2c\20unsigned\20char\2c\20bool\2c\20int\29,opa_abort -std::__1::pair\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__emplace_unique_key_args\2c\20std::__1::tuple<>\20>\28unsigned\20long\20long\20const&\2c\20std::__1::piecewise_construct_t\20const&\2c\20std::__1::tuple&&\2c\20std::__1::tuple<>&&\29,operator\20new\28unsigned\20long\29 -std::__1::pair\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__emplace_unique_key_args\2c\20std::__1::tuple<>\20>\28unsigned\20long\20long\20const&\2c\20std::__1::piecewise_construct_t\20const&\2c\20std::__1::tuple&&\2c\20std::__1::tuple<>&&\29,std::__1::__next_prime\28unsigned\20long\29 -std::__1::pair\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__emplace_unique_key_args\2c\20std::__1::tuple<>\20>\28unsigned\20long\20long\20const&\2c\20std::__1::piecewise_construct_t\20const&\2c\20std::__1::tuple&&\2c\20std::__1::tuple<>&&\29,std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__rehash\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::find\28unsigned\20long\20long\20const&\29,std::_LIBCPP_ABI_NAMESPACE::__hash_memory\28void\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>>\28unsigned\20long\20long\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::piecewise_construct_t\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple&&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>&&\29,std::_LIBCPP_ABI_NAMESPACE::__hash_memory\28void\20const*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>>\28unsigned\20long\20long\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::piecewise_construct_t\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple&&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>&&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>>\28unsigned\20long\20long\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::piecewise_construct_t\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple&&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>&&\29,std::_LIBCPP_ABI_NAMESPACE::__next_prime\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>>\28unsigned\20long\20long\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::piecewise_construct_t\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple&&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>&&\29,void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__do_rehash\28unsigned\20long\29 re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,opa_abort -re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,re2::Compiler::FindByteRange\28int\2c\20int\29 +re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,re2::Compiler::ByteRangeEqual\28int\2c\20int\29 re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29 -re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,std::__1::__hash_iterator\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::find\28unsigned\20long\20long\20const&\29 +re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::find\28unsigned\20long\20long\20const&\29 re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 re2::Compiler::AddSuffixRecursive\28int\2c\20int\29,re2::Compiler::AddSuffixRecursive\28int\2c\20int\29 -re2::Compiler::FindByteRange\28int\2c\20int\29,opa_abort -re2::Compiler::FindByteRange\28int\2c\20int\29,re2::Compiler::ByteRangeEqual\28int\2c\20int\29 re2::Compiler::ByteRangeEqual\28int\2c\20int\29,opa_abort -re2::Compiler::AddRuneRange\28int\2c\20int\2c\20bool\29,re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29 -re2::Compiler::AddRuneRange\28int\2c\20int\2c\20bool\29,re2::Compiler::AddRuneRangeLatin1\28int\2c\20int\2c\20bool\29 -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::Add_80_10ffff\28\29 -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,runetochar re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29 -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,opa_abort -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,std::__1::__hash_iterator\2c\20void*>*>\20std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::find\28unsigned\20long\20long\20const&\29 -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::UncachedRuneByteSuffix\28unsigned\20char\2c\20unsigned\20char\2c\20bool\2c\20int\29 -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,std::__1::pair\2c\20void*>*>\2c\20bool>\20std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__emplace_unique_key_args\2c\20std::__1::tuple<>\20>\28unsigned\20long\20long\20const&\2c\20std::__1::piecewise_construct_t\20const&\2c\20std::__1::tuple&&\2c\20std::__1::tuple<>&&\29 -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::AddSuffixRecursive\28int\2c\20int\29 re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::AllocInst\28int\29 -re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29 re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::AddSuffixRecursive\28int\2c\20int\29 +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29 +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,runetochar +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,opa_abort +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,std::_LIBCPP_ABI_NAMESPACE::__hash_iterator\2c\20void*>*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::find\28unsigned\20long\20long\20const&\29 +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::UncachedRuneByteSuffix\28unsigned\20char\2c\20unsigned\20char\2c\20bool\2c\20int\29 +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,std::_LIBCPP_ABI_NAMESPACE::pair\2c\20void*>*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__emplace_unique_key_args\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>>\28unsigned\20long\20long\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::piecewise_construct_t\20const&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple&&\2c\20std::_LIBCPP_ABI_NAMESPACE::tuple<>&&\29 +re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29,re2::Compiler::Add_80_10ffff\28\29 re2::Compiler::AddRuneRangeLatin1\28int\2c\20int\2c\20bool\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::AddRuneRangeLatin1\28int\2c\20int\2c\20bool\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 re2::Compiler::AddRuneRangeLatin1\28int\2c\20int\2c\20bool\29,re2::Compiler::AddSuffixRecursive\28int\2c\20int\29 @@ -1635,22 +1681,25 @@ re2::Compiler::Literal\28int\2c\20bool\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::Literal\28int\2c\20bool\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 re2::Compiler::Literal\28int\2c\20bool\29,runetochar re2::Compiler::Literal\28int\2c\20bool\29,re2::Compiler::Cat\28re2::Frag\2c\20re2::Frag\29 -re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Nop\28\29 -re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Match\28int\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::AllocInst\28int\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Prog::Inst::InitNop\28unsigned\20int\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Prog::Inst::InitMatch\28int\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::EmptyWidth\28re2::EmptyOp\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Cat\28re2::Frag\2c\20re2::Frag\29 -re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Star\28re2::Frag\2c\20bool\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Quest\28re2::Frag\2c\20bool\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Literal\28int\2c\20bool\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Nop\28\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,opa_abort -re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::BeginRange\28\29 -re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::AddRuneRange\28int\2c\20int\2c\20bool\29 -re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::ByteRange\28int\2c\20int\2c\20bool\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,memset re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::AddRuneRangeUTF8\28int\2c\20int\2c\20bool\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::AddRuneRangeLatin1\28int\2c\20int\2c\20bool\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::BeginRange\28\29 re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Compiler::Capture\28re2::Frag\2c\20int\29 +re2::Compiler::PostVisit\28re2::Regexp*\2c\20re2::Frag\2c\20re2::Frag\2c\20re2::Frag*\2c\20int\29,re2::Prog::Inst::InitEmptyWidth\28re2::EmptyOp\2c\20unsigned\20int\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,operator\20new\28unsigned\20long\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Prog::Prog\28\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Prog::Inst::InitFail\28\29 @@ -1661,19 +1710,19 @@ re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Regexp: re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Regexp::Decref\28\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,memset re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,memmove -re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,operator\20delete\28void*\29 +re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Prog::Inst::InitMatch\28int\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Compiler::Cat\28re2::Frag\2c\20re2::Frag\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Compiler::DotStar\28\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Compiler::Finish\28re2::Regexp*\29 re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,re2::Compiler::~Compiler\28\29 -re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,abort +re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,re2::Regexp::Incref\28\29 re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,re2::IsAnchorStart\28re2::Regexp**\2c\20int\29 re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,operator\20new\28unsigned\20long\29 re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,re2::Regexp::Concat\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29 re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,re2::Regexp::Decref\28\29 -re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,operator\20delete\28void*\29 +re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,opa_abort re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,re2::Regexp::Capture\28re2::Regexp*\2c\20re2::Regexp::ParseFlags\2c\20int\29 re2::IsAnchorStart\28re2::Regexp**\2c\20int\29,re2::Regexp::LiteralString\28int*\2c\20int\2c\20re2::Regexp::ParseFlags\29 @@ -1682,73 +1731,74 @@ re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,re2::IsAnchorEnd\28re2::Regexp**\2c re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,operator\20new\28unsigned\20long\29 re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,re2::Regexp::Concat\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29 re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,re2::Regexp::Decref\28\29 -re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,operator\20delete\28void*\29 +re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,opa_abort re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,re2::Regexp::Capture\28re2::Regexp*\2c\20re2::Regexp::ParseFlags\2c\20int\29 re2::IsAnchorEnd\28re2::Regexp**\2c\20int\29,re2::Regexp::LiteralString\28int*\2c\20int\2c\20re2::Regexp::ParseFlags\29 re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Frag\2c\20bool\29,operator\20delete\5b\5d\28void*\29 -re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Frag\2c\20bool\29,operator\20delete\28void*\29 -re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Frag\2c\20bool\29,std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29 +re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Frag\2c\20bool\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Frag\2c\20bool\29,std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29 re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Frag\2c\20bool\29,operator\20new\5b\5d\28unsigned\20long\29 re2::Compiler::DotStar\28\29,re2::Compiler::AllocInst\28int\29 re2::Compiler::DotStar\28\29,re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29 re2::Compiler::DotStar\28\29,re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29 re2::Compiler::DotStar\28\29,opa_abort -re2::Compiler::Finish\28re2::Regexp*\29,operator\20delete\28void*\29 +re2::Compiler::Finish\28re2::Regexp*\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Compiler::Finish\28re2::Regexp*\29,re2::Prog::Optimize\28\29 re2::Compiler::Finish\28re2::Regexp*\29,re2::Prog::Flatten\28\29 re2::Compiler::Finish\28re2::Regexp*\29,re2::Prog::ComputeByteMap\28\29 -re2::Compiler::Finish\28re2::Regexp*\29,re2::Regexp::RequiredPrefixForAccel\28std::__1::basic_string\2c\20std::__1::allocator\20>*\2c\20bool*\29 +re2::Compiler::Finish\28re2::Regexp*\29,re2::Regexp::RequiredPrefixForAccel\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\2c\20bool*\29 re2::Regexp::CompileToProg\28long\20long\29,re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29 re2::Regexp::CompileToReverseProg\28long\20long\29,re2::Compiler::Compile\28re2::Regexp*\2c\20bool\2c\20long\20long\29 -std::__1::__deque_base\2c\20std::__1::allocator\20>\20>::~__deque_base\28\29,operator\20delete\28void*\29 -std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 -std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__rehash\28unsigned\20long\29,operator\20delete\28void*\29 -std::__1::__hash_table\2c\20std::__1::__unordered_map_hasher\2c\20std::__1::hash\2c\20std::__1::equal_to\2c\20true>\2c\20std::__1::__unordered_map_equal\2c\20std::__1::equal_to\2c\20std::__1::hash\2c\20true>\2c\20std::__1::allocator\20>\20>::__rehash\28unsigned\20long\29,abort -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,memmove -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,operator\20delete\28void*\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,abort +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::~deque\5babi:nn210108\5d\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__do_rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__do_rehash\28unsigned\20long\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__do_rehash\28unsigned\20long\29,memset +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_hasher\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::__unordered_map_equal\2c\20std::_LIBCPP_ABI_NAMESPACE::equal_to\2c\20std::_LIBCPP_ABI_NAMESPACE::hash\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__do_rehash\28unsigned\20long\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29,operator\20new\28unsigned\20long\29 -re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29,abort +re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::DFA::~DFA\28\29,opa_abort -re2::DFA::~DFA\28\29,operator\20delete\28void*\29 +re2::DFA::~DFA\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::DFA::~DFA\28\29,memset re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,operator\20new\28unsigned\20long\29 +re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,opa_abort -re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,void\20std::__1::__sort&\2c\20int*>\28int*\2c\20int*\2c\20std::__1::__less&\29 -re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,abort +re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,void\20std::_LIBCPP_ABI_NAMESPACE::__sort&\2c\20int*>\28int*\2c\20int*\2c\20std::_LIBCPP_ABI_NAMESPACE::__less&\29 re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29 -re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,operator\20delete\28void*\29 -re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,std::__1::__hash_iterator*>\20std::__1::__hash_table\20>::find\28re2::DFA::State*\20const&\29 +re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,std::_LIBCPP_ABI_NAMESPACE::__hash_iterator*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::find\28re2::DFA::State*\20const&\29 re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,operator\20new\28unsigned\20long\29 re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,memset -re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,memmove -re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,std::__1::pair*>\2c\20bool>\20std::__1::__hash_table\20>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29 -std::__1::__hash_iterator*>\20std::__1::__hash_table\20>::find\28re2::DFA::State*\20const&\29,opa_abort -std::__1::pair*>\2c\20bool>\20std::__1::__hash_table\20>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,opa_abort -std::__1::pair*>\2c\20bool>\20std::__1::__hash_table\20>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,operator\20new\28unsigned\20long\29 -std::__1::pair*>\2c\20bool>\20std::__1::__hash_table\20>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,std::__1::__next_prime\28unsigned\20long\29 -std::__1::pair*>\2c\20bool>\20std::__1::__hash_table\20>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,std::__1::__hash_table\20>::__rehash\28unsigned\20long\29 +re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,memcpy +re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29,std::_LIBCPP_ABI_NAMESPACE::pair*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29 +std::_LIBCPP_ABI_NAMESPACE::__hash_iterator*>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::find\28re2::DFA::State*\20const&\29,opa_abort +std::_LIBCPP_ABI_NAMESPACE::pair*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,opa_abort +std::_LIBCPP_ABI_NAMESPACE::pair*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,std::_LIBCPP_ABI_NAMESPACE::__next_prime\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::pair*>\2c\20bool>\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__emplace_unique_key_args\28re2::DFA::State*\20const&\2c\20re2::DFA::State*\20const&\29,void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__do_rehash\28unsigned\20long\29 re2::SparseSetT::InsertInternal\28bool\2c\20int\29,opa_abort re2::SparseSetT::InsertInternal\28bool\2c\20int\29,re2::SparseSetT::create_index\28int\29 re2::DFA::AddToQueue\28re2::DFA::Workq*\2c\20int\2c\20unsigned\20int\29,opa_abort @@ -1761,7 +1811,8 @@ re2::DFA::RunStateOnByte\28re2::DFA::State*\2c\20int\29,re2::DFA::AddToQueue\28r re2::DFA::RunStateOnByte\28re2::DFA::State*\2c\20int\29,re2::DFA::RunWorkqOnByte\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20int\2c\20unsigned\20int\2c\20bool*\29 re2::DFA::RunStateOnByte\28re2::DFA::State*\2c\20int\29,re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29 re2::DFA::ResetCache\28re2::DFA::RWLocker*\29,re2::hooks::GetDFAStateCacheResetHook\28\29 -re2::DFA::ResetCache\28re2::DFA::RWLocker*\29,operator\20delete\28void*\29 +re2::DFA::ResetCache\28re2::DFA::RWLocker*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::DFA::ResetCache\28re2::DFA::RWLocker*\29,memset re2::DFA::SearchFFF\28re2::DFA::SearchParams*\29,bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::RunStateOnByte\28re2::DFA::State*\2c\20int\29 @@ -1821,9 +1872,9 @@ bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::Search bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,memchr bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::Prog::PrefixAccel_FrontAndBack\28void\20const*\2c\20unsigned\20long\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::RunStateOnByte\28re2::DFA::State*\2c\20int\29 +bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::ResetCache\28re2::DFA::RWLocker*\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,operator\20new\5b\5d\28unsigned\20long\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,memmove -bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::ResetCache\28re2::DFA::RWLocker*\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,operator\20delete\5b\5d\28void*\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 @@ -1832,61 +1883,60 @@ bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchP bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,memchr bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::Prog::PrefixAccel_FrontAndBack\28void\20const*\2c\20unsigned\20long\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::RunStateOnByte\28re2::DFA::State*\2c\20int\29 +bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::ResetCache\28re2::DFA::RWLocker*\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,operator\20new\5b\5d\28unsigned\20long\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,memmove -bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::ResetCache\28re2::DFA::RWLocker*\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::DFA::CachedState\28int*\2c\20int\2c\20unsigned\20int\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,operator\20delete\5b\5d\28void*\29 bool\20re2::DFA::InlinedSearchLoop\28re2::DFA::SearchParams*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 re2::DFA::AnalyzeSearch\28re2::DFA::SearchParams*\29,re2::DFA::AddToQueue\28re2::DFA::Workq*\2c\20int\2c\20unsigned\20int\29 re2::DFA::AnalyzeSearch\28re2::DFA::SearchParams*\29,re2::DFA::WorkqToCachedState\28re2::DFA::Workq*\2c\20re2::DFA::Workq*\2c\20unsigned\20int\29 re2::DFA::AnalyzeSearch\28re2::DFA::SearchParams*\29,re2::DFA::ResetCache\28re2::DFA::RWLocker*\29 -re2::DFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20bool\2c\20bool*\2c\20char\20const**\2c\20re2::SparseSetT*\29,re2::DFA::AnalyzeSearch\28re2::DFA::SearchParams*\29 -re2::Prog::GetDFA\28re2::Prog::MatchKind\29,std::__1::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,operator\20new\28unsigned\20long\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,operator\20new\28unsigned\20long\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,operator\20new\28unsigned\20long\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29 +re2::Prog::GetDFA\28re2::Prog::MatchKind\29,std::_LIBCPP_ABI_NAMESPACE::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,re2::DFA::DFA\28re2::Prog*\2c\20re2::Prog::MatchKind\2c\20long\20long\29 re2::Prog::DeleteDFA\28re2::DFA*\29,re2::DFA::~DFA\28\29 -re2::Prog::DeleteDFA\28re2::DFA*\29,operator\20delete\28void*\29 +re2::Prog::DeleteDFA\28re2::DFA*\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Prog::SearchDFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20bool*\2c\20re2::SparseSetT*\29,re2::Prog::GetDFA\28re2::Prog::MatchKind\29 -re2::Prog::SearchDFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20bool*\2c\20re2::SparseSetT*\29,re2::DFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20bool\2c\20bool*\2c\20char\20const**\2c\20re2::SparseSetT*\29 +re2::Prog::SearchDFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20bool*\2c\20re2::SparseSetT*\29,re2::DFA::AnalyzeSearch\28re2::DFA::SearchParams*\29 re2::Prog::SearchDFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20bool*\2c\20re2::SparseSetT*\29,re2::hooks::GetDFASearchFailureHook\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 re2::SparseSetT::create_index\28int\29,opa_abort -std::__1::__hash_table\20>::__rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 -std::__1::__hash_table\20>::__rehash\28unsigned\20long\29,operator\20delete\28void*\29 -std::__1::__hash_table\20>::__rehash\28unsigned\20long\29,opa_abort -std::__1::__hash_table\20>::__rehash\28unsigned\20long\29,abort +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__do_rehash\28unsigned\20long\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__do_rehash\28unsigned\20long\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__do_rehash\28unsigned\20long\29,memset +void\20std::_LIBCPP_ABI_NAMESPACE::__hash_table>::__do_rehash\28unsigned\20long\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::NFA::NFA\28re2::Prog*\29,memset re2::NFA::NFA\28re2::Prog*\29,re2::SparseArray::resize\28int\29 re2::NFA::NFA\28re2::Prog*\29,operator\20new\28unsigned\20long\29 -re2::NFA::NFA\28re2::Prog*\29,operator\20delete\28void*\29 -re2::NFA::NFA\28re2::Prog*\29,abort +re2::NFA::NFA\28re2::Prog*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::NFA::NFA\28re2::Prog*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::SparseArray::resize\28int\29,opa_abort re2::SparseArray::resize\28int\29,operator\20new\28unsigned\20long\29 re2::SparseArray::resize\28int\29,memmove -re2::SparseArray::resize\28int\29,operator\20delete\28void*\29 -re2::SparseArray::resize\28int\29,abort +re2::SparseArray::resize\28int\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::SparseArray::resize\28int\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::NFA::~NFA\28\29,operator\20delete\5b\5d\28void*\29 -re2::NFA::~NFA\28\29,std::__1::__deque_base\20>::~__deque_base\28\29 -re2::NFA::~NFA\28\29,operator\20delete\28void*\29 +re2::NFA::~NFA\28\29,std::_LIBCPP_ABI_NAMESPACE::deque>::~deque\5babi:nn210108\5d\28\29 +re2::NFA::~NFA\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::NFA::~NFA\28\29,opa_abort -std::__1::__deque_base\20>::~__deque_base\28\29,operator\20delete\28void*\29 +std::_LIBCPP_ABI_NAMESPACE::deque>::~deque\5babi:nn210108\5d\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29,opa_abort -re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29,std::__1::deque\20>::__add_back_capacity\28\29 +re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29,std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29 re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29,operator\20new\5b\5d\28unsigned\20long\29 re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29,memmove re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29,re2::Prog::EmptyFlags\28re2::StringPiece\20const&\2c\20char\20const*\29 -std::__1::deque\20>::__add_back_capacity\28\29,memmove -std::__1::deque\20>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 -std::__1::deque\20>::__add_back_capacity\28\29,operator\20delete\28void*\29 -std::__1::deque\20>::__add_back_capacity\28\29,std::__1::__split_buffer\20>::push_back\28re2::NFA::Thread*&&\29 -std::__1::deque\20>::__add_back_capacity\28\29,std::__1::__split_buffer\20>::push_front\28re2::NFA::Thread*&&\29 -std::__1::deque\20>::__add_back_capacity\28\29,std::__1::__split_buffer&>::push_back\28re2::NFA::Thread*&&\29 -std::__1::deque\20>::__add_back_capacity\28\29,std::__1::__split_buffer&>::push_front\28re2::NFA::Thread*\20const&\29 -std::__1::deque\20>::__add_back_capacity\28\29,abort +std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer&>::emplace_front\28re2::NFA::Thread*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_front\28re2::NFA::Thread*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::NFA::Step\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\29,memmove re2::NFA::Step\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\29,opa_abort re2::NFA::Step\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\29,re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29 @@ -1894,13 +1944,11 @@ re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\2 re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,memset re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,re2::NFA::Step\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\29 re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,opa_abort -re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,re2::Prog::PrefixAccel\28void\20const*\2c\20unsigned\20long\29 -re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,std::__1::deque\20>::__add_back_capacity\28\29 +re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,memchr +re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,re2::Prog::PrefixAccel_FrontAndBack\28void\20const*\2c\20unsigned\20long\29 +re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,std::_LIBCPP_ABI_NAMESPACE::deque>::__add_back_capacity\28\29 re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,memmove re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29,re2::NFA::AddToThreadq\28re2::SparseArray*\2c\20int\2c\20int\2c\20re2::StringPiece\20const&\2c\20char\20const*\2c\20re2::NFA::Thread*\29 -re2::Prog::PrefixAccel\28void\20const*\2c\20unsigned\20long\29,opa_abort -re2::Prog::PrefixAccel\28void\20const*\2c\20unsigned\20long\29,memchr -re2::Prog::PrefixAccel\28void\20const*\2c\20unsigned\20long\29,re2::Prog::PrefixAccel_FrontAndBack\28void\20const*\2c\20unsigned\20long\29 re2::Prog::SearchNFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,re2::NFA::NFA\28re2::Prog*\29 re2::Prog::SearchNFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,re2::NFA::Search\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20bool\2c\20bool\2c\20re2::StringPiece*\2c\20int\29 re2::Prog::SearchNFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,re2::NFA::~NFA\28\29 @@ -1909,22 +1957,22 @@ re2::SparseArray::SetInternal\28bool\2c\20int\2c\20int\20const&\29,re2::Spa re2::SparseArray::SetInternal\28bool\2c\20int\2c\20int\20const&\29,re2::SparseArray::SetExistingInternal\28int\2c\20int\20const&\29 re2::SparseArray::create_index\28int\29,opa_abort re2::SparseArray::SetExistingInternal\28int\2c\20int\20const&\29,opa_abort -std::__1::__split_buffer\20>::push_back\28re2::NFA::Thread*&&\29,memmove -std::__1::__split_buffer\20>::push_back\28re2::NFA::Thread*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer\20>::push_back\28re2::NFA::Thread*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer\20>::push_back\28re2::NFA::Thread*&&\29,abort -std::__1::__split_buffer\20>::push_front\28re2::NFA::Thread*&&\29,memmove -std::__1::__split_buffer\20>::push_front\28re2::NFA::Thread*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer\20>::push_front\28re2::NFA::Thread*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer\20>::push_front\28re2::NFA::Thread*&&\29,abort -std::__1::__split_buffer&>::push_back\28re2::NFA::Thread*&&\29,memmove -std::__1::__split_buffer&>::push_back\28re2::NFA::Thread*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer&>::push_back\28re2::NFA::Thread*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer&>::push_back\28re2::NFA::Thread*&&\29,abort -std::__1::__split_buffer&>::push_front\28re2::NFA::Thread*\20const&\29,memmove -std::__1::__split_buffer&>::push_front\28re2::NFA::Thread*\20const&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer&>::push_front\28re2::NFA::Thread*\20const&\29,operator\20delete\28void*\29 -std::__1::__split_buffer&>::push_front\28re2::NFA::Thread*\20const&\29,abort +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_back\28re2::NFA::Thread*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer&>::emplace_front\28re2::NFA::Thread*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer&>::emplace_front\28re2::NFA::Thread*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer&>::emplace_front\28re2::NFA::Thread*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer&>::emplace_front\28re2::NFA::Thread*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_front\28re2::NFA::Thread*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_front\28re2::NFA::Thread*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_front\28re2::NFA::Thread*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer>::emplace_front\28re2::NFA::Thread*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::Prog::SearchOnePass\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,memset re2::Prog::SearchOnePass\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,re2::Prog::EmptyFlags\28re2::StringPiece\20const&\2c\20char\20const*\29 re2::Prog::SearchOnePass\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29,memcpy @@ -1932,17 +1980,19 @@ re2::Prog::IsOnePass\28\29,operator\20new\28unsigned\20long\29 re2::Prog::IsOnePass\28\29,memset re2::Prog::IsOnePass\28\29,opa_abort re2::Prog::IsOnePass\28\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 -re2::Prog::IsOnePass\28\29,std::__1::vector\20>::insert\28std::__1::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29 -re2::Prog::IsOnePass\28\29,operator\20delete\28void*\29 +re2::Prog::IsOnePass\28\29,std::_LIBCPP_ABI_NAMESPACE::vector>::insert\28std::_LIBCPP_ABI_NAMESPACE::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29 +re2::Prog::IsOnePass\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Prog::IsOnePass\28\29,memmove -re2::Prog::IsOnePass\28\29,abort -std::__1::vector\20>::insert\28std::__1::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,memmove -std::__1::vector\20>::insert\28std::__1::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,operator\20new\28unsigned\20long\29 -std::__1::vector\20>::insert\28std::__1::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,memcpy -std::__1::vector\20>::insert\28std::__1::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,operator\20delete\28void*\29 -std::__1::vector\20>::insert\28std::__1::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,abort -std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29,operator\20delete\28void*\29 +re2::Prog::IsOnePass\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::insert\28std::_LIBCPP_ABI_NAMESPACE::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,memset +std::_LIBCPP_ABI_NAMESPACE::vector>::insert\28std::_LIBCPP_ABI_NAMESPACE::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,memmove +std::_LIBCPP_ABI_NAMESPACE::vector>::insert\28std::_LIBCPP_ABI_NAMESPACE::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::insert\28std::_LIBCPP_ABI_NAMESPACE::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::vector>::insert\28std::_LIBCPP_ABI_NAMESPACE::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::insert\28std::_LIBCPP_ABI_NAMESPACE::__wrap_iter\2c\20unsigned\20long\2c\20unsigned\20char\20const&\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 +std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29,re2::Regexp::ParseState::MaybeConcatString\28int\2c\20re2::Regexp::ParseFlags\29 re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29,re2::CharClassBuilder::RemoveAbove\28int\29 re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29,re2::Regexp::Decref\28\29 @@ -1965,36 +2015,36 @@ re2::Regexp::ParseState::PushSimpleOp\28re2::RegexpOp\29,re2::Regexp::Regexp\28r re2::Regexp::ParseState::PushSimpleOp\28re2::RegexpOp\29,re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29 re2::Regexp::ParseState::PushDot\28\29,operator\20new\28unsigned\20long\29 re2::Regexp::ParseState::PushDot\28\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 -re2::Regexp::ParseState::PushDot\28\29,re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29 re2::Regexp::ParseState::PushDot\28\29,re2::CharClassBuilder::CharClassBuilder\28\29 re2::Regexp::ParseState::PushDot\28\29,re2::CharClassBuilder::AddRange\28int\2c\20int\29 +re2::Regexp::ParseState::PushDot\28\29,re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29 re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,operator\20new\28unsigned\20long\29 re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::CharClassBuilder::GetCharClass\28\29 -re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,operator\20delete\28void*\29 +re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::ParseState::PushRepeatOp\28re2::RegexpOp\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::Regexp::ComputeSimple\28\29 re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,operator\20new\28unsigned\20long\29 re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::CharClassBuilder::GetCharClass\28\29 -re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,operator\20delete\28void*\29 +re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::Regexp::ComputeSimple\28\29 re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29 re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29,re2::Regexp::Walker::~Walker\28\29 re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29,operator\20delete\5b\5d\28void*\29 -re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29,operator\20delete\28void*\29 -re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29,std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29 +re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29,std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29 re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29,operator\20new\5b\5d\28unsigned\20long\29 re2::Regexp::Walker::~Walker\28\29,operator\20delete\5b\5d\28void*\29 -re2::Regexp::Walker::~Walker\28\29,operator\20delete\28void*\29 -re2::Regexp::Walker::~Walker\28\29,std::__1::__deque_base\2c\20std::__1::allocator\20>\20>::~__deque_base\28\29 -std::__1::__deque_base\2c\20std::__1::allocator\20>\20>::~__deque_base\28\29,operator\20delete\28void*\29 +re2::Regexp::Walker::~Walker\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Regexp::Walker::~Walker\28\29,std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::~deque\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::~deque\5babi:nn210108\5d\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::ParseState::DoLeftParen\28re2::StringPiece\20const&\29,operator\20new\28unsigned\20long\29 re2::Regexp::ParseState::DoLeftParen\28re2::StringPiece\20const&\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 -re2::Regexp::ParseState::DoLeftParen\28re2::StringPiece\20const&\29,memcpy +re2::Regexp::ParseState::DoLeftParen\28re2::StringPiece\20const&\29,memmove re2::Regexp::ParseState::DoLeftParen\28re2::StringPiece\20const&\29,re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29 -re2::Regexp::ParseState::DoLeftParen\28re2::StringPiece\20const&\29,abort +re2::Regexp::ParseState::DoLeftParen\28re2::StringPiece\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 re2::Regexp::ParseState::DoVerticalBar\28\29,re2::Regexp::ParseState::MaybeConcatString\28int\2c\20re2::Regexp::ParseFlags\29 re2::Regexp::ParseState::DoVerticalBar\28\29,operator\20new\28unsigned\20long\29 re2::Regexp::ParseState::DoVerticalBar\28\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 @@ -2005,65 +2055,70 @@ re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,operator\20new\28unsigned re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,re2::Regexp::Incref\28\29 re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,re2::Regexp::Decref\28\29 re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,re2::CharClassBuilder::GetCharClass\28\29 -re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,operator\20delete\28void*\29 +re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29 re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,re2::Regexp::ComputeSimple\28\29 -re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,abort +re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::Regexp::ParseState::DoRightParen\28\29,re2::Regexp::ParseState::DoVerticalBar\28\29 re2::Regexp::ParseState::DoRightParen\28\29,re2::Regexp::Decref\28\29 re2::Regexp::ParseState::DoRightParen\28\29,re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29 re2::Regexp::ParseState::DoRightParen\28\29,re2::CharClassBuilder::GetCharClass\28\29 -re2::Regexp::ParseState::DoRightParen\28\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::Regexp::ParseState::DoRightParen\28\29,operator\20delete\28void*\29 +re2::Regexp::ParseState::DoRightParen\28\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::Regexp::ParseState::DoRightParen\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::ParseState::DoRightParen\28\29,re2::Regexp::ComputeSimple\28\29 re2::Regexp::ParseState::DoRightParen\28\29,re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29 re2::Regexp::ParseState::DoFinish\28\29,re2::Regexp::ParseState::DoVerticalBar\28\29 re2::Regexp::ParseState::DoFinish\28\29,re2::Regexp::Decref\28\29 re2::Regexp::ParseState::DoFinish\28\29,re2::Regexp::ParseState::DoCollapse\28re2::RegexpOp\29 re2::Regexp::ParseState::DoFinish\28\29,re2::CharClassBuilder::GetCharClass\28\29 -re2::Regexp::ParseState::DoFinish\28\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::Regexp::ParseState::DoFinish\28\29,operator\20delete\28void*\29 +re2::Regexp::ParseState::DoFinish\28\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::Regexp::ParseState::DoFinish\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::RemoveLeadingString\28re2::Regexp*\2c\20int\29,operator\20delete\5b\5d\28void*\29 re2::Regexp::RemoveLeadingString\28re2::Regexp*\2c\20int\29,memmove re2::Regexp::RemoveLeadingString\28re2::Regexp*\2c\20int\29,re2::Regexp::Decref\28\29 re2::Regexp::RemoveLeadingString\28re2::Regexp*\2c\20int\29,re2::Regexp::Swap\28re2::Regexp*\29 -re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,void\20std::__1::vector\20>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29 +re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Frame*\20std::_LIBCPP_ABI_NAMESPACE::vector>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29 re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::AlternateNoFactor\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29 re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::Concat\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29 -re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29 -re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29 -re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,operator\20delete\28void*\29 -re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29 -void\20std::__1::vector\20>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29,operator\20new\28unsigned\20long\29 -void\20std::__1::vector\20>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29,operator\20delete\28void*\29 -void\20std::__1::vector\20>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29,abort -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29 -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::Incref\28\29 -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::Decref\28\29 -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,memmove -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,operator\20new\28unsigned\20long\29 -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,memcpy -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,operator\20delete\28void*\29 -re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,abort -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::CharClassBuilder::CharClassBuilder\28\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::CharClassBuilder::AddRange\28int\2c\20int\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::AddFoldedRange\28re2::CharClassBuilder*\2c\20int\2c\20int\2c\20int\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::Decref\28\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::CharClassBuilder::GetCharClass\28\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::NewCharClass\28re2::CharClass*\2c\20re2::Regexp::ParseFlags\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,operator\20new\28unsigned\20long\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,memcpy -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,operator\20delete\28void*\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,abort -re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::LiteralString\28int*\2c\20int\2c\20re2::Regexp::ParseFlags\29 -re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,re2::Regexp::RemoveLeadingString\28re2::Regexp*\2c\20int\29 -re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,operator\20new\28unsigned\20long\29 -re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,memcpy -re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,operator\20delete\28void*\29 -re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::__1::vector\20>*\29,abort +re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29 +re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29 +re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Regexp::FactorAlternation\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29 +re2::Frame*\20std::_LIBCPP_ABI_NAMESPACE::vector>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29,operator\20new\28unsigned\20long\29 +re2::Frame*\20std::_LIBCPP_ABI_NAMESPACE::vector>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Frame*\20std::_LIBCPP_ABI_NAMESPACE::vector>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Frame*\20std::_LIBCPP_ABI_NAMESPACE::vector>::__emplace_back_slow_path\28re2::Regexp**&\2c\20int&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::Incref\28\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::Decref\28\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,memmove +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20new\28unsigned\20long\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,memcpy +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::FactorAlternationImpl::Round2\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::CharClassBuilder::CharClassBuilder\28\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::CharClassBuilder::AddRange\28int\2c\20int\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::AddFoldedRange\28re2::CharClassBuilder*\2c\20int\2c\20int\2c\20int\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::Decref\28\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::CharClassBuilder::GetCharClass\28\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::NewCharClass\28re2::CharClass*\2c\20re2::Regexp::ParseFlags\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20new\28unsigned\20long\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,memcpy +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::FactorAlternationImpl::Round3\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::LiteralString\28int*\2c\20int\2c\20re2::Regexp::ParseFlags\29 +re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::Regexp::RemoveLeadingString\28re2::Regexp*\2c\20int\29 +re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20new\28unsigned\20long\29 +re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,memcpy +re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::FactorAlternationImpl::Round1\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 re2::AddFoldedRange\28re2::CharClassBuilder*\2c\20int\2c\20int\2c\20int\29,re2::CharClassBuilder::AddRange\28int\2c\20int\29 re2::AddFoldedRange\28re2::CharClassBuilder*\2c\20int\2c\20int\2c\20int\29,re2::AddFoldedRange\28re2::CharClassBuilder*\2c\20int\2c\20int\2c\20int\29 re2::CharClassBuilder::AddRangeFlags\28int\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::AddFoldedRange\28re2::CharClassBuilder*\2c\20int\2c\20int\2c\20int\29 @@ -2082,7 +2137,7 @@ re2::AddUGroup\28re2::CharClassBuilder*\2c\20re2::UGroup\20const*\2c\20int\2c\20 re2::AddUGroup\28re2::CharClassBuilder*\2c\20re2::UGroup\20const*\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::CharClassBuilder::AddRange\28int\2c\20int\29 re2::AddUGroup\28re2::CharClassBuilder*\2c\20re2::UGroup\20const*\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::CharClassBuilder::Negate\28\29 re2::AddUGroup\28re2::CharClassBuilder*\2c\20re2::UGroup\20const*\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::CharClassBuilder::AddCharClass\28re2::CharClassBuilder*\29 -re2::AddUGroup\28re2::CharClassBuilder*\2c\20re2::UGroup\20const*\2c\20int\2c\20re2::Regexp::ParseFlags\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 +re2::AddUGroup\28re2::CharClassBuilder*\2c\20re2::UGroup\20const*\2c\20int\2c\20re2::Regexp::ParseFlags\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 re2::StringPieceToRune\28int*\2c\20re2::StringPiece*\2c\20re2::RegexpStatus*\29,fullrune re2::StringPieceToRune\28int*\2c\20re2::StringPiece*\2c\20re2::RegexpStatus*\29,chartorune re2::Regexp::ParseState::ParseCCCharacter\28re2::StringPiece*\2c\20int*\2c\20re2::StringPiece\20const&\2c\20re2::RegexpStatus*\29,re2::ParseEscape\28re2::StringPiece*\2c\20int*\2c\20re2::RegexpStatus*\2c\20int\29 @@ -2117,8 +2172,8 @@ re2::Regexp::ParseState::ParsePerlFlags\28re2::StringPiece*\29,re2::Regexp::Rege re2::Regexp::ParseState::ParsePerlFlags\28re2::StringPiece*\29,re2::Regexp::ParseState::PushRegexp\28re2::Regexp*\29 re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,operator\20new\28unsigned\20long\29 re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,runetochar -re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29 -re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,operator\20delete\28void*\29 +re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29 +re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,fullrune re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,chartorune re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,re2::Regexp::ParseState::PushLiteral\28int\29 @@ -2142,31 +2197,31 @@ re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\2 re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,re2::AddUGroup\28re2::CharClassBuilder*\2c\20re2::UGroup\20const*\2c\20int\2c\20re2::Regexp::ParseFlags\29 re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29,re2::Regexp::ParseState::PushRepetition\28int\2c\20int\2c\20re2::StringPiece\20const&\2c\20bool\29 re2::RepetitionWalker::~RepetitionWalker\28\29,re2::Regexp::Walker::~Walker\28\29 -re2::RepetitionWalker::~RepetitionWalker\28\29,operator\20delete\28void*\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,memmove -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,operator\20delete\28void*\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,abort +re2::RepetitionWalker::~RepetitionWalker\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 re2::Prog::Inst::InitAlt\28unsigned\20int\2c\20unsigned\20int\29,opa_abort re2::Prog::Inst::InitByteRange\28int\2c\20int\2c\20int\2c\20unsigned\20int\29,opa_abort re2::Prog::Inst::InitCapture\28int\2c\20unsigned\20int\29,opa_abort @@ -2175,26 +2230,30 @@ re2::Prog::Inst::InitMatch\28int\29,opa_abort re2::Prog::Inst::InitNop\28unsigned\20int\29,opa_abort re2::Prog::Inst::InitFail\28\29,opa_abort re2::Prog::~Prog\28\29,re2::Prog::DeleteDFA\28re2::DFA*\29 -re2::Prog::~Prog\28\29,operator\20delete\28void*\29 +re2::Prog::~Prog\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Prog::Optimize\28\29,operator\20new\28unsigned\20long\29 re2::Prog::Optimize\28\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 +re2::Prog::Optimize\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::Prog::Optimize\28\29,opa_abort -re2::Prog::Optimize\28\29,abort -re2::Prog::Optimize\28\29,operator\20delete\28void*\29 +re2::Prog::Optimize\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::ByteMapBuilder::Mark\28int\2c\20int\29,opa_abort re2::ByteMapBuilder::Mark\28int\2c\20int\29,operator\20new\28unsigned\20long\29 re2::ByteMapBuilder::Mark\28int\2c\20int\29,memcpy -re2::ByteMapBuilder::Mark\28int\2c\20int\29,operator\20delete\28void*\29 -re2::ByteMapBuilder::Mark\28int\2c\20int\29,abort +re2::ByteMapBuilder::Mark\28int\2c\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::ByteMapBuilder::Mark\28int\2c\20int\29,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::ByteMapBuilder::Mark\28int\2c\20int\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 re2::ByteMapBuilder::Merge\28\29,opa_abort re2::ByteMapBuilder::Merge\28\29,operator\20new\28unsigned\20long\29 re2::ByteMapBuilder::Merge\28\29,memcpy -re2::ByteMapBuilder::Merge\28\29,operator\20delete\28void*\29 -re2::ByteMapBuilder::Merge\28\29,abort +re2::ByteMapBuilder::Merge\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::ByteMapBuilder::Merge\28\29,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::ByteMapBuilder::Merge\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::ByteMapBuilder::Recolor\28int\29,operator\20new\28unsigned\20long\29 re2::ByteMapBuilder::Recolor\28int\29,memcpy -re2::ByteMapBuilder::Recolor\28int\29,operator\20delete\28void*\29 -re2::ByteMapBuilder::Recolor\28int\29,abort +re2::ByteMapBuilder::Recolor\28int\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::ByteMapBuilder::Recolor\28int\29,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::ByteMapBuilder::Recolor\28int\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::ByteMapBuilder::Build\28unsigned\20char*\2c\20int*\29,opa_abort re2::ByteMapBuilder::Build\28unsigned\20char*\2c\20int*\29,re2::ByteMapBuilder::Recolor\28int\29 re2::ByteMapBuilder::Build\28unsigned\20char*\2c\20int*\29,memset @@ -2202,78 +2261,99 @@ re2::Prog::ComputeByteMap\28\29,re2::ByteMapBuilder::Mark\28int\2c\20int\29 re2::Prog::ComputeByteMap\28\29,opa_abort re2::Prog::ComputeByteMap\28\29,operator\20new\28unsigned\20long\29 re2::Prog::ComputeByteMap\28\29,memcpy -re2::Prog::ComputeByteMap\28\29,operator\20delete\28void*\29 +re2::Prog::ComputeByteMap\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Prog::ComputeByteMap\28\29,re2::ByteMapBuilder::Merge\28\29 -re2::Prog::ComputeByteMap\28\29,abort +re2::Prog::ComputeByteMap\28\29,std::_LIBCPP_ABI_NAMESPACE::vector\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Prog::ComputeByteMap\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::Prog::ComputeByteMap\28\29,re2::ByteMapBuilder::Build\28unsigned\20char*\2c\20int*\29 re2::Prog::Flatten\28\29,operator\20new\28unsigned\20long\29 -re2::Prog::Flatten\28\29,re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29 +re2::Prog::Flatten\28\29,re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29 re2::Prog::Flatten\28\29,memmove -re2::Prog::Flatten\28\29,void\20std::__1::__sort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 -re2::Prog::Flatten\28\29,re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29 +re2::Prog::Flatten\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__introsort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\20false>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20std::_LIBCPP_ABI_NAMESPACE::iterator_traits::IndexValue*>::difference_type\2c\20bool\29 +re2::Prog::Flatten\28\29,re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29 re2::Prog::Flatten\28\29,memset -re2::Prog::Flatten\28\29,re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::__1::vector\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29 -re2::Prog::Flatten\28\29,re2::Prog::ComputeHints\28std::__1::vector\20>*\2c\20int\2c\20int\29 +re2::Prog::Flatten\28\29,re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29 +re2::Prog::Flatten\28\29,re2::Prog::ComputeHints\28std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20int\2c\20int\29 +re2::Prog::Flatten\28\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Prog::Flatten\28\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 re2::Prog::Flatten\28\29,opa_abort -re2::Prog::Flatten\28\29,operator\20delete\28void*\29 -re2::Prog::Flatten\28\29,abort -re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,re2::SparseArray::SetInternal\28bool\2c\20int\2c\20int\20const&\29 -re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,opa_abort -re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,operator\20new\28unsigned\20long\29 -re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,operator\20delete\28void*\29 -re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 -re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,memcpy -re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,abort -void\20std::__1::__sort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29,unsigned\20int\20std::__1::__sort4::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 -void\20std::__1::__sort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29,void\20std::__1::__insertion_sort_3::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 -void\20std::__1::__sort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29,bool\20std::__1::__insertion_sort_incomplete::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 -void\20std::__1::__sort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29,void\20std::__1::__sort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,operator\20new\28unsigned\20long\29 -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,operator\20delete\28void*\29 -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,opa_abort -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,memcpy -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,re2::SparseArray::create_index\28int\29 -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,re2::SparseArray::SetExistingInternal\28int\2c\20int\20const&\29 -re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::__1::vector\20>\2c\20std::__1::allocator\20>\20>\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,abort -re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::__1::vector\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,operator\20new\28unsigned\20long\29 -re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::__1::vector\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,operator\20delete\28void*\29 -re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::__1::vector\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,opa_abort -re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::__1::vector\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 -re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::__1::vector\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,memcpy -re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::__1::vector\20>*\2c\20re2::SparseSetT*\2c\20std::__1::vector\20>*\29,abort -re2::Prog::ComputeHints\28std::__1::vector\20>*\2c\20int\2c\20int\29,opa_abort -re2::Prog::ComputeHints\28std::__1::vector\20>*\2c\20int\2c\20int\29,re2::Prog::ComputeHints\28std::__1::vector\20>*\2c\20int\2c\20int\29::$_1::operator\28\29\28int\2c\20int\29\20const -re2::Prog::ComputeHints\28std::__1::vector\20>*\2c\20int\2c\20int\29::$_1::operator\28\29\28int\2c\20int\29\20const,opa_abort +re2::Prog::Flatten\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Prog::Flatten\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::SparseArray::SetInternal\28bool\2c\20int\2c\20int\20const&\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,opa_abort +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int&&\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20new\28unsigned\20long\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,memcpy +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Prog::MarkSuccessors\28re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__introsort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\20false>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20std::_LIBCPP_ABI_NAMESPACE::iterator_traits::IndexValue*>::difference_type\2c\20bool\29,re2::SparseArray::IndexValue*\20std::_LIBCPP_ABI_NAMESPACE::__partial_sort_impl\5babi:nn210108\5d::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__introsort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\20false>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20std::_LIBCPP_ABI_NAMESPACE::iterator_traits::IndexValue*>::difference_type\2c\20bool\29,void\20std::_LIBCPP_ABI_NAMESPACE::__sort5\5babi:nn210108\5d::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\200>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__introsort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\20false>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20std::_LIBCPP_ABI_NAMESPACE::iterator_traits::IndexValue*>::difference_type\2c\20bool\29,bool\20std::_LIBCPP_ABI_NAMESPACE::__insertion_sort_incomplete\5babi:nn210108\5d::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__introsort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\20false>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20std::_LIBCPP_ABI_NAMESPACE::iterator_traits::IndexValue*>::difference_type\2c\20bool\29,void\20std::_LIBCPP_ABI_NAMESPACE::__introsort::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\20false>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20std::_LIBCPP_ABI_NAMESPACE::iterator_traits::IndexValue*>::difference_type\2c\20bool\29 +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int\20const&\29 +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,opa_abort +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20new\28unsigned\20long\29 +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,memcpy +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Prog::MarkDominator\28int\2c\20re2::SparseArray*\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int\20const&\29 +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,opa_abort +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,re2::SparseSetT::InsertInternal\28bool\2c\20int\29 +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20new\28unsigned\20long\29 +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,memcpy +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::Prog::EmitList\28int\2c\20re2::SparseArray*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20re2::SparseSetT*\2c\20std::_LIBCPP_ABI_NAMESPACE::vector>*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Prog::ComputeHints\28std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20int\2c\20int\29,opa_abort +re2::Prog::ComputeHints\28std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20int\2c\20int\29,re2::Prog::ComputeHints\28std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20int\2c\20int\29::$_0::operator\28\29\28int\2c\20int\29\20const +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int&&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int&&\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int&&\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int\20const&\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int\20const&\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int\20const&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int\20const&\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::push_back\5babi:nn210108\5d\28int\20const&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::Prog::ComputeHints\28std::_LIBCPP_ABI_NAMESPACE::vector>*\2c\20int\2c\20int\29::$_0::operator\28\29\28int\2c\20int\29\20const,opa_abort re2::Prog::PrefixAccel_FrontAndBack\28void\20const*\2c\20unsigned\20long\29,opa_abort re2::Prog::PrefixAccel_FrontAndBack\28void\20const*\2c\20unsigned\20long\29,memchr -bool\20std::__1::__insertion_sort_incomplete::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29,unsigned\20int\20std::__1::__sort4::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 -re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,std::__1::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 -re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,std::__1::basic_string\2c\20std::__1::allocator\20>::assign\28char\20const*\2c\20unsigned\20long\29 +bool\20std::_LIBCPP_ABI_NAMESPACE::__insertion_sort_incomplete\5babi:nn210108\5d::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29,void\20std::_LIBCPP_ABI_NAMESPACE::__sort5\5babi:nn210108\5d::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\2c\20re2::SparseArray::IndexValue*\2c\200>\28re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20re2::SparseArray::IndexValue*\2c\20bool\20\28*&\29\28re2::SparseArray::IndexValue\20const&\2c\20re2::SparseArray::IndexValue\20const&\29\29 +re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,std::_LIBCPP_ABI_NAMESPACE::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 +re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::assign\28char\20const*\2c\20unsigned\20long\29 re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::Regexp::Parse\28re2::StringPiece\20const&\2c\20re2::Regexp::ParseFlags\2c\20re2::RegexpStatus*\29 re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,operator\20new\28unsigned\20long\29 re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::RegexpStatus::Text\28\29\20const -re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,memcpy -re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,operator\20delete\28void*\29 -re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::Regexp::RequiredPrefix\28std::__1::basic_string\2c\20std::__1::allocator\20>*\2c\20bool*\2c\20re2::Regexp**\29 +re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,memmove +re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::Regexp::RequiredPrefix\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\2c\20bool*\2c\20re2::Regexp**\29 re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::Regexp::Incref\28\29 re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::Regexp::CompileToProg\28long\20long\29 re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::Regexp::NumCaptures\28\29 re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::Prog::IsOnePass\28\29 -re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,abort -void\20std::__1::__call_once_proxy\20>\28void*\29,operator\20new\28unsigned\20long\29 +re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,operator\20new\28unsigned\20long\29 re2::RE2::RE2\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29,re2::RE2::Init\28re2::StringPiece\20const&\2c\20re2::RE2::Options\20const&\29 -re2::RE2::ReverseProg\28\29\20const,std::__1::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,re2::Regexp::CompileToReverseProg\28long\20long\29 +re2::RE2::ReverseProg\28\29\20const,std::_LIBCPP_ABI_NAMESPACE::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,re2::Regexp::CompileToReverseProg\28long\20long\29 re2::RE2::~RE2\28\29,re2::Regexp::Decref\28\29 re2::RE2::~RE2\28\29,re2::Prog::~Prog\28\29 -re2::RE2::~RE2\28\29,operator\20delete\28void*\29 -re2::RE2::~RE2\28\29,std::__1::__tree\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\2c\20std::__1::__value_type\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::less\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20int>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\2c\20int>\2c\20void*>*\29 -re2::RE2::~RE2\28\29,std::__1::__tree\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\20>\2c\20std::__1::less\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\20>\2c\20void*>*\29 -std::__1::__tree\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\2c\20std::__1::__value_type\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::less\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20int>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\2c\20int>\2c\20void*>*\29,std::__1::__tree\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\2c\20std::__1::__value_type\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::less\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20int>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\2c\20int>\2c\20void*>*\29 -std::__1::__tree\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\2c\20std::__1::__value_type\2c\20std::__1::allocator\20>\2c\20int>\2c\20std::__1::less\2c\20std::__1::allocator\20>\20>\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\2c\20int>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\2c\20int>\2c\20void*>*\29,operator\20delete\28void*\29 -std::__1::__tree\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\20>\2c\20std::__1::less\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\20>\2c\20void*>*\29,std::__1::__tree\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\20>\2c\20std::__1::less\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\20>\2c\20void*>*\29 -std::__1::__tree\2c\20std::__1::allocator\20>\20>\2c\20std::__1::__map_value_compare\2c\20std::__1::allocator\20>\20>\2c\20std::__1::less\2c\20true>\2c\20std::__1::allocator\2c\20std::__1::allocator\20>\20>\20>\20>::destroy\28std::__1::__tree_node\2c\20std::__1::allocator\20>\20>\2c\20void*>*\29,operator\20delete\28void*\29 +re2::RE2::~RE2\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::RE2::~RE2\28\29,std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20void*>*\29 +re2::RE2::~RE2\28\29,std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*\29 +std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20void*>*\29,std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20void*>*\29 +std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20std::_LIBCPP_ABI_NAMESPACE::pair\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\20const\2c\20int>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>\2c\20int>\2c\20void*>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*\29,std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*\29 +std::_LIBCPP_ABI_NAMESPACE::__tree\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::__map_value_compare\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20std::_LIBCPP_ABI_NAMESPACE::less\2c\20true>\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>>>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>\2c\20void*>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::RE2::DoMatch\28re2::StringPiece\20const&\2c\20re2::RE2::Anchor\2c\20unsigned\20long*\2c\20re2::RE2::Arg\20const*\20const*\2c\20int\29\20const,memset re2::RE2::DoMatch\28re2::StringPiece\20const&\2c\20re2::RE2::Anchor\2c\20unsigned\20long*\2c\20re2::RE2::Arg\20const*\20const*\2c\20int\29\20const,operator\20new\5b\5d\28unsigned\20long\29 re2::RE2::DoMatch\28re2::StringPiece\20const&\2c\20re2::RE2::Anchor\2c\20unsigned\20long*\2c\20re2::RE2::Arg\20const*\20const*\2c\20int\29\20const,re2::RE2::Match\28re2::StringPiece\20const&\2c\20unsigned\20long\2c\20unsigned\20long\2c\20re2::RE2::Anchor\2c\20re2::StringPiece*\2c\20int\29\20const @@ -2286,20 +2366,20 @@ re2::RE2::Match\28re2::StringPiece\20const&\2c\20unsigned\20long\2c\20unsigned\2 re2::RE2::Match\28re2::StringPiece\20const&\2c\20unsigned\20long\2c\20unsigned\20long\2c\20re2::RE2::Anchor\2c\20re2::StringPiece*\2c\20int\29\20const,re2::Prog::SearchNFA\28re2::StringPiece\20const&\2c\20re2::StringPiece\20const&\2c\20re2::Prog::Anchor\2c\20re2::Prog::MatchKind\2c\20re2::StringPiece*\2c\20int\29 re2::RE2::Match\28re2::StringPiece\20const&\2c\20unsigned\20long\2c\20unsigned\20long\2c\20re2::RE2::Anchor\2c\20re2::StringPiece*\2c\20int\29\20const,memset re2::RE2::PartialMatchN\28re2::StringPiece\20const&\2c\20re2::RE2\20const&\2c\20re2::RE2::Arg\20const*\20const*\2c\20int\29,re2::RE2::DoMatch\28re2::StringPiece\20const&\2c\20re2::RE2::Anchor\2c\20unsigned\20long*\2c\20re2::RE2::Arg\20const*\20const*\2c\20int\29\20const -re2::Regexp::~Regexp\28\29,operator\20delete\28void*\29 +re2::Regexp::~Regexp\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::~Regexp\28\29,operator\20delete\5b\5d\28void*\29 -re2::Regexp::~Regexp\28\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::Regexp::Incref\28\29,std::__1::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 +re2::Regexp::~Regexp\28\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::Regexp::Incref\28\29,std::_LIBCPP_ABI_NAMESPACE::__call_once\28unsigned\20long\20volatile&\2c\20void*\2c\20void\20\28*\29\28void*\29\29 re2::Regexp::Incref\28\29,operator\20new\28unsigned\20long\29 -re2::Regexp::Incref\28\29,void\20std::__1::__tree_balance_after_insert*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 -void\20std::__1::__call_once_proxy\20>\28void*\29,operator\20new\28unsigned\20long\29 +re2::Regexp::Incref\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_balance_after_insert\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__call_once_proxy\5babi:nn210108\5d>\28void*\29,operator\20new\28unsigned\20long\29 re2::Regexp::Decref\28\29,operator\20new\28unsigned\20long\29 -re2::Regexp::Decref\28\29,void\20std::__1::__tree_balance_after_insert*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 -re2::Regexp::Decref\28\29,void\20std::__1::__tree_remove*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 -re2::Regexp::Decref\28\29,operator\20delete\28void*\29 +re2::Regexp::Decref\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_balance_after_insert\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 re2::Regexp::Decref\28\29,re2::Regexp::Destroy\28\29 +re2::Regexp::Decref\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_remove\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 +re2::Regexp::Decref\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::Destroy\28\29,re2::Regexp::~Regexp\28\29 -re2::Regexp::Destroy\28\29,operator\20delete\28void*\29 +re2::Regexp::Destroy\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::Destroy\28\29,re2::Regexp::Decref\28\29 re2::Regexp::Destroy\28\29,operator\20delete\5b\5d\28void*\29 re2::Regexp::AddRuneToString\28int\29,opa_abort @@ -2317,8 +2397,8 @@ re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20 re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29,operator\20new\5b\5d\28unsigned\20long\29 re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29,re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29 re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29,opa_abort -re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29,operator\20delete\28void*\29 -re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29,abort +re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::Concat\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29 re2::Regexp::AlternateNoFactor\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29 re2::Regexp::Capture\28re2::Regexp*\2c\20re2::Regexp::ParseFlags\2c\20int\29,operator\20new\28unsigned\20long\29 @@ -2329,74 +2409,80 @@ re2::Regexp::NewCharClass\28re2::CharClass*\2c\20re2::Regexp::ParseFlags\29,oper re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,re2::TopEqual\28re2::Regexp*\2c\20re2::Regexp*\29 re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,operator\20new\28unsigned\20long\29 re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,memcpy -re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,operator\20delete\28void*\29 +re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,opa_abort -re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,std::__1::vector\20>::__append\28unsigned\20long\29 -re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,abort +re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__append\28unsigned\20long\29 +re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 re2::TopEqual\28re2::Regexp*\2c\20re2::Regexp*\29,memcmp -std::__1::vector\20>::__append\28unsigned\20long\29,memset -std::__1::vector\20>::__append\28unsigned\20long\29,operator\20new\28unsigned\20long\29 -std::__1::vector\20>::__append\28unsigned\20long\29,memcpy -std::__1::vector\20>::__append\28unsigned\20long\29,operator\20delete\28void*\29 -std::__1::vector\20>::__append\28unsigned\20long\29,abort +std::_LIBCPP_ABI_NAMESPACE::vector>::__append\28unsigned\20long\29,memset +std::_LIBCPP_ABI_NAMESPACE::vector>::__append\28unsigned\20long\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__append\28unsigned\20long\29,memcpy +std::_LIBCPP_ABI_NAMESPACE::vector>::__append\28unsigned\20long\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__append\28unsigned\20long\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__append\28unsigned\20long\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 re2::RegexpStatus::Text\28\29\20const,strlen re2::RegexpStatus::Text\28\29\20const,operator\20new\28unsigned\20long\29 -re2::RegexpStatus::Text\28\29\20const,memcpy -re2::RegexpStatus::Text\28\29\20const,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\2c\20unsigned\20long\29 -re2::RegexpStatus::Text\28\29\20const,operator\20delete\28void*\29 -re2::RegexpStatus::Text\28\29\20const,std::__1::basic_string\2c\20std::__1::allocator\20>::append\28char\20const*\29 -re2::RegexpStatus::Text\28\29\20const,abort +re2::RegexpStatus::Text\28\29\20const,memmove +re2::RegexpStatus::Text\28\29\20const,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\2c\20unsigned\20long\29 +re2::RegexpStatus::Text\28\29\20const,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::RegexpStatus::Text\28\29\20const,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::append\28char\20const*\29 +re2::RegexpStatus::Text\28\29\20const,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::__throw_length_error\5babi:nn210108\5d\28\29 re2::Regexp::NumCaptures\28\29,re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20int\2c\20bool\29 re2::Regexp::NumCaptures\28\29,re2::Regexp::Walker::~Walker\28\29 -re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,std::__1::basic_string\2c\20std::__1::allocator\20>::resize\28unsigned\20long\2c\20char\29 -re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,runetochar -re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,operator\20new\28unsigned\20long\29 -re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,memcpy -re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29,operator\20delete\28void*\29 -re2::Regexp::RequiredPrefix\28std::__1::basic_string\2c\20std::__1::allocator\20>*\2c\20bool*\2c\20re2::Regexp**\29,re2::Regexp::Incref\28\29 -re2::Regexp::RequiredPrefix\28std::__1::basic_string\2c\20std::__1::allocator\20>*\2c\20bool*\2c\20re2::Regexp**\29,re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29 -re2::Regexp::RequiredPrefix\28std::__1::basic_string\2c\20std::__1::allocator\20>*\2c\20bool*\2c\20re2::Regexp**\29,operator\20new\28unsigned\20long\29 -re2::Regexp::RequiredPrefix\28std::__1::basic_string\2c\20std::__1::allocator\20>*\2c\20bool*\2c\20re2::Regexp**\29,re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29 -re2::Regexp::RequiredPrefixForAccel\28std::__1::basic_string\2c\20std::__1::allocator\20>*\2c\20bool*\29,re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::__1::basic_string\2c\20std::__1::allocator\20>*\29 -re2::CharClassBuilder::AddRange\28int\2c\20int\29,void\20std::__1::__tree_remove*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 -re2::CharClassBuilder::AddRange\28int\2c\20int\29,operator\20delete\28void*\29 +re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>::resize\28unsigned\20long\2c\20char\29 +re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,runetochar +re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,memmove +re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29,operator\20new\28unsigned\20long\29 +re2::Regexp::RequiredPrefix\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\2c\20bool*\2c\20re2::Regexp**\29,re2::Regexp::Incref\28\29 +re2::Regexp::RequiredPrefix\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\2c\20bool*\2c\20re2::Regexp**\29,re2::Regexp::ConcatOrAlternate\28re2::RegexpOp\2c\20re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\2c\20bool\29 +re2::Regexp::RequiredPrefix\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\2c\20bool*\2c\20re2::Regexp**\29,operator\20new\28unsigned\20long\29 +re2::Regexp::RequiredPrefix\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\2c\20bool*\2c\20re2::Regexp**\29,re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29 +re2::Regexp::RequiredPrefixForAccel\28std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\2c\20bool*\29,re2::ConvertRunesToBytes\28bool\2c\20int*\2c\20int\2c\20std::_LIBCPP_ABI_NAMESPACE::basic_string\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>*\29 +re2::CharClassBuilder::AddRange\28int\2c\20int\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_remove\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 +re2::CharClassBuilder::AddRange\28int\2c\20int\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::CharClassBuilder::AddRange\28int\2c\20int\29,operator\20new\28unsigned\20long\29 -re2::CharClassBuilder::AddRange\28int\2c\20int\29,void\20std::__1::__tree_balance_after_insert*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 +re2::CharClassBuilder::AddRange\28int\2c\20int\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_balance_after_insert\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 re2::CharClassBuilder::AddCharClass\28re2::CharClassBuilder*\29,re2::CharClassBuilder::AddRange\28int\2c\20int\29 -re2::CharClassBuilder::RemoveAbove\28int\29,void\20std::__1::__tree_remove*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 -re2::CharClassBuilder::RemoveAbove\28int\29,operator\20delete\28void*\29 +re2::CharClassBuilder::RemoveAbove\28int\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_remove\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 +re2::CharClassBuilder::RemoveAbove\28int\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::CharClassBuilder::RemoveAbove\28int\29,operator\20new\28unsigned\20long\29 -re2::CharClassBuilder::RemoveAbove\28int\29,void\20std::__1::__tree_balance_after_insert*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 +re2::CharClassBuilder::RemoveAbove\28int\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_balance_after_insert\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 re2::CharClassBuilder::Negate\28\29,operator\20new\28unsigned\20long\29 re2::CharClassBuilder::Negate\28\29,memcpy -re2::CharClassBuilder::Negate\28\29,operator\20delete\28void*\29 -re2::CharClassBuilder::Negate\28\29,std::__1::__tree\20>::destroy\28std::__1::__tree_node*\29 -re2::CharClassBuilder::Negate\28\29,void\20std::__1::__tree_balance_after_insert*>\28std::__1::__tree_node_base*\2c\20std::__1::__tree_node_base*\29 -re2::CharClassBuilder::Negate\28\29,abort +re2::CharClassBuilder::Negate\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::CharClassBuilder::Negate\28\29,std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29 +re2::CharClassBuilder::Negate\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::CharClassBuilder::Negate\28\29,std::_LIBCPP_ABI_NAMESPACE::__tree>::destroy\28std::_LIBCPP_ABI_NAMESPACE::__tree_node*\29 +re2::CharClassBuilder::Negate\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__tree_balance_after_insert\5babi:nn210108\5d*>\28std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\2c\20std::_LIBCPP_ABI_NAMESPACE::__tree_node_base*\29 +std::_LIBCPP_ABI_NAMESPACE::vector>::__throw_length_error\5babi:nn210108\5d\28\29,std::_LIBCPP_ABI_NAMESPACE::__throw_length_error\5babi:nn210108\5d\28char\20const*\29 re2::CharClassBuilder::GetCharClass\28\29,operator\20new\5b\5d\28unsigned\20long\29 re2::CharClassBuilder::GetCharClass\28\29,opa_abort re2::NumCapturesWalker::~NumCapturesWalker\28\29,re2::Regexp::Walker::~Walker\28\29 -re2::NumCapturesWalker::~NumCapturesWalker\28\29,operator\20delete\28void*\29 +re2::NumCapturesWalker::~NumCapturesWalker\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::Regexp::Simplify\28\29,re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool\29 re2::Regexp::Simplify\28\29,re2::Regexp::Decref\28\29 re2::Regexp::Simplify\28\29,re2::Regexp::Walker::~Walker\28\29 re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool\29,operator\20delete\5b\5d\28void*\29 -re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool\29,operator\20delete\28void*\29 -re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool\29,std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29 +re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool\29,std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29 re2::Regexp::Walker::WalkInternal\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool\29,operator\20new\5b\5d\28unsigned\20long\29 re2::Regexp::Walker::~Walker\28\29,operator\20delete\5b\5d\28void*\29 -re2::Regexp::Walker::~Walker\28\29,operator\20delete\28void*\29 -re2::Regexp::Walker::~Walker\28\29,std::__1::__deque_base\2c\20std::__1::allocator\20>\20>::~__deque_base\28\29 +re2::Regexp::Walker::~Walker\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +re2::Regexp::Walker::~Walker\28\29,std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::~deque\5babi:nn210108\5d\28\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::~deque\5babi:nn210108\5d\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::CoalesceWalker::Copy\28re2::Regexp*\29,re2::Regexp::Incref\28\29 re2::CoalesceWalker::ShortVisit\28re2::Regexp*\2c\20re2::Regexp*\29,re2::Regexp::Incref\28\29 re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::Regexp::Incref\28\29 re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::CoalesceWalker::CanCoalesce\28re2::Regexp*\2c\20re2::Regexp*\29 re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::Regexp::Decref\28\29 -re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::CoalesceWalker::DoCoalesce\28re2::Regexp**\2c\20re2::Regexp**\29 re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,operator\20new\28unsigned\20long\29 re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 -re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,opa_abort re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,operator\20new\5b\5d\28unsigned\20long\29 +re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::CoalesceWalker::DoCoalesce\28re2::Regexp**\2c\20re2::Regexp**\29 +re2::CoalesceWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,opa_abort re2::CoalesceWalker::CanCoalesce\28re2::Regexp*\2c\20re2::Regexp*\29,re2::Regexp::Equal\28re2::Regexp*\2c\20re2::Regexp*\29 re2::CoalesceWalker::DoCoalesce\28re2::Regexp**\2c\20re2::Regexp**\29,re2::Regexp::Incref\28\29 re2::CoalesceWalker::DoCoalesce\28re2::Regexp**\2c\20re2::Regexp**\29,re2::Regexp::Repeat\28re2::Regexp*\2c\20re2::Regexp::ParseFlags\2c\20int\2c\20int\29 @@ -2410,52 +2496,51 @@ re2::SimplifyWalker::ShortVisit\28re2::Regexp*\2c\20re2::Regexp*\29,re2::Regexp: re2::SimplifyWalker::PreVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20bool*\29,re2::Regexp::Incref\28\29 re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::Regexp::Decref\28\29 re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::Regexp::Incref\28\29 -re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29 -re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29 re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,operator\20new\28unsigned\20long\29 re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 -re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,opa_abort re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,operator\20new\5b\5d\28unsigned\20long\29 -re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,opa_abort -re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,operator\20new\28unsigned\20long\29 -re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 -re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,re2::Regexp::Incref\28\29 +re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,opa_abort +re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29 +re2::SimplifyWalker::PostVisit\28re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp*\2c\20re2::Regexp**\2c\20int\29,re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::Incref\28\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::Star\28re2::Regexp*\2c\20re2::Regexp::ParseFlags\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::Plus\28re2::Regexp*\2c\20re2::Regexp::ParseFlags\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,operator\20new\28unsigned\20long\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::Concat\28re2::Regexp**\2c\20int\2c\20re2::Regexp::ParseFlags\29 -re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,operator\20delete\28void*\29 +re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,re2::Regexp::Quest\28re2::Regexp*\2c\20re2::Regexp::ParseFlags\29 re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,operator\20new\5b\5d\28unsigned\20long\29 -re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,abort +re2::SimplifyWalker::SimplifyRepeat\28re2::Regexp*\2c\20int\2c\20int\2c\20re2::Regexp::ParseFlags\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,opa_abort +re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,operator\20new\28unsigned\20long\29 +re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,re2::Regexp::Regexp\28re2::RegexpOp\2c\20re2::Regexp::ParseFlags\29 +re2::SimplifyWalker::SimplifyCharClass\28re2::Regexp*\29,re2::Regexp::Incref\28\29 re2::CoalesceWalker::~CoalesceWalker\28\29,re2::Regexp::Walker::~Walker\28\29 -re2::CoalesceWalker::~CoalesceWalker\28\29,operator\20delete\28void*\29 +re2::CoalesceWalker::~CoalesceWalker\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 re2::SimplifyWalker::~SimplifyWalker\28\29,re2::Regexp::Walker::~Walker\28\29 -re2::SimplifyWalker::~SimplifyWalker\28\29,operator\20delete\28void*\29 -std::__1::__deque_base\2c\20std::__1::allocator\20>\20>::~__deque_base\28\29,operator\20delete\28void*\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,memmove -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,operator\20delete\28void*\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29 -std::__1::deque\2c\20std::__1::allocator\20>\20>::__add_back_capacity\28\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_back\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>\20>::push_front\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_back\28re2::WalkState*&&\29,abort -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,memmove -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,operator\20new\28unsigned\20long\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,operator\20delete\28void*\29 -std::__1::__split_buffer*\2c\20std::__1::allocator*>&>::push_front\28re2::WalkState*\20const&\29,abort +re2::SimplifyWalker::~SimplifyWalker\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,operator\20new\28unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,operator\20delete\28void*\2c\20unsigned\20long\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29 +std::_LIBCPP_ABI_NAMESPACE::deque\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator>>::__add_back_capacity\28\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*&>\28re2::WalkState*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_back*>\28re2::WalkState*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>&>::emplace_front*&>\28re2::WalkState*&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,memmove +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,operator\20new\28unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,operator\20delete\28void*\2c\20unsigned\20long\29 +void\20std::_LIBCPP_ABI_NAMESPACE::__split_buffer*\2c\20std::_LIBCPP_ABI_NAMESPACE::allocator*>>::emplace_front*>\28re2::WalkState*&&\29,std::__throw_bad_array_new_length\5babi:nn210108\5d\28\29 +re2::StringPiece::find\28char\2c\20unsigned\20long\29\20const,memchr diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/opa/opa.wasm index 667b9cdd4902ae7d186d5007302013358862ffb6..a294543e8823f45b8ce4ecfd1387e7a9c8b41663 100644 GIT binary patch literal 431796 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

n!#ag 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�iTFn-Um*77s1ozqWTFN^jtoM$IylM+Lg6;!>?C3 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 y{5 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%0AG7XjUKdX?B3 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

ZF$B3P&H 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%0Adw^Bb2T(@q% z%-3W7{Uff&L|k~lxqJ~!P^DJq$P`5c6jL)@wbW?rUshyYU7zsi;N53PHUD#en`(f zwP@PobTDGa4AIB-vFYOw&21p3rVQV?izRiui)Az%4&4quSEQ7MTxr4}nFS3y`V2iQ zwx!Dq-0OaKHUbx1k|{wRTjgJ$~}K~}AC zH6z_j8#cYzdbnOu{Gm3gfRBmacsQB;7 z)#a;&iqOe&!6geQ{BEfH7Ey#G3syBCr&Dwra@e4W#thv~>n}C(6z*`UCl7`k0(qGW zO>x(FcYVdFqb~_uE+^M5lRyKg`3qAW-{dUzun?8UQKNRXS;7PY~)wZSeZYl|HYxV6Q;svJ$$ zNw0(y9zUgzzz5l3K`C}_wS&Go!9_+};KN{b`se@`i=2^Izqa|#vp9%POde%Q5tL~8 z%W1X9-oHCs9Hf0KW;YuHZy5MNxD6NLpg_^|0W%;6ERoj8EJ8a zo5W7keHYK&Y4~#q=chaj;F0>cMi;QOt9-z#vZEx&D?jKdpO2We(0!;gM&N&ASOJ^* z&xd!ggz|brC~E`Xn|}-&a`S%iXI%Z1a}QBQ`3F$&ddg=|jS*dyrMHWEw3mnSM4kvs zeF|mlXCo5R_s;tFns54GIt1mUP|?B-9?CjZH%evGnnf5%$CX-pIVUvGHW6iwHAIG0 zhy;ER=~s8X^Qmds{R+%YG!+X84;bBEe8^dW47}x*#Oo~_!kQce|GS@r6DB-66dXAhq!@+^;4t zGF)8P_A^`M9yR!9g{scGP}TAQ0C!8h3+sKu6XmJRlg_s@oc&qZ0#=VHZrFe)=mHH> zI!@6sie$;mJ}Y4(C1;cOW5*4i={z0yin~wO>g9H_wjs&nE3^UpVuSj4ISKh!?_gie z^Xm1CVm&B)eFz*84bGt}ITz_HT)xzTnth-_!(wnlb3ad-%U{!3G^)L!VkFrkVAlgg z>86)6EIZR13f(q6mWAn!pepdr#?zBxvqZW$jRyzL0cVoyz%^thW|U+RiU#?ifH?35 zoCM*lGsarP5!*u~OJ}5Lh$Pl#)DZ|u+$&-+8>G&L^v_SIP`DWb0=5jHyg>SJ6HqgoKShWa zV5gaDUYEF&bis$Umpblp%JHZ_XG{EKTCMW|^G_I>(*m;Y4tv=FW^e`RV8PX$a58*} zc-Y2Z&YA2u^_ev3$?y=#i1s3q;QgO$|$)n zUMPxnggB{_`%fQ;1*0Dczir>E8xK(08jmh@aAUOih-;RwL@#|$etcFm1F~O^2(SjP z+=jIUuYyZBbPFkC#lGMOuz(1vjoe}LA7IgM0vP81aI}T4hz8+)F5V-)Q+$pU@6nKT zA5}%p`+(5>HK;IXcmD{w@?VBM(3Isbj-jg+UJ;|_TzZ^?k?!pk0W&=ag&18jvA&nC zZrdD~q|b}y&k8v54b?K83~q0mEYoB7G`!QZz@EQyu{}Z#pIPN{BUAP0x1l9Z5kV&r zJ!tHaN9%{N^~O)godLOW#%gf#NbLFzdmh81`}f>-Fs|fU^&aWqy$AjKtNy;a`HkCZ zjPl&Sf7ss-cfZH$Wg-Ikz_phY;PMMpcC>o+D0Kb0kPOjdhua}TuKWz`vuu%!KWIN= z{M6jUS-o>z@oVFyQJMV;dgJ1}HhZL6h;{x{e`tZBEJ z6A**nNxhcEQg@hcuww#Z@Vm#3x`uOu9TO0P_dRw@#SX7}06W-dYpPy{9c+|}9can0 znZk~!exnL>3SS6^P%~4ha7aNA)ii2t5abnx@e0Fug<)`1VMzuR1j2^oUtt*GBl`^F z?;ef43;MLPm_9w|EvEQwG=@;_bd<%^8LF_sZb=usCVB#+my5yH1C$ypnimWW);4^0 zHSSzgnqBHW?YGCe;<208k(l|1H1~KIf1MAP^ADA=hbbJ>-M(W=<(jVYCgFgimbMjY zmM?P+N`{FqVsj1#hp>fKV~>X5aU*lT?z3j`<6kUTo`=G)cwaQ4jEtLh=&UcJ2J zm<_~F4`Wc+ybv5JA9E2P?0G?FxT?c%U3NQSo~ml zAALZ?bvvS@JM-$<*r_as%h_}5r8@-ZNC+(;p4cd!E2%dx>kWl+o}ylQ#!0_IR>;GU zmzSn5y>@EsNplKSuglYC_@CL2z=8+M*N6_q1%uUhTp3;8IZR9hbN{mS?PlQ_M~@vC zXW6Uo*YG59aqJ(US~8k!>x=?ECYa@Dj-dVJ(4b&IloGip8VJ=$8!~_w!vN}wF<3gn z@uHI`I5*?wwNN5oBt}qgjMtG-(%lI+m2c%3B-B+%3rN~LCIpQC1Z*^2p(6*XSXn7o;lbSb=qF|9D*-}Fo1yFwtaL2b~ zL<&&PZqSrR9_ZZePns`}Qs^Ik-#L{?nBKcpUU<#$)g5R1NjTfE-bidr4F(e}T;kW` zmV9l1fSX{MWb9~;Rg1*ldT)o5^*{KmH*D59#Yvp2jUTM0A0?ZMLqGWFf1N6iTZO7Q znQ@CRut%QU645{k{^X!SP9A*1V}+)})#$C4SgJ!ns@|Xwr=zae^K!%H# z_Cbc5wM_qtm~X~*bM!bT7U@FJ+@u7TptycIxU(wL_i(p@;g9wRkCA##XHrE9(U9?yUeoSTg&8 z(BPKYivz}&_||=2;@8p^Y%#ZNkTl?7Xi;iWj+7pvn!F5WbV6pt;0DOstt;Fxk#r0X zueRIHR$D#jQmjB3MbZ(HavT9hDIBgcqiT-d2sF4bU+DPt)W|#@UlDFO-$SgFD4pQ( z?B}p{EF%TmJRVuLZY_B;8yOU7Xfcn+FSIixFV)?km|MoK%6gPjG6ZPel43H3mqJhU z19mR1+7}zyU|h9yVVL95dhzUX@eGUq!r&S3{1WW>I!eO>;^2Jw0NkpH*No<(HbM<3 zK&VIIQYbCm1rkTu@AGP=&*}35qzuf>-I4homfXA!UNcCdH-rX#=1d-H-eY&xkFmHY z99Ai%oD+|KWmNRW9yVXt!(t0N!&9QwRwfAS9qx z56T3D6BvRc_(90Ji>5fuwpjocAvo>tiscx_IMSi&0UUtpLhBYrY zBIZjvSAqpDnrjA>5CP_9)HM1pZ0uMdqu;>pg&F`ufTNhbcKkFnh$b-l=qc+d41Lyon}=<*OoC&orJj3-P8WIkUGw40 zZMG5fPU<4zKU-x#hBM)}mz)Z~8|)52(pI4y-X@472c3Cp&E*W2hH!(N^~yf~UIXf; zNjGo^+E=ItzsLHEu4Kkg}Yr+#~>i`k6IINnL*3 zcG|W<1w^hNnb2`RxHfq{j#xh;<)aeuit=!K$lH<>~$9gz%a>KNMK`TBW%b3^QIFTQ7-jGiB`1$=nNMtD6%mKpvytHcMPHXTH$ zB*5;VaYf_{JMk)_qdyNh(;TWPu#nE z7Xj-JJQDdaYc`dQ zLSe^K$PoXd)0@l}i$CTNmlGOJEDvKjsQOqa{2+7*_XUQD1Lf}l=*`Y0V8@trajU*t z>$IDVSE9qHL=^-Co-;bCc1R}cw8mYI&%C?pGNi#pH5FTj3g|dA0Tl`@+8KxWFGpWF z9GSFm$*l6C76&DE{@tVK25VsXxBtjD-ZcwK2L7$Tc#riSt@BB{C+}gXT6Xj@f)`Ni zIqr<*ak(uImV>XBfr=d{7LH;{cp-W)BL;L(GUrsU6ZC9LaX^_HmM4t)t7W|4P`q_w z4~+;}q_Xb{ZR=m=mL?!N$~f9vm&ViKSk4`P;MbW?AwQRcTbVMFnng||%^=H-+BwWC z@PDgBOcOj5|3d}HZ52AB^}+mqtbiTIQTz{>#yvk={I3#WxLi*+`g;ET=LUBgz7zIP z1hpD1J}UM+v>bzArTf|yj2@L&_|m+XRjw*pA&Df*O;83+q91=OwSialYHC-o7D%fu zkJfh=HKw)Py6bd3q@v@{D#F$VXGN|GwE>*o*|L$Asq=~2(6oV2Dp-14~K~Nxf3&Vuy1IIN(kmDiz zzH(^H4!nRpgb`~iQiQ<+rNVw$LrRDm!^QWD8WOl^OZg{}IJ?3_t_Q=>G6q_+;^-44 z8PjJl&U{iV7%FA)!!MR2`LXkqXS|`}OvAOsGRB5T>CCh&kE@RqWD;@$K=3sh(WCia z9S#pQMPLYF5vDCeAIKAg2^?Smzf9V%>H6#L@Y6*`y@`QB_qw}ar-1F^~vjDp!e)xgoSyp&zr97%{#^}1>> z>nY3{Js#DLI^+3-!Op*Z0=~CcS@MNWZ}i73YSmiS%Jn}!#1jB;>XYRnv6lRCxc(=H z$*~pWgWO#LaI8bVDA8#u_)#}UiwavPJ1UgjueB6wxj4CFJ%?*kl#0WMo9jh=Mq0VX z2XZ4w9(%@WtY$+*uth|S;3-55cM2jJ!y}-Q3bjO&40?lzp6P;NZzE!7wI1|{$f5aJ zokTeh5z&&_D9=b5B0?I5^e{-zfxz>lIP-~c0RKmV540grVSNLcUDEsETXp_lIo`hc zLFn81g?s;{Sy`v+PyWC6B$!$7k8PR*R%bn2{IL9vrY~F(s&R1lg|NiP;muD61}1J& zolfT8dJMuh?BEd2q{9x`Xh5gdGL``7Y{p`E_z=Y7*Htd0Tpg`HGW?xH2Y{CV8ehvX z58iWoeeFH`zPhT5GDP9Q9o$Aq8okf9D363Duz7}Z zj;Oq~{^|Gwyz-qcn~$M@k;sRWbfnRI2tgc53p8B1s~Qa^60@sqNu*fK68FJQe}~s8 zQ^=FVdq<0(6QUV#+V=!zCNWjjISd#Wa)H4se>*VHFiS{?fOsrbKVMr(!R0h~jY+M* zpKH*yO;S|2+zO=A@O0Dgbh}|@Q#ZkPrY*|N`gwVI8eZlM7b$(2F=6mxBf{VfgNJ#| znC*&=?CVOH0t!{rh}?@~6kVwan{ln^?8^T{S!5EkK?*!NxD3}gaEh#9n<;=h183=V z3K6YFE!nS=Ul7Zth+#D$jAs`=s5_2FO)8~0!!*HCBRRgUDC~(LFfIvP4e+wLoE_HB#bTy-~%}S9`>7Q6Lr%Z)w z$OGgKtq?iSXm}J9oZ-5<0IR5A5mbbik63~#;{%Dd*S{fFf(v`Z!mwjp8Ci!|u4=!S z4%E?JWesY+Cs%%d)>OS$t{3_`WEF+|PA2-+Zm2jY+vdv((G*U&b5uL6$!-y@iO*^H zMF|%ryAvrpLpHq7O>1~z3{WmSx&=_~J2;0H`)|6<3$2gD7jh~y z6e`mkrKabFIQPsxv&{?fyQ7S6^Fnly7X_(m(HZt^^nw9QaPb%JL3bqI`x2&+`xzvj ziwFSO|LxMqeIzmnB@THhUj~X8rEorNs)iFIH6LE6`vf|5es8jhpJqTEUfyQTYqo2j zf3FJ-Yqd4;x%m~EGlD7py`eUFXGOd^g_?3vP?t=iNJgK;%T7x=Ibyu8Px?IreI1x| zUyB{sCN^Bp^-X7|;%o1$rmZM3>gpc{h% zt!3GoBzm2dhlBQK)INuRBMzDqp`z{uN+6NqM&Jd*QaER3-)$ec^zvAm^5k7ER@EH-t`4CjD(%x|21fiGel}(4l zsHT&0pnwNLu(b`I#Ai}s(GdjFb${yh6RbFaQjyH;Y zg3a35j%HEzTWBN(kWtrBV}5%J#QA16+r3`?*R6 zhG4`k4^Z`&5V6SDZE?cP{==rsyNpJnju0VK#SC>QFhRiXv%hPi7!E)wu95~NQTJ2u|jP0~p?Q}^_Y1c48 zmr9>bez z2-Yf_FORTq@$S%Z@2AjApxU;1*vY8ykXjHJJAG^xB(942y)C;N%W6~#1_(AT7BhZg zguD{{CTsFu>wbaLjYi|-1Rk%w`a>L-sFsa{AV2`B(c+ZRxk_8R&LqwTQDp{eTp=AC z0JD9>T3)u3*_~C>JpFYm+;X7l3HGFRRl|_L;EpW;m~!To!&&{IId&8}RVJP|hMz$W z;?#A4nGsUjQGBT-V`h+rbTwO9ggY*34RNIFH^c3*dHYMSRGwjMt;kjed z*mc=OEY7QGLQlisa)|#?A=YM8tRpZu`!3X?En%pB-GCco$~{TiaB7Sp^*Zx%vu28b1E?q z@0d9;t6*kE&6-nP10>5O)|ehJNmymN$5cBdTdCpLlhtK6Tuo4THUtQ?PhwLFhU7A~ z#BiV0-D;_hGMCU9B77>~lh#^W=xRCx{4X9f)zXF;u=UpLnDp{|KS3V-NpT^1+*;T6 zclh%R(MidSsS&18a;6y8n?Fx##`e=JY#dnUBO z!xP5$b*yfeq~FL;6DW%E%54q>I&)5p@}VanUeW<`=65Z7Tl~SL$ry$JPG&7#3MM^U z{1u6 zfQle|ykEgIo{M2a#Dy%H5xd5eKuX}BR?*ZxEI^+0HWZTq`e8JzMcN1yW@ij1%#62P z>G8V15okXD{TsE~J_tFht|ox(YtVMxcw7IK5B}jFGYwgW7_T56))c_qNkSbw6$gYc z{Fud1T=}@sM=-=0-#4Kz>f!fv3NXtHuYTB5GR39{`(&O{bYdVwC=y>WE8TV!Mk_vo zX+bCK@uPV`2SeyU0%NT2(llkt_;36^jUODyBc5m)u6!WpomGn?g;o-)9>|+VB_nl& z#epFPm@<%8uADy)Oxuxgj~b~@I9;Q*-b%DarX7PFIt-|@A`!BqA8*V=(a_kkBLnc6 zLweDY@N5_BkG4K~BA8vio&(oEN@l0kW=i-woji@Q7rOye!@xYso`7 zm7_j0&+wzrY)x_Fl5<2Y2U<;#p`J9Q2kK{GouLLB5<)UJDQ&oBP`=ZTPR^z}1U+(t z7&uX{k$Xt>dwPvLg7!v`LaW@{>%^zF9b0Tr;3QUgmYo?HGzEFIa2!L?s4pI~hB+$mIm$8VjOXm~T#736Vx#kf6`WfD zDX69_K)d{gQIHg>^XH6fYD^~TMDCoa6k5j}+XPUeKAV7$*qN3+JX~-xNmNVsu;yDA zg5-jxwsV7KIk_PeKmbNi)J4Usj7Z|*FTQy#ecw}pvqfruhjp4z&=h^)K+xYyi9<0= z*UMnI_eZkRY~FRu4BDSz4grGJl7OCpA_2E>E3g3WdT^#p;w6;O4+(7Ti2S5)ea~eC zf|Ey0d*&1gY$OJskT=|!AU7}rJ{jGk+g|tF9=lbR@}DF{mv?!`PXdZyFooqr%{RPb?FHwZ%6^ zvAn!R6PX&5DVp#ujXj!35D}hR0Ul5WbES|YnL23v7S7vvrW8W)ARz#s^yqgABqYb~omRp#`4>k#Uu8tT9 zBZl4tGz^#zC(K_E3DC&I)hDB{OF#8luZlbGsS zl;HfW@W{~^RKb}P!$+fYlmtY@cLuSwTX<9AE*wTSc6N!uXozwV_W$L&0-*GG(neEc zL&e)3#xB-$c7?V=BG}kU!Q5Vgi$bx%X$47Svb-W5aS4QYWO!yTHd1M@df@izK}m$e zfH*Wd6fc}`#=IxH>HAi%;so@h7aItHo;c%J-veMT71k{`kJ;_JMyNWBBL~7L>$&L zR7>2*VwtNXEPx7FbC!_V8$dT>x>v+biyg^_7ZpHO@Za2If zbqyzkka2eH&i}~a_<(#6+gIE+?O{zu4VocR(d#@=q0gpewCUgn(lHVbVSQW|2AM)@ z{1~!Q*PdNpd!Hx4A5NWF?u7oyRt8V?V0HWzW2u>ZhG=XebJhWaDq1U@8d_q641~A% z=?)>2WXE0?e3GzIz{x5=X!xc80=yM44$Je4%kdje|o} zP#^yQg>iF|ZN!^7_8!3s0{^|o(DlcE`S;n$82d+t!*D6fVEvrpMx}ptNXb)K%HO7Z zW|umLjCD{kBZrGmI;NH;G|8M`Hk_X|-VRuILsl^EHjX&2b%Je7UOQg6L&KViGX@pI zFcv@My3$i*ZSN_W&VO{sKJF$IYjh(DedrHPl?7u7nBn-%$Whqg5E#Rrpc?*eQ;kU% zaK{wM5I~@}iU9D>{lzX?nNepe9oXEqZI3-fp*@gZq?7W!12fnhS^y>xx^UFyVNjp( zW1ei#f8+9APUe4&T)*8+_DqvesFH!>1p|X&j6wpYF=Ao^pAy`oo8|qte&Y~!;XmWW zPY5zN8hV1;$zVDzdm5lR0Ownd_v@&Ee{7m!Q`n~BIf;W~t0@BcwwvF`|FvV#bzf;GKv9lez3oBLvHiLN|?qN#!Y^p`FGu5uF3j zYH4ws#xjvjW0kys#>VSj5KY&|>*J37BgOs~InI(*Uwm)A8Mz8rx3;3FMCDf`Gku!}mqTAfm}bs9jShqP{i({8s6TasY!L$1$Raej2OfEV^w#QfvK zgk?Lf49;V-=V&f(I+`0Zqi}qc%!nx{DFR9=DD}8K+0D63o{-U`+2DuPin>* zR*}Bz!TcAFIVZAVo|9spjhdMdU{Jx$q9_-baQ4(kZyX}XMe=12z*-{4jPzQL-Z;Cc zz!K_Fo-|b^^rz1hNa%7t2d`uswD$%w{SGKHN2M4s53eFe{jh=+XMp4RTf* za9WPx7ziq0ssP&Rb^#=L3S^2nFP_YW3k8_-|3a7VxOM5N5%}Yu!OQ(~WWnQB`hd^F z!E7)eOc5O%y746%`UWr0yL|&aXZ_ z3WmLzPazt&h|1~itYF6{m_Ic4D@+O#^v!`tzpg+;Jly~VJ#-f+MF*Kv&W>))b$Q&) z@$kNXYL17_5m3z_C_sgITkd@T^?5bX!uf;R)gfPIIdz!2vo)|zD9o(E zde*}l%@HMwozxEh@i${HcE9j#4cGd^f>p_dAkpU+%Tz%?`Nb9{r)j!(HoF$x^9~_C z^74sd3}=8{!-11Y8UrX-u-;&y%%h}8aMIV!s@aN+oz8!1J|1E>F3$5=NGZAfrb+lG zTUk!usQSA2?Xb}4hotGhQw(?9F%=mY=k-rd33Wxu}gul;JesQ642lk%^#)U$5=rvazRnG0~% ze=opF%WTdhB5%Ha^sUcS8CLg}ARXO_4S*i4mO!h+R2=n9!?yqm+v0-a2&u&1Z7Gf+ z+2j$v63It9v=iY?9>p%89rwjz9(ZLBYZvSsoT+rjaE5O^c}nIRbR$L*Fm zoQ^ERVo%H{M2EQJpIYH{W`=(!Hf5&p2E{Ip)+h5Z@dMTODybL63(_tUX>p6yI>XH- zOlb&{3^B+vp_2M?EPn_{h@#oY2i99&<#ZVw>k1Q^NAV#ZM%XQ%AxDtY9HyuAibD9; zW#5-ZhsR7K(R4r!vvU1`e}0dJ<=NR)2f;An>nbn$tE8zb&5V2%)5WD|PGFqxn30Em zY|Kcg9RhF@>8cBL6_z@U1?_~H*WGrGQ#IzwI-ZzlZi=s_xs`)`{jLAhF&!;0x0o8E zPg?Y5jb)vEL2&9VT#16Qe=N(REAhONS zDY&#efrZULCkJL}7y?MH2_VW~d_;y3(eO;!kUF@jRlTnvNq&i`jEW^nCPFKgg`~-@ zPUlUwL-sUE84zho8AumL(o`Jl$7R{;wb-D>73{&F#Z^5ySAmP4ZMCns+Te@Y4MWCb zp{pjO68plwykY6VMl701oR?!Wu%eS>)yE%NWzBE)YyMSHuc-oeVi3%* zbAkXzkB*!ujeul#UD6@UKvEZV%5zAIn5f&YvQ+*agFE)pi3&X9 zY;XE^n}-{p)SRPbgt>_yPmlB_J3HyDDyIv^HQ<*CF8u(UdFR!^N7ajEaE~hBUSCB% z3*__$80Z4W_uTr$|IzRFpnd&@$?5q&LmrLt*rV_#>;Hz0=Gh5Bg8c3O99AARuuZn3 zKEPSi9P@x=gM;AmGkM1Qf0_3H@)(){kef39wravdd z0E|VliO!Z9+z~5s%2mTQLCGNnCB7qx{=x$$i5<}KJ#F#LaZj@i3I}|z;#>zMnnU5l z=(S_5O(tMxc7kFZif&k~qDS#C*)lyvIYK5nRgM+Ik8`73htv7JVJ`6i9K)cM&TGay zqUrJIiO5dyR7uHx7*?4{CZah{qN)1xA*qr>27LWF1cl$ttKn~QYe-k>7;uZH@FWhG z$`?7%didTPsb-4vfBx`zjN;fE=%#5Mw=s^%oyr_a(v1ChJ?yKZW9g*4GRWpTs|oRJ zk1bQ=CPmopp(=UQB&Zua$Tq{lR~S#bJaD(+Kn{i0dl1)ra+`FAc~*)xK-s$x_%`^; z;Q&Cvpm75w{y|{Nh<}v8$M)~yZ+;^rz4+ffwn&NuWJMSt@Eky`W1q0v0`w&-tHrJ8 ziZ%c-FpJwZ@W904sxo~9c&6cI49Stn8r#khysX;*?Bnj>E_RCJS=KUfQ7Ql2(n>2b zSui9LeE7D4O3ZEnFYp*v{fF%^lCJDaC>&B19<|MHM$WPT!b}_E$t0e{A}_`RX4yiy zFR%;sC}S!IHj%Z9`k}JJkkpiVz`6gBA6Nn4H2=zEklMyV6K3`2ilYj&3fnJ$?+z3F ziQu$US^Q-yoDF%0m&vn&a7EpaW#* zPuwFrPc}aePX?3Cuk+vLO7II-f-W~->A*H@UpGIOwFE&tuOf7~$fB=UM#Vi;UvQ zu1V;#iP{d6Iy93$aa{~ft~PY|i)msH2z{vsTdBWfsW+cO;5$g$mwSM69{dII8CgH> z2iBLs*To&eZ)^N*#P@6FO3gp;vz{~uA6wr=0!f)15ZG>>g!B8&Lekd)kL_}o_qx9? zP)MJWBL+Y8qCkmX7Wlh#{3A1*E`FvU^y)MqFrMsIXMz5ZoDl0HPqP9+w!u~~WR?s4 z1D-c8BF}ytjQ%QQ2&#Jg?bj9mX%BK_KQ@kd6v(K8%fq6!*$#|XEkVe+J;ZPjClgZZ zUN2R78gIzboj0?R&w>a@gcTh-Ahhe-S`BZniFDllWbwZ_!P848qQuq|B2!jeBTQHq zjmVL8<`HwCW(Cd=k_6_%3-Llt)<1i+4=NLo%_$=@Q8X8~qD^ z>o@9t!~5_SK86UC1XCTq2mKKh7Lo?1QJYF~pHyGUZH)!fV*}2U^&=&%DJxo%+|08H z%R{IERmiCiZmS6cMrIEcq6wolKUv-4cGg|;JpK5_iT(AMt& z9mW$Bk{$t`4#@Ph%Y#Nf%k$QmzQ8Mk>1ewBXRP$urk)30W}lG7aQztu&zQFBKln21 z6DgE>r;ASt#-7*g&ke`8Jb{IhR`@RNGkuk}%x-vTbTnk;h0KbnmP?>Oy#7lJP>XqJ z15E*F4V*~+)G?3_CpIFKzZ=T}iTx7tWt#4H)|#UK&9`qDj$y->W0sk7zFW!t9tawly)z*N_xnLq>P z+P1g>aQQcCMw~_np?GyQ6oCgp%TW}NF?D48*+H)(-WL&Z2*Un?m2y6VAWIq`s-9F- zVLN;%p_5?9u3Yj#$$*@dnMiI;I+a(64SdxCkPu17oPg@fkWQxSbPWJ&jGwg7M3XW} z-Ph@$^nru_M`Y7jzf=HmRhzDJ#CBhK2Tq>B7?4V^fKWPXR~IbXWUm{?h}#jK7p#2x zXo!C^Cq>41D^_t(D3V+dfD+!c@a=Gvwh2YX(^X`(kgqG@(lP*FW2%J zZzUEU8c1_su=t|5fl#rW)z-NW$G|~gMt({j)lgeDG+jAHXu$?DuP3< z$^1c}*it#khBP`!>a`s5&miAM{v6N0`DEvm>F`GE|B?^Iq-9B_j-eL@H(LL!bR{`k z98X)zmYsf_k|4na23^eTFJX4syN30eEN4iIF-zHnAjN@kpGYfOZ#)C7OCL3!yW2Qm z^oM=j9WKCmOmBo3l?kpv0dn ztcp2o#dr09!OMQ)ILpdI(V&J)yrLPM5C?wXxEb+`z@HIVzdTgK9Iik88)|uKRgDT; z{JbnG-u8>$e#*D$;T7a#WfRu+3i7E?t8YOmV&-V#|=O>9>Wg~8$W>9O|3FNlTUaS%T2OrEM_P?iuWlV z`;MSJYP%)g(U&~PrEWAPlMtevNb#=QsL^A{stzfb|51yplk!HWuW|O@R@rD2B4K|IB2b<&is(qOD8@wpBujR{UGX~9o6+kIq zYi0{2xX((?2tC3^OF;m2z>BDTFm7`O1}_e{lVF1vo)+%%siEc24-wV$g7&9YEp8k~ z!xt?^Pk5qIWnI%EiW{LSm6PffhS5v2SFRs_g<&-EC=DGp z3$bpF(ykL)4!yx12H8|rjI96RNAKMoEIy_v$Q#nb7v*bD!T@k<5G!da#QA@Bu7yPS zUep2`f9OnH)`?c=^*QWhvP;VkuEMB9SBfedUXRlDo6fcU;-kZ-TBAb?r;+g&qmfA( z`OSMHnUY-hA~^l7JL~B)WgEA_0I|XRF_>Bdv2*9q`d`(*d_$@6dL zzwd~{ukDZk=aPmudN+w9*t(Qe;{)+CE-M3N!UUgP8oSsO-7Dgcv{_uTW#YiS9{>o> z=$53IB+8i>6=S|7MYx&F~_yVsFAZ7M^VZA37Ynzt>9k`(cH$fQ7K^Kg0TH5Z|V{MmOyK5>Iu!IvU0WG65#bcnhNr zXIcWRdYi2liNQ4|VY>u)uf*vRLQVD6fT?&DNplB|f1HSoA6kF>WXAC2xg3O7bu$quPu#r zudSK;MK|S9RyPF{&gs}4#~P0{@I#oOOvc{0ZF$@q>7N^MB}0)+$OcBioR`D5 zuE@|#MSf4piRyh*XGl9X)JOC6Wj+9*X``VI&x5>0Lnq}8C1T^K47z1qpn*&TK-q~p z=76uzPr$fO*eUxtwobZGu0(n9h@BMas)d5#^cHU_$}Y@cdcGEqQY&tCw_}d96(;Lr zL-S-w>xcXXD;P4BVJNPf!uWi1JQ}M+I~%Njpspam0l)raeZ}vs!W7ME+%hTxkr|5E56le5aK%5K z{PLW!exH7GkGv?&yly<*V5w=L;}?71%KT~Lmd_$Vt;uKcIWNzJ$Qy?SWUT?cY2z*r zlDrls@7wre;tG0rJap> z`Ol8W+`#hw+`>|`9QH60HwTcBogq-5H>^wg<%{u)>D&`>IsZRde?6fH2h8v9ZY>Sn z!@EjA4zVE*UppRZ# z$G1Bx;^y7KbC|XOi^^~G26?;shSkwKn9pSW#GU2Q@A=R(wL$TGWf8D%GE)vmfS*fD zXH}MBYlBk{B`Y2;HjnQPs{tRgEp5vw?PG)=(?byQ>26BfR{;A8Q;4w38G-eWi}8_@ zH4XS8SOwPW!71H7D9h6q1}5(dR&)?lDjYm}djrJQ-f`D%^|uYybif_WjCKP`6qt5I zt@XJBcKXh?*?9eYu2l)V*$cv@R0HLpvqnf}2e3&3nZX`1w$%Zn0|SE247)7>rv!w5 zjF9KWoq*-={_s!wwDa&!fcts)BQT6rE%;|0KvyUzBV_$E|HxHv7f=+qwr0VI4N7hR zZ#WcSuMU||n+1spoW-$>_IVG|Wfo?>y$=>0UyMaIZ~+z(iHtkNSwMiv>S7?$&Cv&E zEAq*;-cEe-VXldhQh5xKs$sZKB!$(!e)};~Q}aj+!_YyPI+P|IZ$@BKAArZP+^^${ zXyc=gw)9w>E0-Cu2PHEazITx}@CLfN)m;s zj_PGmFhJ#6N3{)p&@-Z-TSvZHhtjwV=#r*cL}|7yBG&f$qt$xzHD|*dHKo?ki0nXv z6YwLnT^-IFA=k^OL58ZMT8DHe^bz%)$gm|MW)w@lK!!xWW&n($1nIeOA1Vi4S*7h ze{~OLoBenAzlE~OQdDRO07J3@K(FXJ9`L7tan^kg>54fL= zTmk+jD68=?#`X?iI|jC}kDC}6SUIHR91q4rBr>~p7$fLI2X!0kYPR^7f`Q+t>qo45 zSI2F<^>=;b-nPbggr}y3@gEXEs1ZL~e`=r|e#mG3c^i@WJpGKXKBJyCE6^U2LYPNS z->MGbKnxE0;J$hgT9~3XH|lcC>Lffrc&~Q8e4#iXqbHg4o0p?HP@0D*Q9l5?RhjxE zr>Ipyr*HILpbwZKfjOHLRSiz=oMLF8Bp1MJdmsBSu6D;JQO|&Zi8y&rR;^?w?h|ni znZOot&O)3)ICCLHg*7o(Pn;kfNBa4THr|+?XYs`~=@#JLdKlt67#mo9WIvA`U19s!UZUp8uV4TGQ z{N#*K-M}*Ex27oP+Chou6e9B7+R`$?W+PoAwgSNm$ETqGgO|g-Uf8dDMf_hR6Dc#+BrLFjem}@^)*CV zlHu0`UwRBt+erw~%8Lm-NI=vBKu~FkN3LrNka8jpYTr~GXI6PD_RuOxWA5VTQEn6r zA9^awgmB^!XWwM3d&V9~tbDp>>_OV+&9~(tGc1V4%qDA{5F?+d!k=8Ak<&p&Y2=th zSP%x(F&1(?au;95L!2)(dhhSx}y^4%E)4p3|3RT|=X z+S}J)X9gb7ZD63azK7HOb&-|Z9>2u6+vW!Eo~>q|Mx|oA$L*P@x2Swo#Q?0|0iWRG zoqnJSzHaoi_6dW*hS+NOh5dftq$`a-(alFJ|B8F%g^ThPUG)~~AVG+2Fv#$?SF<LenbIazI;OGko4Y0Z-AQXai6w46L$o!8HW1US75faOmk1OdTNMPvXC5HhP3v zn#I3u7&G!_0Fp1gvM^E1!6|vfR6R$w_jSjy4;J2$kms@qVQi$4nq_zp!9qcv9{cVvxy|yK$1ec{;*qO=7xY# z!ESA^uINoJkAen=6_`^eQ)Tz zCD5*{5wyns+w1#pEKPe2H%-iyyRXh`1VM? zaa0ii`7D<~#&e7^bV^c?%ge>B`m^MQd3GH?cCWXhg5P?93%R&~P!wU~bp6?n_NCOp z@SM4q0=IBO2E;)Xx`F3;{Fij|T&j-Yax-p&YY)y}CevYu&>G$frf73ns|NS4E#8CrJdD0sIM zMayrpL2CQCM4G0msTLv4Z2e(&Zf=4C{7wSO%fvc5mO0vPgO@BcX)jGy2!5FV_; z{GDD&pnhAB;&08+Exrs7Mxbpg1UFf!{c$<1n_K&puU`j$A72eF+O&LJAVvm1?r?-= z2L&5?gpTv}k^Q&)=KT}*8Nd@;19(Rb;O!R=;O+eY-oD?39lWUe-7&Mdr2!mS^|-byV-^M)jV3kge|yn?km6=l!c+KfK&|vAFK< z;D)*kY{8Zy*MTsj(M`ShZbisL_NfSJcIglN*$sXbOm+Vnp69W{D6>i~DimPBQWs+kJ4K#ue-&MUqz!c42Q>76`` zZ(gYg4OBF}T8UYmmA_frl4$8zFFNZs`nFywH16Z3qP2o z?8V_sm=hnYqQNoQJ8>-($MZ3whczV*I^#>oPTi%)SwwMVZ)uQ)Y#Fkid;#ySFHiOn z$`YQh3I?#y-GA6)U;!1fwJ$35H({i-mv`xPYxuSF`d=*}c7a;(O8^YK-$6~V%?n&e z*M*Pr(&1n*91cfQ3^TKWPo4uLpxEi7g9`$HEJIZc473EfK9^Sri_77(mu+;x+|8=B zKYN5$&7Lor{bGOimSFb2XVtKZ7pAB+=p;=xJ2yu4L;k%15*4xDQsv7z|2+#kq! z5Lju|K^mKV{U-%y4cpRkL(52meAdiY58#O}O)m9uJ|{O;(E&j4RuWg>X#IX+yQNj^ zwMm%_oO^4bvAvZRMtf`cg@G+22@#7KHID~M#AI@n&f8swZUM#K^}pGy;8q=kP5{yq z3&fv_X5E;it8*#~6?#A(%}bx6oix!+9i}ncpo^5lJ_sKKKx9>A;c!7rCKgr~x<|#b zvDa=vdO#wp?TFd>XFu{YAK_jw>}h(bH>}dLs|S}4#^3rgzGr>-_!&1@jy5%NeaTVd z+7Cj~TzaBZv-@_p--D!~Bpc<7F`N+$#-tCI4`^SEmk(NOyyT>p?pUz|V`R)SqZF== zYxFbuc3RYt=7oT(qa>?~fCy6uFTCGn-8GBKNHVH4hy_i%>Ws|R$`Uy;Jg3y&WJ zkB)dw00HmWO?+R_>ZrN##|npyMzDYZm?jSVUUbUAapXrcD>?X|Fe;FWOp|D7+|!i- z(Sbj?3h9dC?h1WAP==dm{Xp-~Klb(`mZ);#J{abcJL4dzw#UWwV1_D?`ZHc=T2g-$ z2cto%5Ga0E-coa4HM8U*m`q=k@0HAijYP@plmLP&R6ke8#g7*qU-24^xk4O(ERW;C zAY1D`i*#rpAs;dg8^T49@nwS*s9(e_Ex4)H$wi$cRebfp(&$8ixO~ZJ_LG!f(y(6X zra#xz_9wO{@%9GO58}(wvjAj43JUuoj+fg&?x(7VQ;02xSpYBv0?31o+nazn^ExNu zcH5*(KvvjxPRM=XklF%jze*+58umq*KZJ;yR0I3=q*|t%IuIE@5c7Tj5ooe1c2eyE z#cg|@vrei3=uD}hDCoW@spjs3+I%$o)!|#YNxx=x2KYRm_IN)H{rSQyd3I* z4O|gM^+1Ua^GlOX%3#8f5WAz@iZg;4xb-Cf!&ISoSi7;UH9K|NX{$V)%fKfW_%pk z1qY>eyC8PHCde|h32s`*6#0iO6K940^H=Txmxn5<%jwfFZ*iV`5(r>)B?<~8rr7Nb z?{nANVe1WRz2=U;djl{NBs(6!#E@Ijf;1$*j6_`u0ANtMkPy55sIPujAv1-gor8eo{ zKujv}S-V4EORR&zxJ}GlrQx9lR&R}$E+A6qNR}bM7&sm5fP+!v95`2t{p{50fw&8A zYO!YLYK>bhu`NK_#R*0uRja`e_qko0BM4~XJ5Q$JH5FSTPhofBYZ4OeH)!#G z6uV=OPd@{67KQ!i8x&-yCkdoaRNk&$#AXNmW_uGZk9fo}e9%bEd(M@e>SY z(s+mlfZPFYpe3-qqV|q&_#ovkXz@NnDaG*6WGd}CTN)v2C|da*&M+({-mTv*t~6{C z)5E+-0gL(qpPVu9iqw^;#pCTU>wR}N#3puA+$ms}Gzp<9ey4cIlyEhKbJXi_>A-ur zJLF~-RF7jzi0n}}OtYGzz|LxJ%?44mq#R`TxqHxTvJlOj3ftG+L)VKKSgjcEIAv`a zMlQmk;@~y~XSeHKDci}0D{x`jCX&s!wAEgakk05R*OFbFz|ITXMFd7-0IS?^o1pI^CRb#0!0RBa)J` z8j``}1Pl`WgCgNJ1$v6|*YGO1SkmXuipq&)Z02ulNIb?>P(ENm+R)ahi>W&!!*(@8 z?WNI=3I{y_8@+qjys4xC+S#J|>k#Jq{yKD-1&RtYMHySoFgEt>5=$8Rud-%da4^a8 z77aG;sO%{h-;fc5rN=um7#iTg<$722(JN2JO$N-D3kJoq)}Z)u@t`chpnR{tXnR0B z+p-~2rXSF@dRi<;U#Vd*NLqk};aR>?uf!fkVjZ179|^L$00j%z!kZ!0855~?7HttEMGjevQea(xgO)(&^*whuFab?0 z3yOg}tp#75wrv-lWXTUejBd#h8PwbB-MSYyyiW!D1uq&yb)R9j?t3@id4njUPL0jP za?BFQw`%225x}d!d9v~dVBneCE?QLO9yF!b9g05KpNl0frs#v7qRkA_py_gIgl|za z$4C;Kxd%>HM#_x0L)yG>F)hKIeV@hL0;P@)p2OADLHNd5kc{F|9+y#e03LU%8qR{8 ztI&fBJRCcnwYD85dF_HiZwDQ>Hk~c8Gq@hp7+P%rG#m4x`QN|x{u11`8y8?}-X*Gq zevcJ!(LEQ4f&NDe;@|I57wXqxyWlt;jMmJ@ND>ql>OifgxS zw%Km|>=gtZLbaD`Rv|o$kH|IlU1fFHGd7#;v4h&aLvA*?R$kApV7CRQNmk|MFD*9D zcDHuo!k|lO89!n9-95NN-;WhXZjr8x;oYNz?8Ldu*@=T)oZH&XP8>>Fhl<^5AG!=Y z-P+7esh+HxWMiig)x{mS!;NIaLM_R5!H`_{9qKqYq+QI|8Bp-T-DR%)b|EfA4%{6u zI-nwhVXgRRo2>_(L*KnT!)_v)DpAjhC~39~-^YP1+!_5@uE1E-Gm1KA3@#Bgv^mQK zquNAKAFu-WQKa0y0rVGWwYf90x$4<2HYS^UKCj(hJXLc;5+bYmK3ZwgO@w-Z5e<_bS*wBfuH+4qgbvNCwMXnhm|5 zkfhskB?@Kjvsu&Derq#_wU_c-rj&>)3pvU8k&P>h0L!Daq_vQpc+?gn=nwk{`kl2u z+^l^cq3M3h?%ES<$FS$!+GiFVSQOaeTK#S$ZGz~>y69c|@Qb$g+perydwpfK z_BAULor0VO)}cKYLI7b-WRQU-X$(q#K2#cTZuNZ94Zz!Fa*#2xM<(Cv9D^v>a=!D9 zK{hI|eSp>mnizq#Ypi3C_i+rK5`fo1^JO>&4ItTd3`VPCQ8JRwF{rZF9D^*U&~ydo zJtc8N_<6@*JY4+_hG-SHtV*8V$uAyGmCNE+fm66=e(iB;dC<&a$?6Qch@9WBakglL znY%jYbggZ6E~-(vwg;BcwZhVSU2DV80g<#qs~*|Ch>diWI!y}vKN9~BGM1cHbLp#< zVkZY3JNY7ViOH{)OGrY$=3Js%(Y<{FG^CC4^HY=YLEPM1rzR&i%G95jL;^N8))Vn@ zIO??f!I|Ebg4Q>Fd;q<{K+=ch%1ciYBO~EZ`g#PN_)xKonn<-?EA4jHYK_C8Efs9b zR5V<6&(SxP<2Rxsb968r?e?d`3Z?7Y?f7`>P$uaVJ_+j4IbLhIf5vrf87F~-CnP^M zp{w7n@okZBOTL}t+Xp{!jFkHXJvty0!_6OhJIoM`DLs5XBI`ANKqhCvKPx|2}yg0kY)E`O!09iGu)#C;nmz5g7=Oym8U1 z+a9Lsh<@}Qu3zX6mi*CKuIQ>;!;3qcqs8cMR=myvtiL`;vYp|AhR0^N$SG+LC36&{ z5@{TKLlSB9)q_vN^G(n~DzDs)05uQHt>YXFfJmwOc?s0!an#b2RkGmt%iev$UDxT?;N{&>< z*lExVI7Vx3pKtjda+s*4-GCaIVA5`kH_jGJ8l%Xc0i;xA!c2^7lPoxe2J+C$u=fP~&o&?k|)Lh+BILg>}SYxKN&na-p(d ztd9#tPiDOWIO8a`9SI~(A$d~zg~@z8WV16LkGC+N@#btkCc>9~J}qZ|o6HKekUK_X z116K>%adH9r*g>DPim_2{sl(Khj~A}z4(NQ0*s{} zQiBecX`M4F8WfyzxEwWAioGg!y|t3mK3IRP z6u{oBSfn$7UD~ngNpzI0W+B`(LKE>j$ka0~Gz!hx<&>K4>cJ9n&;~N>U2O9|G~0@! zIJbmgD}=uJZ^_Es#+to!Fr98kQ?RJJGi9B`&I6wBZD_HV7QEQ2B2AXnyt7qyHUt*f z^d<&Po3*3wKB4G~L052HlEQtOt|a+t6i2?-NoX+uNCNie4B}A+3pFQtVb07PSS9?2ON7A;9mlva56d z0qnKb6T4Wox2zqpAJA@giZUsQ9RL|5a*o(}Zu>1(W@mg7`+eZ&JXtIDQ5&g4?#w0x zuQ1+QG6_B#^C9@D1?iJ4GcyT(woUNUj^MK$?4~giDFpA<^fpwB;HO+fSq!)%c>FTB zOi7QzMs)=b0DrcZ!!aB(3`IL39=C9j;aid=vgZcN$^1_rk*u=ufya7QK6+w}g#NpK z_M7fdJs-C9naI(1In zx=Z9c!CivGXG<^efvrApzSRl^@)P5X9Mu)shw5l2`*IeN7vJiwL`aibk!zaI@Cjdq z)KPD0{`|pt7$4gDeEJMTH6r}W*nX1OcU7}Z_j%NR-Q`L%m?9Gf^`Gw@3cGV zfEz0`Hl+MZ_GuNQiNwb0v)Z8<2t3@~^wH~v-J2bcQe_aZp%kD-INW`(6rfGO4|f|& z0TBVy-6jQ`=)5?kqO|5VsVLSh3V{a|14mM?1Nh8+Brs5^~ zqHiI(Y#dBI z*Vth~W1u~lvxqIqIC7@npb6!x@SgplIjD+A`x0GmG>f9F7@Wa&!l~LWH|+aOwx2S; z(dr>z+RU67l(Ql|OLg4kS#w;n$yP?G$|l;G*QB}pA0R^OE?*+G5|f^qUeZXlkZ)hx zk;^udF*+Re#DD&{ZXx1vo+cs4KZzi~T$)V3lYg5?A{a=)MwK%s=-CN+|IPec5 zkI8Nn2I2te{aZ{?)MHy_0W`uY)kZc%>O+CQp9uK)*j`I}OH z$B;&8ert%O8EIakd!}Fes*IDOYCTgH7T9XxfW2Icm2B>$+?R~y$yiYn(x`!?^dPe9 z^ADRuu+6zwxTsF^SGTrdYkzDm7n!CF6`bXXA)&r6<-P$P@};zp3^PeSL=| zR1*oQJuSKk|7!ABvzqTDN+m2CtVAn)d!b%6=~G?Y)IbMnG82BA8ObvIV@ndYFI5^Oi|MvPpM++M50kby z*{&@h7#SypElH8d<}0@C@r?MOUD5Z6vbHKULl&iOXAFc@Q48tB_H?|Som#_N7PKnO zsNo%fI1}wdm`r{FYTS+#_~WnS8LkX^#h}7)x1g6LDjr9?Bl{n5LI_K?gIhP zh{<1+W24D*%3cZ6c#B!zI*2M=4U@Z8RNd4-|8R}1HZx6KR>Wki({!sWMMNo8Q(o)oNPK-c) zhN2uJAxHId`pGUmXR&%4)s8BY4Lr74ovVY}wMI3Z6+zsbgbhb#EO&JZU%HaNL8Y$^u0#GHm{S2Tcvf)nm3}j7b!)kW-)5|O<7eL z#o@g=yRVB<^ge!MDwDfOWR`_LW(i?e&`%>KmAv3U+TmZ3@}P#eNrkX zI1-D3T+^^hv51^U*6|Wf_KPW#4?O9s-#C_0HSCjOy$FYvjo4v(pfd_lG>yDzYT)(9 z^~k@WQ@n$*+;di4;BLyo_qoMSLbzse#n^aERX-8K=;^ZeR-h55o+#WI zO?-n$i&hc4GvtbKx(Rkv=eOV|T*AD4;S@yxywWME*t6ewMlr?Hcz?JetfSE#Jk5GQ zc)vhF++n5nlAX`GOt&;JPtf!L-D&J?f(0s-%v^8RV1yIL)MauZABp*!Bz4xoFlj3s zyRFGTj%Z}o=hKoFuOwM}cS|lMQl6r;e~P6`43S}4W1!z`Hl#4Bq*}Y|>xPn^K@DVB zP)|RxF_V&xdi1D5(z#xvkjUIBBo0~)6_S}+C?tKdypVjOM%BraD*iVMNx7|%THmOm zONR#s3Dqdd$mpE$N@9Jwkvu_f*i&w#!UUsleAl#8E5=vtVX<=n#P}ghvliI z(tcV)a^9p*>#AZk2Qnfc8)_)ERV8#1_JHHTil;>NJe7)_t=?^tx9wS`v7Y3m-q}}L zR53*hQZxC&sq_E;uDDJuDjsZA$hinp0}uh)eT$Y$mDs(@9=Y-ALrxZP&R*$-9O_fu#eBU&t_MN;yF>*>yTopCGMpeqwdi=LT-eHdwRPDiY_ zH);qv2QfttL4e|lF-quGyVqk$guYTnR+gF%6F>KzIYC~eA@b5H7ZHjlFJpoDMv<2o zrE-uGBlc_vWr@g3iR!s31MJ_Em$Aqqc_}HoSqmj>SW-R6o=%NZ-K7p_6+s{4ehSxA zMOi8vQw$jtQw2rzKC`I;X&0}3$vEUmOp!%a@ED78wgx|6;0nt!!PQMFfR=?wtp?-O zTS(U7r1YRK+5>zndb^}v4OMoR(#Wa?RSh;kscTbub#cOY-B}$;;zRCzzJK{~P{XKx zr4kwwu%t);BBjKppB8I!bH9+s)x@Qx(Y5Tg&i&6IbIj3WO1FOpF6s~Knm zu4rFt-&QP8v3nVOc{Cy&8PgS8N>5C685@#pooKw4n$eCYF%;WkX2@J)FOF!41+20I z>70}iKumNner(ytM5GwV!KyI3iB+e5{PbIcSOn1xvRR!U2h|T!yzFNaZ0(!vwHfeU zGOH0s)u8;OtY8qW7nbZ35=7Ag3|m^Zw-Ma3rGcJ^VQQ}|!YJY@GndJpdU7nLSbGyA zltN{a$V%r|g`!VyBr0Tp6-0URzi?4whN@3!dYppDTi3{i*Zjh+z4Tym8T?$2@ zXgzNB4JTnobg!F4Q%%ZFQAR;j@!8>$)1&AJmI;a?{fTPGYWKhPL@#f@Ry+Fgd)f^$ zt#3jraY@oN4pwYJ$%iVqZ#!-v=VXttxb>)S-&J^kO&NR>73(){Ad^~3ZCY%;(0JCW zlv};ZUZqf@*aSkErD76|rp6c9;O?dIe2sF)|4CK;r;P{w#&q)E(s=rSi^vNpP*g#$ z6jR^~au(BqQ&Az=?ACNb7^t#w$>lbP8~VY*L=Z`I+PgNLu}-DFjRbp>ic7RE17*><$VZP0#r_f_? zLsBMEqpSBy9v5FC5{AXl$I#{w3w@0rVT@BsN&7#UL+n$&?o= zcm{8$AdRp+|C+pg`7w@zB0E?R85X5vAgXL7nf%*^jlE@WVo>?z%lPU(A^8s_+pZz#AevSU|7)t97O)Gkn|M1I;{HDW%lFq+EZ zigxIQbpB$FwXj}Ad)=yviJ&Sb0-8|GhPvJ5-?QPmnD0D^V1YgD1z#%0hBvaZ`t(YD}DbxZc3eD5%)K6Kg z5|+GCv1|$rU8B1v7Mwr~$8@MEf}l8?-k|%ZVl%T;(U6sxRWQXAtDKt7+Rd`wus$)? z;6t(M+5KO=%;H z%Y8s}Pulbx+QH^r>M)t?oMbzsi%F#YgCI$<4`w2&S9BqIP&!VYaEOF$-LqF!rR*h| zH2X!R;>D`b>H~QcYw*&CJ0@c`cr;b$9QuGz8;vILYkh>o6}})!s3uR9K8SlQqUb53 zAT7zm!3HG<)fZ0ok7G(7J!64vx}*n8&+=koO0>$|XZRKH$_&2Tr&THN-#lZr>CE94 z|FkM!CDUJ8QkGY%Wn9d(Gqd6|u`0&Ye_Ew2ceRZ~T2GL8V|rfG7m#apWteVb2C#5d zeO`m7@i|`nIdc*#vLTWt=>LeqyUYl@`bMM*%GN8!5Gfa4 zZMUe-Bte!(sGw|Oz}7ACN1?C+`hsFARzYp#s@Gs&AM?zN5|DKhK@d^Kh)1$9te?q; z{<$U=1k;8U!FF5Gkgjx$T)$1cHBc5;LbqBf!t8sM%`j4t*!VSC2d#3*j@}4Gli!TJ z->j3>x!XO1K%AsLltz@XZ`}Czab-{*EJ(*P6L_6PQO-rH|8kB0>JxeYfdHt$} z{c3Ad=}e}gqN1{@)*r5V3|3*2hbc*VAV0j_t(gO_HSQoCA*ErzV-t1Bki|jmqE-7` zU?%6UTlY?;gPw)f%$q)wYVoebI&T}d1gJXQQgucwDEs7n4w8uxQZMEKe;S>l4Drf` z<$`3&v%SX+dQ|cTUkXAPG*uq{>C2;WI@(#>mr-Z>^dV8H3;pAR3lhjeWoZ<-P2WC+ zrWA*}lxkB(q#J3r#|5vGpb{EWk(8?tO#G1>hz;&eFEM=p`4-_+gfEd&O^|HdH!XLh zh6)XVP9m`XAb05nYwEeQi%xo!Y@LD>iXEGWGXD&@LFA%mB=bZTEw=5pV7*GuWEq65J}C)BH&%?YRi#IbQR+JsS|qFrrrVIYhO;M;tNac= za%D?7nlibssMh@o&9tX*;*DCN8GoaRp(oB4^0a%M3v>}5tmfC7nDeuME5*g1^@vvxSQtn$dwX6YO;WTKkBX2ci;ezMHEAS0KPyoS z@8#AgMJef})H1ii%X|kdW?K*Ay(eY6shAyBe>b}HER})|Om5XYsoeK9)_Fmg5mMfIpeKF`0N>6Y6z>kpH==hUXC!ggXp*7ZPsc9(8R*M^DlUSZfalV!h&qB#$m^$-; zZW6MLRed^NOL4zh9@tL^9 z8B+m`I@Cnq3l>Lt(5;m!o7vZV%ddgNT~i^PL%$RoCLSeL)re+^deR9g0VYu<0C6dp#Zp6Oit-@?xFOqyJ2a$WbOgpHJjEY5Yt|HB*mTazn<%xAJT&{NDNfF6;t3dYcrNCn zHCod~kyL4UEkr;_Wx`JhW8v1M5bBT}#d1&)iLsWhmfB9`Hmf%%CLEXqAdNNjFeJe2 zk5VzG_=l;%I0?5~c0>qBoh4FWZj_2j5+p;@8B!oNdC^dUYoZ-}jZrp}>bRx}mlaO0 zJ)!=PaZkgU7mUb170-vl=(8#u)Rib4`4U|g3zx|r1|Q~Lt^q&MYMs=$pvYMk8qM=lL6EO^rLS$ACk`hP~IOpmL*cFgxkNfP`pca;3r1FHe0-% z3*ijr*AGDceEfG%L!QQpmv#Tk@%_)}{%2S-o46m1TiN}$`TLD6Snf@;Z&t)ADr8Lf zwx0&+Adk*t_eZYyZ|PW1tE4+oBshspw5Y?#zsPQ?>xDAL!5>rzOE+v~u=nIMdry9J z;(m8fG)xGcQZ((`#D)q3jAHN^*~pD{2OWfEVV6qC3yRt9(ZC=K>z z9}D6ScKJ%b*Q1IDy+`S@Y#ieu=oyVUX)0Q0m*DP2~!P?cLGjE!T6bX-d_gLjNbE=j#CFQm6yk!OpA>{@tKKrc_E-WyTIvp(ltU3IdTbTD*rO8& z-E|>r!|YQVbY|-jTKK{qEJQ&CQORa3qHcYoSsSy^RdvcIO~e?hh?bXXOQ|!th_$VZ zQ4$8Utqe5IOO>BJExI8}efB!N%*l8OO1>p)W0EQnrQ!Ay8*Jct>wdacSF>fDT>Cf^mO*7N+rAxazfQtHh_ zO%tM&>l7cbgj-9^!k98Q`;kg}#T$tl)hDG$#oWQpUlO0Nvu89;L{?AI{*6o#zfY}R zyCw)!&O|G2|3UGV?Z#y6f{BNAvlgatGlPx4ne3IyXFU-c&K-Jn;||lO8Ba3190mzv(N^-fN5W=$V9aqVmHEigIynvx@BrRCn53>w|c#!+3 zFqNG5IGDKje#lM*z8{j5hJ-{{Lzk_t7QS+X0DGErtYfc@Dy_3|=jhI6T$F66vneSp zlef-R9ahbSnh=}W*I14S5qf3kMpVW;3))mS$r$PXx;C9fAFo2jKO5zIM?!q1Yibse zHU$g20cygB-X|<$#IOu0r6`t~M0y?dW7{el*$bMo?GxCwJ7UJRKuhaR)5P}Kk^8kp z0{jkAP&FbwRRS%^GU+&(6k;%{aUMaobIOWXFHa@N2YQ}BaJ5uaM9_?YxhKpHDl2t) zjr!!CM^+Oqfx+_%sCyKz&>}sh?1cc94|-N9ks>XMlP>bV`=1o4M6?pL}*5IUAazN9_3TUg;{K~FarOLQq z8(i-jYMPS!n&u>MUtV=jF$wxlYc$APrKZq`WNjE~+5CZ#B&&7IXN&ZbtXW1et64}9 z^&Sb)kfCNx?L~F`Lp94dAgWXQ788J?%WBs4&Vw74Wkw`Ys?~I{R;@m&xVlGm+H;WZ z$t^lah|Yh{l9Oa}7jt6ap^cmN)^Yqo@}h;6_ib&5U+aQUcX*qEzAt7G*5_Kip=>V-|> zk?MpHQLN&w6pyq8$2dhEnf42gvHQ>xaC+4%36yvwCL?{Ttr0_#rd$bTStohK3`UN- zG@j_mrb*_hlFyaW>#|5sh-e(pf|!6QdLS3E=>d*5Jp6z&PRhG#Qs?R+j3zeBGB^{U zAf{f$pbBy`s`az~E6uVk(OQwaijC4z-sazw(coSOLzMbN4l`t$LGR(qY^TA>IBcco zu$mJnwahFSyXbY5HX6|@RMr%>J{TLFpY*5>qDpmDn+#QQla}W)@22Bw8d4Oe<`$<$ zqZZ6UAfCxHpan6f8u`J$Az;JLzJB?vCdA|vzM}24pZn}}@tOyTLgb&ZjKW!M>7NS~ zHpdE^9Zx;R`pDR@^9Bl}rGGA;C36u!-uojve77B5o~@vTvmZ_)zXgTq4!$^)I#|3w z^&@JtZ6x%7RPiP6RQ^q?yl87v`J=dmu9S~_bMi&6Kb@+_vc(3~?NFS4`FawJUzsO6 zr%OC^ejOaWIy`D}Q9)Z&%lhRk)W1DRZDmi2IQe(~BrYW%f-oM^B?qD*Wu)0n=6M<4 z|1$ou5P0q@$`*TjE2qK3`3|?r*8p|%Zs{gM-C+5y@E1rEVc*Z~d4xK!H4o}h`2-ETY95Xriq1eS^Z zDSTWxs`8_r(vsejA#)O)yKxt z+v)`rU6jr~dyZ>%lO}lX81dZV^Ttf#n$4i}T`-m5JE}`7x20b!g!b5i9jY442t=Nc zR;!BDK*ID{O#{u^gPbWMXLWaxGfdO~rSjA9$huZ9sCu>08aFFpX*pF`u2d!yj-^SY zBkR`^Ec5G&9U)@u(;PIS#OPn8Zh}}(aFZiV+9XixL3&nrBidvlrY>-ovC2gptAbZo zL)7Yh-l5LJ>M$ZxC zLQ)Z0VX6A{)sZW0T8A8E88DU-qH4Jl`LOmgN;5fMD@&`$3`rOTR_~ptxIt0S6aC|K zrJ4%OpH4P^pevh;7wJm#0Sd)4igcw}eX%Vmtxd!Cr3rj->-M?XniO`Z20-mh3&fK= zuazmTu(fop6C1^b^3p&g#fH@qRh7eHr>)e5eUtrGUs|O~U$@^Pei%I{(PVEB@h7?& zYKT&GFl51z#BX2}5+1BK+TtwH5lRXzG}09rWpt}X3BPz+i`x#iK>?Qd$CTa~VPnO> ze^ti748=rB%uu5TUDU>_eeJVjubn+*PA^%Y^RUIrz8-@nRK=9`kVw+3!^soOkc`Vt zovhci-sw*zE4A`JsZ@llOe4a*&6LFja}V3lfOh(;X*P?PS^7o7T7aHl9_GY=~+ta>|s1Q`hWFeAc1?O?%-ydImg>dXp-L?9c?{N|6y4 zd@Q|~!F>q)C`ZmQgMQ42jfEo@RyR4R=e^)HcTHH8peElVTnxjqrOYa4K408!+1krh zSrW9^OXi`t4rDhVZGH4Oe^TVuqJ=Y=G+XN!WNlNR$&l(rHAy$u%6>hf33DRKWQ*D;Lkew%W=9S)D6i>2AyU;;r}3q> zw8q~U2126UKuk@ZVKPBV;Rzuj207$&@=c!j>{r&zUz9-)XA1${!uK7D(e+$5MW{!h zq+}AIuo8#88*NHQy=iW(`|K`z4J&6Aq*|d4a$i?%NrLxT2rZ&Ifo5qLt2PZXS}2QL zpir?c7B1-;!z+t%*ur6D>+!lQ@ExvS=)% zg3;1&Uz3zoREf2xS^D;YGBPyb5JAy51`AhjS zW3Cf}_Lo?|)QC+w#V4~^h!BMa`6vAX?<*wscron|^{K_jO1nvWHgF5nqyojpPOGRI zDv7zGJ;n5{)mC;9Pj!NLye3WCO=wWH!3$jkQ_Dbth)Q^we|gF*(oSSsQIxvY>(xW3 z392CsZL#3dSO-O0X`n_5XBFTB=qwmBDOn>19%j3K&4T7xjI>Y)8R5*xqFyBpB*D;% zvH|vt6MsP5dRq-iF-evBC$v0k{nYYdDK#~z+v26vB8*sVVpOJ4J*H!kvp$%@-~$m$ zc|x{S$BB;3@D_J$n;Dh&XQ-K2H zjl>B4(FT0&CafoN>|>54dqRUA|%m- zv@i`-WE8L6gla&QP(5Vrss^NGBsQjPHf7I6d~85Iv?mf_%$L1ElUlpW7|=RMQj3l? zp^=(Zygf1IX(J3x==UW~9y%M$-?URp1>@f&M0%za8sh4_#IvIlI& zjOzn=OC>EUk*xpa&!u_oMreD_i)OUXn?2r2ZZ_4R3lcGt7^^4uc%qh+*pwO>q$2y| z7<Z8R=39VfZWcfzm0~bNnw-fk2sSo#Bwn1T*3jf1yyLor!h_NUNt9Og87Tet%gU}^ z)iAE2vbtK?sjjG~wxa?KJ+o+T(nm=BndO7oxh5;HOCHS55Inn51uB2GgkXC#9E9&u z6=mU^BnTBKB!nzy#ZYpjWeeTP)6zrGAEELVV-MM~4T|>qXwoM#qB##vzgC*X{AnqS z5+?&W&0#EWrj81Q{KrZtWv`d^wY?`5F=RjMf27xRy@#ZUYOpz1RR3#_oUB4+II z)nM-mKDxOSlT>|PnWx6(+9Q$*!)G)6R8I9}99F|U1D>cS6w!=bj*X{%#qYf)Rd&@S z!x7o0hzyacC~FawX0MOWc?})$E$w1fm79<|TN9H{6s~mPH44we)l6t@qO=5%Px!7y zf#OkFlQH_7NhWMBEAz2~qxng6P*_Fi3#ovhz1q8I9jp6NG?XpjlRCr2gGlzaF~xWG zN?pl%wit}aj`>WA!@0`J%8DwT>R>%MxsgD_u#ZeG?o(oe2^pD{V|tB&aS^%7hT%NR z&TJq>L)>H|ZB5xg8s9)njRoqWAx3z$HAu61zQmgv$N+w7>(#{8f*p_j%9793>l3s) z`-hQp)dI3xn2Ru4q;lU<8%TYx*Y)gePH+9L5NTimgZPLig`@Rx8(oaA=N_=uV~~i; zvDY+EEyby%)uT$)l^8YbF=fg4`I1fSs6)lD(WC;x3Au`ih90F$o@yjiF}$m+CVlRa zDI)J};8L1ZuaSlLL3wNZ_(AkXJ&4s|JczQ{*pwA(xQS0E7Fh$=Rkf5H(x=~9eIjRQ zhcxBV>OC%O{G>gkbTd-wAtFA^J|+?&3Kw5!L{X^nA`b@PCIm1U#>PyEC7+_r{aJ(H7yUu!KIQ+gK#f=kG!kW5jy(LRAZyMiRG z22B5FrW>k6bSkdqch9;E6RlkN7e$eGBpud4JN32tj0RfE2!^0IP0pwE~_%*NyD zLv+zvMo$qe-wf+f@^zzvQIPvN`7;%$HasI>EYk=TJgFdJg^0Wn`(Y8iX8itELOv8i zyt$1RpXf%ENYanm$1JN&u&lhzjbVYsx0p2!QUkJSi?jQ=9rBMY35lb{Pk<3hA%gc~ z*6(1YK{ZxseIym7+0w39QY_?g=|wgE4c@eOLIz?rLq5e=M6=sUo>8SJW?#FHzjpSE z4X7qAW>CwS{JRO(UgTX9NY)8T`YBc4N31l~f2aemzoq^LWKvE;H6bPgYut!fWPQ=7 zQ{IBoQgWye)wk%Md|L1KA9gfepfN9#3(rye`W4tv8*`T`+n^-7S3qRcZpK zQqypOKi>QtKU*uNy(!FJXSdKa+&?^BHURwbT!#4e82~d3`uLM|-8Lcixs7~oBPnb& zorCu~twM)E`{5f^lToqP^aPE#bsIGWR%6K|sJ}%F3Lx_u_iQpFKk2H;thZQa;ESvZ z!K|C6+0omj5wRlMv?7&%c8YHv-*Y7&z=Kg1{EgIJ(^ z8I3)e8#hSva!$+*;B|Ba_`#T1Fc8TR<_CT871jsh9YYHHaz+56Sb{($R!Hvx!RNjw zDuj-W;5|E*7|Y5-X6W>Ai^(ny3<_XnDXCx z8Ellf3^ACRTAqTKt#M8nWt_8|bB!FqnM@?(gwyh2AxGyGhm8dUG8(_WmVH-6DjW1w z>c*Dgz`)g^y%h}=mAE+TT6j5g6c?}bE6@;s=;(R|>y#LGl3X0+g@Snx%na>HrZVQ@ zw1bS3)^1g-n2Xy@5*n>m8CnhVx-_eL3d~$OXL0dbzd|nN;#zpnlr3@bDsoe6(|5Rd z)oOYSK3a(!20oghQDG%v{)V)smju%1Fte*9Hd~FsCV4qryfYhf@zUM84UJNfi)-~D z{vsFGCM@{Pyr3qnf`Q{Na&c|Vg1^Yct3=EC=10g~6$~7Ik&9<&G|Meqoa&6ZII4MZ z@ldz5o{O6llx%aOSq-R24I%v`BQHr^x5e}TRT%*oMVP>!wiT5=JRa)pV|5G-EJun7 zBOMR#8KT(!&UbNmK9<(v7;gg$6ybBt+yuffRk2xDk>NGGSMsJzi7>S0qBy)u zw<7Bc(qM+S;vou_uEviwqfLe(nArefMjxz*iAQ-f`-ps^4BFJkf;uQlsGl%dD9)NR zGsCn6b!552QwOUurE;i^siSnaZX;Jk>aY(7X&qNcT^r_by+|E0b>lBmhwWe@#ab~w z)KOWY4t?wue~~&WMIE#P4ocQww!)<2sl#T@#dL(k|fZCPaKS)OarcM zhpA~AJXsbF|BhgqF`A2-OWTVO8mMI%XOKe2&0<-02WEvzc6W+R8KTrtD3|qZU2Uty zoSPh=j<7dJr0_%ck{V!W+3sK7;+oczROElAca7ns+nM~LQ(|by@R8d5_OWZC%KoMd zcM&eT2Wg}&jjGXU`h3wArk zjneJ9(=x%U1#6;|Qo*W!whV5sj%0lCBxl(ats?t)N^+`3dXgS-W`T^*^|`!PITJWG z1oGi$vd}L*AkrqEg(fTbP)18(rPPr&wGrjF9Iw6W#2YjTi|?fN@zt%(@3cGPbmGfs zL8ZY<+#uaSDnD**{@K0WP)x6sLPd5lD$0CHB42tIH`{9wP7RFBPp>i2QuZE}y-d7Q zO+-+p6!dHyWS_*wDyenI*>8V3gJllQLH3IqGuODQ+?hQqI(s??*SUPpI#=lLFRXLD zeTBB}LRVMsvJ;}tuCDf#g|2AnP-oX*XHT@Ou&kp!>g-wGeuX=vWhVcwu=qVg-Amj1 z+Xj2vmagEgp0$Op&gGF0jrJC$cWrzBimu+v-Msdt{q2{#OD=cwI|qi`>78ra2io$h zhx&)y!l8kVA-A}_YiQ*VSG$)Exz@r^+w9Jsws{3YhFtehSKC16mF;bVQx88OiqkwH zB9qHjM}uT_S#Qr^`xS$(uzdMH7;|7~=|32AsHgpkzV>B-stdAf>`!Z&!Kf0wQz{b}kzg z^^yU1(SU0maI**8ApsZqW)xr!ay6ORM=Y#=y0gLZJ;TJ1JdTdw1vHYsW03_VR358(q=c?|OQRH6N{@;mLUW zAa&5&6ZQ7B_ft##ZfRlpUc=)yBwkl3HYpknxg_n0sH{Hh!JKz=(gWg#8tCX9>RKKx zZI2)lXr!NhQRs=fdP{MVsdcsYtQ_nRG5_Z=lFxB*>kJI`clNA|+6R^u`sjagKHT#5 zu1;!|=XVZ7P;XR-28h^|j8p7S%es2i7wAaI%kd*9yrsT8k^I>m-R-^>e48)p?d~h| z)4z-}S@jfX+m1GP#$ab(*E;nBq88ayGD>I9kaeZkxZcgnxu z3s?8Lw-$Pqb@aN^di#32dspAyHGynO&7Ph2T1-Q&U@=@xIBUtp+l3)+{ruPAgb zhnn0FR2iLeaK1n{ZI?Tz z3#N-ZuP{h?Tn|{(QCJJFa_4j{Z);V?!}+|So|W8x{jgB)A6iyWytX{a`Jj&8 z{=z`Ft}f{9S!vvlv30;0H&s#SYHKa@4|XWR-1gr7l{%TfZn+#icv0_4JD;G>*TJF`^W*w6~YRqsJ{QEG-NcbhdzO(e-o+3AhCmH994l5gmGH z)FbNcR&Dyg76q34Cr1`Q{fSpo&cTz0;J!1CZ5upgYR}=($-3{fLibR&n@vCLgs*kG zd`EA$ThF37EYu)VWwL1A6{YB#sPo&Tp%nXBER)r?PtE{zJUg^n(W zWsipSp$iZK+S|_VTwPc_)Jbnshe22w>~wR7R^j7habb0Tr(3kHt9P)oZDC<0o`nqN z*RBrRF|C8DqKv&Ok@z|amv^+ygVU^Z3)giP z=*w60DDK2C<9U7eg& zfL?U6h~dJYT?7FwEnHdXZ(Foxi1E)Yv(aDU?NATnKf(sRw)lh-qHc|KQSYcQgk=k9 zEp&CS>u={8l&8VBSi<74?&Ux~QYW6p&>N56+%quPc5#1i@8G4=_C^vSmDi1P+PcB^ zb0rG6a|R0hpWQ)yu5ND+ZCx5ihhTb8VlkIN1{r8yGt}O*tlhP$DU9vRZ%+;*blhT% zNVukkJ35!U6-d`TgUn}Cd!5|~=#rt^xnNS_Uc!<75%o(p}^%K!;F+G+i4FH zj~L;)xS$sAXfO1&EoIuZdY}#VJJ3OoVlW-(92g|`>yULcsdMIP=J$j$4#a*)8wJvuHm%Brj zyPnH?`2Ht80$p5C_L%!T>+^Us+bom75xb}uuDW$rw&Kb_3&Drg+l z=^Qv%ZyzV;s)gf`x|`G4>-wR~5O(GuJ;YyLJk-CM)49Fexy;$fNitpQx(j&Eq~|lR zcWFem07lE@y0D1U3OLJL>oT{1)R&FsPd1(FWJ)$|nLA`D)Yx67lj)H9TD@QMQ2_# zr)@$00(Z$<-6e}$s~cEYScs@awI6+ik$e7v#pmW1E;{3!a~HJD443wHVS(!^=r&zD zJAZC|@uKri%eS4DUo>Yn5R1HAZMyKh`SU}}qmP)nmxQLzJbZNIOHOyQ-F(IihJ@4N zle}Y4)Z>nqTzGQyrsImE(a_+EW_)4la^B)I@L8N0#}>u#H#vr}E8Fc(*E&N9p~9eP zO_cO!gtZ>c?3Q7G2h4QW%y0t?(;AeUXDExYZ-%?3rCjV&I;NM9H0X@};3u43ZW947 zA^J%Hfde5>oi#qCshUrTJxQUG_~v!pg)92{+n2@irj#PFUo}joyOt^+{MVDM4q9BN zF0{C1sLIw|+;XXkWAd^Om{A@u(+9ZeZW@aX5$cX~(~fYB(*8haD34%6Q+<~`JPsBE zA8cC=UnswV9;3f~`RGeik#tP*ni^!Cb5SxB1`l_g1AXe3GpF|VUOsR*V{_Mla+^?@ z%{(gd*Y-#Q-qSx@3Z6tVN+99wIoyTmz|?L|%X1MVF0OR-9xeiz+R;e~JCLVLdpK1- zN;+6z=$D5Syc8JJslean&_=53Je)S1MB##eM+;WeD4(9Y$)+Ivh8Yo4*!hzeC}Dyf$6 z!1$cU#ixw-Jj17_XuU&&ZN6~>p(+poryr$lDHbxxn&wl)R+6Fe`;?OtQXA5kj`lV8 zwH!`jgT0LWKB;6hGb2fhk$j;0;ldLGjoG z$&^&j#B3j&>JD}`OAyCuiuGjH)0#}NiZ;mh5z!huq*HjI&KVUuET##S-kc5g@5M@Wr{0z7{Bl>1#rlH8-78@ zzj?>K9sl(fRw~;K_yrx`^^Us{|4n7_-huz-5bv=N@16K>DU0_m{DO{iyyI@gFX(v0 zJ8lDhLC2%saqq_e9t$hw@4fg19r1Jj1;3!;DM;z}n_&-|~?{oNtWW3Mg-&PjyPW)d8@qXZ=ySwn;T^8@l z_yrw5@{aoo{(H*e-HZRevatK{3&(}~ z{DO}7-iPrEx*jgMf8|6--unoCA$jkk_=V)X-@z{=?|lsak3o`0`~<&nCpYVg+@IqA zb6LE<;1_hndHySYA^F_r@C(W3{tf^0Ao<+C;}>+?7M}eAenH2>A?!u`Q}n!NKMR~1`*HL5PqTQX zzAziVpyT9_-s$)S9do?n=HM4}%=L~t1OGV|R!XlGzc3{{SMFQz3zI{b+;i~@ZwO&> z7vUGCg?z|ej9-`;!sMQh|E=KY5GMCR{KByzOzy?_g=0dP+)MBa=X}~1Lhcg$LNdJq ze&Os8Pwq1O!isr-n$yV@WSCf z&vLu)3;FO2xxM&>WO{4x3$KQI<@VzjjttM0JA_|2B817k8o%%#;a<7J_=Q75Jh^Yj zFU$^kk$WwEAsO#R{K63-p4^-83(0uzz%P6)JVWly_}>W*3t@6^!7tns!sNaOzi>zh zllw9J!hYeoazBn=7#G6i&dGQz4)iUzkFWud?9*%UUtSjWPx!9}Zx8p%U5{VTG3Xt4 z1Aalrq26&f;lDYA9TLKB!7u2TW&auT@!uN4P7Pu2#{Y>B7KN}+;@?^p_8I)b4@14k z{Ve{^gCB)3xp(6K2G|+GAxqrhi=y)K6KaXG782oZy!2hDfEAh^k@C!O#3UOb? zzpE_XtN2Gkym(A;70!(XI$FKsa`>l*uqcGJ;6DfK4C%{l#oq>!U~ak6-v$2$OpQe&JIgOzw^N zg&&15xi{e#zWEMc2DuyXe--GM^*5i#`|#gi7Pjsn=4_ziW*=AX)%b;9H~28Q@4_z} z7vh=w2IdPO*}fmaFFY99Qtrp`3p(;Y_j%cff5gH{wBe@E|3F;ta;x!=1v=vT&*9&% zEZ#)?2bIN(@E=wdZz}%jW${|@zqu^larjRyi#H4ZoU(ZH@GmHf_ZIv@vK))>3(2ta z@C(VXx8fI)VHe^Tl67z~ejyolDSjat)`nk5hAqLr5+t9|fxovbULXE7;4FW;x&8Qu z!1*Ce?ppkpgXJMi?iKjgf#DD)_e%W#1o}dl+^g_k4Xz1ca)MGf_htOMLfG3w*em!29dUUNZA7jDIzAbA$r1Pk9r>U6dOZ@qpyR6{Y$kp|M__|) zA%5YP;hA!m;O`Cb7&7eW!@nLp8{)~m7XNh?uf)UdKA3S3=s3_jZU_F~f?tPw&1H%8 zG@zr!JFW%)WkBPfg5)m2U$A(kXDr1p=%{(p$6bbB&~YGxuiWMM1sw;3cNI;{6`~pUT4iivPK?Ff3&55U?@yLAi(F7m{Jk_=RNHtlOyr zkgS(s{2wU`Yr2DR1|;Ln#NS&MwhsSQWnow27j(Qb0jf9e)b(?!+(Xcrt{20l%Q*_aW>q{DO{+L1z9U{`)PgL|5O$|E;pH2k;9z z;y(8venH25;Thk?FX(tUw8x^YjOSp6|xsCM16RbC)C$bdaQTQ(c zNg3T$q}*XZ$J7vSD*ki8(}5qz-G=}BW$~WIzpE_Xa9zrM0qB@z|B;9B{}pTx>B-$V zG3D+DIwJc|Jp4Zc$^6agNx3$lBeMUL9shcejOTuva*aSoQ;64ue>V7Oc&^+Eu4&w< z3y?oPPUYkXa54C&I56RsU%#4b*2QrzO~f00`mAo_ICz#h?n3X*y4AZkeapM6UNm?3 zx@mdGv18mabFX{q1Ln3r_E>&{E^wq0xaHqcZg1fid_U#hZL#-^AA-$E^IznvsnHma z1@%A_tm()EfcWjEfJ4CH;7B0j)iK~ia59(;=7KYUYzK?Lg`fc1!Ah_ibb~cuJ-8OU z1H2Qw4`?d%G4M$svi~f&3&@sqKllcC5Ih9F4^$8TPvuwkrSd%AO4#1=y_xW2-oJ*w zJpYdq79XnTeZhWUf1o;_2;$=aPBf-Z0+Jup9yW!+O&&4bzcBZ<+$A_+qf6o9jfvzh*E$(>aty=n4y^HwCpT}a@#;<^taDGF| z+N|#w?{bSBzuG6|=$a$t;n${pyg}k;;>frQL;UjaTS#3rF--hqzdk#}FAuLGZk$Ku zPkEKAmagHaGKlim^HaP=W(&F=g;_%*wQ>Sn?qatDesK+V_;M>99dX)m`Mv)P(pX{F zugv-U9(?TR^7Rs~`X~?2QVx}`h4|{X#UqrjJp7)J{&B?Deev|1;sL|MKt?L;6dIpQNvrkbZgiFGBo2;wRhd=@7p>ygkIfqAWibh4|&+FNFBR zW%>DIh+iI_3-LD)KiQuuLj3aZc&-xD&0U$4yBGX`vHVE-=FzzOL3?*jNV%_pDV!I$ z{+4XYU61=QFlij)er1XJ#5;}$CxDoDXbg#ulQ_|Matb&V%mR53AG&@Tm<>(`bHEuO zK6HI9(Eam(#-o^5DjoIA2o%67AQ?jAl5l^-+yl2CD0~1{pqQp-7iUno#v?)N8@A)h zCLDpM!B4~a&v1qNVb(iwe+hK&uW*GkBIaede+LSG5qEbuAHfwg=BVRN2mHC2{Cjga zkJlz}>&RJzT^_=(z!h#JJYIvKIO_=$%GVrdoq?cr25-l`9`I-D3U1)!yPV&Mt2G5m z=N-5=gU1MeC+;mF{9U+$#{OGzg-1BwfGa%8`MYu71C-8taRsFluL<}b=kFs-C~*FM zTtQ>~2XF^aGtd3-$t0AHrt5%X~3V^?QiGghn(Mm zE1SLYxfxeb_-Alsqvy};@}CRgpU2$>6#q`#FMuBq=Pum4L-?0*g&z_A6v{~cUG>BKg1g(q#{ zu??JPX7~O}xc9HPg2JEUpP+PN8@Iy$&OhNc!e77@WY2yPSGH^%vtLJ?Uqg5ku58x| zk8RenSI4$$qKur(bwT#&*fuS@bkZgr+oBbJHgN^npJUsz_(g1U7N3Z1&3bOq#+`{fY+62e36zM`i$+QI*;w6I#1d~llIWq4k{aHZ2uI^B<-HV+%J^dIg|EH*);{(GiBct zl;@;vGilRI+A@= zxN}1IJY3lj75)}nLFp{Q6?C4o70Ny+DEvZPLHAyaE9m@ETtVlt4N&Jx2wMqsZwGE~ zh|`C=2AoBB(#Dsx?Onn3bzqn{Nn74kgk24;A$%D3MxgX>!o3yfxf^g}TipjamyJ&0 z8*%RdioXf>^C5g2?wuk0E?l98IA6iN2k73|<|cca>}-PUM6r$S#xmR5!(5k5O}s0% zr78Xn!X5|8!_&Aw07^f$naN(Zld#xUCi|E$hWNk1m2FJ%W1H9p&SP7cc-nJZ7nJ`O zabE(%gvU0ow{tE#m!SL{+URXu*Fuv=a4t0dY-Hp}T;ao<&%_nzVxw$WO9<-)Il}vJ zW1H2roL>h>ek8V09Y~x}wkZ@%vPp@zByCZ#4Jt)=Y_@TfNOq&xW+Z!2Y%5Y8VjGdtiETr&3&l1e#ffb}iWA#_6rQyG zByB!PTaRo!X92}O8&^1a?a0V{T-kmU9@~6$9@~0!9@}_y9@}=5huEegdroZ2QJmO@ zqd2kcMs}OnW}`SsTTN`EQFv^dksT$r$;ciP+hSygiES{lzr?l|#gA<+vbV&x7TH;1 z8;k5Kv2A4|V|Hv)(Q{*4iq2&}5oAAk5Lb}hB(|BzUh)uOj{ueNdECE;^P~+WX*-E+ zCK2h6vXx-tkd0(2;Yr&_Y!gv<(iRfiKxPr1w0*=jk4WJYOSX>K#-Z?0wvFFgF$dPSO=~G*8~jXz5~1yd<1*~d=h*bYzAAw*TA#jFCac`ASYu9~#*_7`q<9VvI*s?xnmV+Z~}f@i_=VEd%!CcQFg zL}mgzhHI{^xxVI>npM{4qJ@szEI{790oWfL722ewY4zx^l+!85?KZFH-=_pEdyJ0_m{V z2e_#tQ{91+4t&FbQx2RpVUf%m;gD|qHf$wWOR6f327glZld7>}#*X=U_0OvtCN@mW zMq{HRqG{2RXnC|E>Wwf;zBsabWcN!WyGHIKec`cymN$_{u<>5%9}GO6a#ww%=+S4SlI=5QIY_FcdKwu#SA+=xzd2Z)cB%9L9MdIP*I;I{bke<|N_o{Kkg^1q+| zkjg&v6>uz=3*44tx6InIU`y+k3%6XdrESZ`@z0Ncar~>}`?lV{b=%mKdlWD+d9jp- zvU*@9>TMaD-Bx#x`x;iOr}(|V@1FF}(!WaoHvNb6NO~|cn7M}E_55z+S4rE|@teeN z3cp$W)Q)Py7&rN=Q@(Yt+=Eny1QG>O4Uo;q96Aef2iZ({~N3QXZ#={y9Z#=4TM&r?q3mVU9 zY-@Z+<2xHSG#+~Jtb@-wc*(&dhq=QCj$C`>`;Pp;kt4j0eD1Vor|+81gsr8DUv*2= z($ezgmXlgeZTU#cM_V@X+tu<)%Z3@Z&DcKU7c-)nZ8O);{NBtFeis})a`g5EBMaOe zjd$F1$IW-NY&w3^w9V5te~;hATQA~7h8?(W6ASM2WCy&CEq z*_|4RMot`=HFEJt`$!+ZkB{6ovUB9uBflB>)5uFBuZ~z7q_7KsG2m$MW^gLl06q$K zfLFjX(Bv-g^WK#E1&HaJ2<~~{9#6SL!Qo&9SOrA)*MjT7EnqYF9QX~``EM!r9B|)H zx%0sia0PJx4$lPVgO7rbgWJIW3ivec?O-$b4EP+l2YfByKHP7C2SMc%lnc~?day6p zA4~>s0LOz9!6{%CI31i3a29SWI2U~S$&}j!9(^k1z6(acnm?r67eVTeyxR!evy5+` z1-ut*1fK(Ug8RWY!1uu8;CUcr=4ZjL!3ap9%uItEI1$VO^FS+j3s?f$ffSujq14<7 z{s5i@uK+1G2f#3R8teqW2M%Rt7UaNO&;O*!w=3n|1O5d(0-gmgfpWh1^UR+!!$&=L z)JsQ=90i~KnTt~HLvQ5%gHx^t^npPz3}zofcs1<|ssn0qj{$E6$AOaqPQ?{m#dQ@o zR!pxPo_y2fBM&o$%Ga12=BoxU3vysQmx7pL4k<$)>Rp7Q-EPfq#Kl%Gub^OV0%`P-DgPuV@?(8fa>+qbrFjq@UR z7QFdgU}J#$H{>G_A8)I@w)Xnkf3Cf?_T9Dbt=&|+rFL8G7i#aS{Zj2cwfELOSo=`z zzt%ol`&jJ`emiS_QTyxKztp}|J5n3pzvLkJ4p<2~z$)-AumQXqycc{BYy_J@sy0(w zSzB8>wl-HgzIJNu5w$I~Gi#5oJ*M{9+T&`EuRV$1DYd87&aItSdv@)D+PCn#u=bML z%lNIRU0XXm?L*T(GVQr(Zu%3`D_bgC#_(%wIlSe#mJ?gto9yszyU%>`sclbv`>98t+V#}Nk*|+@bL63sM@GIk z@^2$gjr?%r$A0Wo2I}d5pamQcq6u$G$d-sY@SMMbzk%n$E-(V(u48u{x9g-`r|_G#E5B>@uG4p&vFn^&`Ih&$e5~a*sU}=%8)Mg<&@DI@m=R3l zLO5oT_Ico~piR%o^k%NFxS`_gs`IM)_`RiOam}^^w;#A;^1n^~_sKga|9tXqCjXJ& z-}t>a`K8I*4|?gKT?dUER2S7pJECW!BU+kUKGgEz7Pous?r3-O?pL8RVJEVHa3Xy} zSowI$b%K8aZwJ?dcY-b8v%sYqc$c-oEn!a453T^~!7OkdxB#?);mwb2-m&=yn}53b zXPZ@|;T&Tph~?|yx?AerRkxw;J$0Mvw$$BK_ocdf>h7(3pzhms57#|X_gLK%bx+p) zl;6&}U)24&?$339srzePTsLw*(eiT3t1Tlf&(0W`v18`$neOPf9=&3ucVx}T$9$Vo zzcQpQzmqZnx4C)qbbiG&YT-Yi5>$aYFdpm&CV&ILG2l3G0yq`S1Fhf!@Jnb_km34? zTPW{@pG?>};kOf>o$%6xod=8@;KrrgK43gJ1#APq1J8n&K)gO^i`#Jwm?@a#^8Tk+CKk@5BPF|bfS9|iR=QA&4-d1rlW1^o6URb%L@}@wO zf8}ecXI1ssJpB7rPw@Ly)vv4mRQ2bom#bc3Rz6ad8iwz@@db}p)EB&>DugL@NtGzGqzGvWjFV$9N>-gw$E;~LuHG4$1 zB|9^FboQ9+@!6C4U6Q>t+mv+v4o$i650zU+sxAI^T1-^a7JWj~qy zRCZH#OZIcwd$K$DRo2zjHPq$m#??)&JEHFRx|8``P z>r)La4Ko{#ZkW|@M#I}0-rjH>zZ)8EZn&l4lMSEdcSpmvhA%YS)o>rb?F|n!e4F2o z8-CWn)O75uv2(|sIks!;O=E8v>vBirPUY8{J1=)p?$TU=Uwdvvt|!-*8_K;c_bz^W zj{E;-a>(%bTgS(9$JD-E`}gj@e*d@a|Ka^N?*F^}|FZv!`@0Es6B;J$Ga;HVW5TQn zZ<(-ULf3?z34IfWC)_pRDSkiZ7frlk;_$@lCf+!4)5I1G*3BJ7DmD z;RCiFu}NzM$0jb#wWGJfl0ZeM@<$8O(v`>$@FaL1H8 znwZ_b^N#!P_~spt-0}P!sZE(pm7B(Fs@+t#scF-!O#_?WzUi(_f8F%Lrd|AA-L!jC z?dC%^w`@LRv&QP{Hh;n9!#g+sa`Ue@|9SJvn|E(^Tc)CiIBm=6Th89HWXswuSMs}N z%jdV;$?r>B?%s0GmixAB=l4y1Kicw>EjzdTZp&Y{{B6tLWZIUk7j3;{YvaHX9I*#92rmNgl)KxZ)oG_9fxoBj?UgZqtZ;tsZI223; zd{@Dp1WpF0f(4)zTndK4%W@f;KMFPi(JNH>;y^q$<;8{f(RTB zhQXJ?*TMb3F~$lxu(xq}3E@|PVenC~9Xtg775oy!`p;M{S%OR=d1V;98)zZkJP_;G zW8J#sz&C>72IOF{4crObSo96xuz(iaIY7Fw2S7Y;%OK;t8C(lK4|agxfXqI$J2*W+ zIyRvd^nfHei-m$Tp=k}9Elt;3~m571>B7L&)`<@F>o8$1SEg_6#Q4` zTPGtE3i13(^Qr=H`=T!dbHQ1l4HUpI_&j(3JO~~N7~T&(3V0g)2)O;(6$+dlFpRqe zd?mn5@b(7HvyTKDf!^mB0sq;&eLC~=Qv>q2!bWfh*aCKdX99kKE4TwavbZzB2?4FR z!X@Ax;9~*XabE;(a!Ic}jq_On{kXRR$6TrkRD&9j1ufu=fW6Jj-oZ7^#e|)2px=OP zQ#@ilN>Ojp;`IncJ4^>M>nidAE(5V%->s&;!7MNvECZK=tHG^cR*!!V#`V&kpf%vV zxVM3w;2H3X0N0mtFWgA^Zu0W4`)A4sBy%U{HL?8NcPDeEFL3?d*VmK$e_3z1{Yi9T z;D_MH;AQX%*!L-PM&M20Sg;VZf*#NZZu-C4I}i9MiuUp6N`R1r#6}C4L|L>U^8Y?Fvv+%YmjFuC z|NHa4pC_B0ot>GToqgunX^WhSEJm7;`;i9`X@^XC$CXlq?2PP+j5D(8UE2MSl#lU? zNdKJ7KaxH=k$?NabU)Z1Z7)b}N5|~vM>{>$X?3SpwH?h%qy2p?{#|XkdQVH~*}G>^ z&%=98>KW)cwdeGnGkdPUhHT#2Zu=GH_sbs$V$+r7pORlzbbQe^i%z!LOU;Y4jZ(R^ z3OgkQd&IISQhMy%V@QuZmHn#TVX=Sny7lW;+-*p=QW({3ybSS+{aUKWqdxwaJ+k_m z=4+z5C>mBuN;z{`)rkPexU1)ISZuoZNHZjb{#As6zY7xad{ z;Ddg!9c&K+U=ZvGJG%zEN?<4qgHqTHM!^`^!?mYtZ`cRM!@jUT8~_KwA#fNR0e&cl z3JAbtsD`Of3qhC$VQ7Hqa10y^vs{g?xo{$!0;jvqaGe9^!^N&kU01+W@L#wV76XQ= z>v~uQx5Djkr|T})y{?t6hv6}J5}tQ$i0huC=7R(x_5)!VNci__JQ&4bKU2=Z*))dOrvEsOiRaf&wpr}oe$S}p7yNv zJnMPU^Rnkvcpct^x8WUl4?cj8;1l=^zJRYh-+I1>pWs)|Z=PbW-&+n95P->04O5{O zf-nuj&;Zk6Cj1AEgX3W~oCasWS#UO-3+Kaya4}p8m&28C75o>jg+;IgmcsRLBisbH zz-@2`+zEHXy|5DQhX>(dcoZIoC*f)DGu~(6d3X_ChF9TrcoW`+ci=tv06v0G;4}CF zzJjmeTlgM+grDJ8_#K)-9$pW~uRWweI%Gl?YzAAvR?r2yK@RkUT*!xB&>Q-K5BkA& zusx{uDf$+Er*A>}mgSv1g}xlEKQHO&+S;|X2U4Luq(M4lLKbWWTfkP(1yG4w=Ri-$ zg?#7*y`eAopdV}p+rt1D1UtgcunP=H?P3}jg-Q~yJj`t4==*Y@G86xZ^GN~4!lR((dY0beCudG8nJN1!jUi;vOrU)UcGfP>%=I1G*eKa@iS z1Yj~$!&In+AWT~{W6?2iEF2HBVJ@5qC&TG*CY%lDE;@hFg>W%k3YWu`a25O)t_Arm zfg9mAxC8ElyWw6~2@k-d@HqSczkt|^WlN{fp2dm{rtM1FpTsPSjxD6kN7hxa+Ba62 z_vkY7zSsQ)`d5*0h&5hgGXKv(E=6ufS{j$}497l2JTK~T7(26-aTZgNlaMQsyO8IR zFOl}VD{X@eK@LQM$f<~o%do#!y~Do!y()+IB>Q{S0qon~tIlHI{$BMM`|@rjVvTiN z=1%NWk+Da|z#)vBlW|7UCt~$^*!w%C(W5bjws&b)|Baq-X_p?^b!1m*XP!Y@auNN) zGXCIF+Kuh@{;@^J6-k?{Zf{LB?X5%T1H6KE)^){OE!b+oPqe3IEX<${_4tLC(T*x@ zsP%9P{IuxjMKV64t@ry(w~Ynzr74k~d60 z$u~*+NmjMcKk`TWMXY}LR>xn^*YS7uk4!NABmdX?L;mgmh#znEPwD^ox8FmLAN`~K z9?t%b6#6mj{Tyx9pFw-RwC}gruKy+WGxC3ZKFc3%#~0gIeh;}Gay<%9z&CJ8?pe7P z;+?C987@yU?Lm{2g9LoI2;LO zFbOK53Z}qOPy=;P4Jzy^w3*(^PQ|}4E(IDf8 zcOQrHbf!5G*B_JXl64ko~U zFcA)fgW*s(9FBxCm;{wj1ykTCsDV1DhY&>IXqW-Vz_Bn38etBc04KpIa4MV*XTp3q z2hM{lU;$hW*T6zp3{7wy+yKkqX1En@hvje=+yg6M72FRG!o%<=JPuF7)36$zgBRc> zcm-aAH{dN;1MkB7@F9E*pTg(xC9H*S;5+yMeu7`%H&_Q9aNu0Jfa&>}`PuoK=eIN-usDBE{xCHj za5Q59=c=)QWkqF0lZq;fCPOt$h1#O}q7XE|tfI!EIdB4;1gF5Ma5|g`^Whvg4=#X< z;1akDu7Cw_HCzJ=VKFqpb#MbLgPY-2xE+?mU2qSqfK_lmJO~fNqwqL92~Wdncn)5G zm*5q64c>saU=6$rpTQUK4U{t4a5oqQV_*;13&z4Ym;n31L^u!*hC|_SI1!GJ zOo5}I1{z@woB$`mDR3&B4rjuAI0w#y3*aKS1h!$s;|J?4D11W!B`jv6JS4>2nWK!a3~xOM?x7)f=Z}@DR30jKpo74|G;sJW-V%j zIdB4;1gF6nFdxo=3*aKS1TKRsU;$hW*T6zp3{8t}ShQ@>t&47ld}Jtc08)?4Lu8(zj2C(r zk#RyjXp5HdK?fo-E@(a?*SHtZ06kW-OjJ(g}lT(`?uS@-|nM!AGiCo-52dPYrh#&Z}w`xu>G?3 zpSAzC{qNAZL$?k&9eQ=>-Jx#>Ux)2F9Ma)1GZ){JR+2U}ZCKj)w0+YKN}I%dx!KJ7 zz6VxB=XgJ*=6Ju${O)xi^MsPk1*-2jtz!eoyrp|!g>8<~yUb7eg}F(tbWi$F7?wUN zefRV|()Ui^C;fo*gVHCZSESE@73uebD|4UBgJ4o- zMds|xxtWi{Gnp@Bz67sizMc6^=C_#xIt}QwL#L8XyLTGb=_a_f(>|fF#C|~BeTo0CuLV=PtLB*o|YZS zo|An>_E~UA_T||}Y~kNx^DbL<8OS`N{g}rd>Jsj9YnSJlMe=5s^sbp*PwaY9*Ck+$ z@#(^x_XD~g*}bg$vE7dcnfsHH3yRGN z`q4HgNah25RrGby@!K80oy?gmWZsm_4GJy{EsQKYZs8TopxJ&c?#1nZNf3*B zE$%B-z~aWmvlrjG_@TvX7Jtnw%I3v=m{+s=lKq!7E}6UJmL;o}d;mV?j*o<~%pdmwvwVi>1;Ltmh^%caxuUe$vs5 zVLk@owJc%YP8M$Vc{(yz=L6(JWLw7a%Dk?notS5gjLBkb9+JYCTsJZp8H33B0&|dM z$X!SZV{P3?Uqt4`k4DBIVIz%f=ODKrtB}W#Cy}R-XOJSs+U|_V+#iv*5t;v!!q{1v z_b79%WG>?{B-wmMYaZhyjwhSPxZ{?j2RYKnGPVyOH*V!hxeZy4tU}&E-b9K!qhpb! z$Q_8ajz46Jj$>oD9(jqJvDB=RisGV&U-26^8Iufr)FkwM5V$Pi>0vb&Le z*&c?Rid>9r&)8UN9f;xle-5$;S%Tb-3}Ec*PDqK7p=@_Wh9jeq-Hn{e);W*yLfpP( z%oP)?*E)i=U;^p@+ZXF3ctLMYjvJD|E&5PUZ zIqoBp@*43VLy#Jz!N>`0MJ`3IM6N<^L^gQdENw_TA)hlQ^ebdFV?tj-Mp0+%g;?|Q zWIVZyC6{r-KOxaybl#Dr2gft-s3Nn9IY*`F|05ylmw#57=jSuFKOpto6B*C!yid_{ z$aCj7=a%lD+`9?LA&B+!q`0jsDt z9#QiSpHTA--P9SwGD}T;F;>+VbEqqx$$U0iM~Ln}9{Ob$WeGEioUfue1^QrNh1G)|BHn>~2?%mPv2XsFO%Aulr zW%t_dq3&LE{EjdLcFh@)GZKA2N9p>jau((+%4vd+;M1JXbH0Rcl>YD6V}~9)sWe> zPJO&9dRD})k3}boK7Jl~19=;<^s(q*k%N$fkqeE8-W3^UMD(r5O-62ID`M$YnHPQ@ za)FWWjb63%r=>4NPgWt8o;(Fxbw&3T-QUbxllN}k`+4=)7GmRHf~=w5Uqzk2cInTt zGGxZNKVtOS0&HHH4|EUm4DuY(j5H!wB3Apo=yFSs%RGhXPua^Sx3RtK#$FbSd1%^* zv^~=HftcMqTiMO`VK+YoF?-pq?Bx-Tx$`l5d5*G|?^E{jqs-`ks$3`4 z5!lT8D0}(9sJ*-@eHE7SQ`pI3DT}RKn#5L~t!(9$87r}sAI^A^xz^fFb}2h~1a|U1 zpzY(?%07P1*vA`c7f;KYmDQNUF5WJ?ID26B&e^+Umt^mXjeM}Nk+p3+C;P)K=c6Ti8vDC{(}1RdO*=;I@UczDLNYu2^QJF&8h>c|VCe@-KZY-o*y8d`wY5D?7fXtW z-5#IK{w>Juh&UHlwQ$Gwxc0)!XVw>CT^IOp zFR~J`+wX&@H%gFQjSOdN+4Ex4UvFd?+uIPa@hv+)mpWz}q&LzRk@fqwr=Hmv*#!~% zU)Hx7iipiGBDTKB3y5X!zs~<+^NZN+{lU~N$?W|DaX$pH?EVY*|03jKq?kI!vj2DG ze|ZP6zXvq2zYMt=`wOdy`r@pCc8OLf6YrbF^?@HB39TG&WUn9@M`sSG~ z!B0x|mDy{Uw_VnBe3NyqY~_13H}eIiJK>&`6)9!ys@tt?_j9{d?H_Ajl@?^Jz^~H2 zOZz#ks$-C~Yrg7Ol^#qFrB6@)F#VhKs*GU9jEq@o9gu@FkK~o+^E&vUhCG_eO~wZ-7oGwA?J{sWjS}| zlro=cLXSgw)aS{%a5M87^XBDE$e)vcBCEiaZF}jqpKjZ{?a_VD?fZMt??p7Cne}T* ziq9EvK5M)A2JSI%{J?!#N@b3%^=eym-gOs~5kzIAuwiS_5V6 zlAo8zI(lO7WH)zH?V{E?ZKW>OP(e;bPD9?I{ZH0s%cHHM7c#<#teGV8Eb=07eacpNHmm^mq^4|9qVy)+5 zt@E-Zo$!%gXuEAjto3rrXj_r>IeTVd(<1vK6Oo4ySu4<5$8jxs{AWbg861wRMqWkU zLB2z*^-(6E6AwXFBd;P>IbKCseGDl^hYdm2pu4_7taZ7p^(3wL%LP35vYyc@=Fh%> zq-?9#AG6B&1lj}+K@LO8kw)y(3&ci!POocM_B{6ovDS+#eTVt>$XedPe@4V!eFm}C zO_lZJmLk_9HzGG7*7|bWeSzLZ)H-utv*rw9t)JG&J(GFz*8N+6j@9zA649QS;w=b z`@b>weHU}zKXKgmL#QL1_uYA)Te^?d{fpiYv!;mXjkmhJ-7SSOco=d7QjV-*U7X+B zH@CO0S9DI9(jBMd+jWKL1Mwrzc?46`oyJie405xE5U~dQfy=Jvy)uy(juk z)*O0`bjIs3S<5m}kF}(`L}yuX%hu9Q4Wzj>{q%S1pAFGF@+~Y&zmyog@u|@phf-!_ z{aH&ttWOVE&-=zc=Q4L*Bsvcs9U|kxiV>OjZRr&mCpI2w?0i}02|bRNrP0;T>MvWB zfxbg5{c9ahp-zzcLe>S@9%(dsT-F7VcJl?u1Bk2#BK1cKI=L@WhQH&H6vCACFsz^S z&9tdM#_O?D4Eb`)hXD7E`w1!;4$ib*}4t zDfiA=oA!k+FLimP%WGXyx_0b3s@v#pvTpH$?hCsw?tXpuLvza18p}g^4DT_Ed%dd1 zBdlQie2?tBzInxYBlAY*?VGoM-jR97v1aWVtXbQkS9&jBufkqa`Zn}^sPDslKkWNe z-?_eve6RRk_x0RZ$;}^Z?k^8`t4Hs_wQfae>^MJ?#BQ$4{OzKR=j0#F6-46 z7w-yst=eCU*D;?vb79uPFwBB)SRXpFc>3a}7eBN3r^UZ4{tf!GZkiwNV@)?%&rQ|? zeyi#2rnOC9H+{DBGsn8MOXxjaov2{eObyh8VUe@*&*%@1B2r|mZh1fjOHYe)>i^y7~A}7Cw zU5X^E2hVw<5vTp+9A{g`Jrlb$x?YM=5b_<%;d!Nb6JgN09oFr$Zu~ka6PEtij*lFi zYMyO*uG;bDlAX6zUYGt|`gezt{zLkgLXYAes!U6H9!CES)E;uvc~8>b_H<7J@Jh!q5N@!$

$+|y7z`ya6ox@5>;|J?4>%MKha(}aIjwnDkY}$9 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 diff --git a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/optimizations.go b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/optimizations.go index ecdd8d82c1c6..92ef107ee52d 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/optimizations.go +++ b/vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/optimizations.go @@ -133,7 +133,7 @@ func (c *Compiler) removeUnusedCode() error { } caller, ok := c.funcs[callerName] if !ok { - return fmt.Errorf("caller not found: %s (%s)", cg[i][0], callerName) + continue // without a caller, it should get removed anyways (right?) } callee, ok := c.funcs[calleeName] if !ok { 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 25cbc13b4718..e531a9b9b994 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 @@ -32,7 +32,7 @@ const ( opaWasmABIMinorVersionVar = "opa_wasm_abi_minor_version" ) -// nolint: deadcode,varcheck +// nolint: varcheck const ( opaTypeNull int32 = iota + 1 opaTypeBoolean @@ -90,6 +90,7 @@ var builtinsFunctions = map[string]string{ ast.Floor.Name: "opa_arith_floor", ast.Rem.Name: "opa_arith_rem", ast.ArrayConcat.Name: "opa_array_concat", + ast.ArrayFlatten.Name: "opa_array_flatten", ast.ArrayReverse.Name: "opa_array_reverse", ast.ArraySlice.Name: "opa_array_slice", ast.SetDiff.Name: "opa_set_diff", @@ -162,6 +163,7 @@ var builtinsFunctions = map[string]string{ ast.TrimRight.Name: "opa_strings_trim_right", ast.TrimSuffix.Name: "opa_strings_trim_suffix", ast.TrimSpace.Name: "opa_strings_trim_space", + ast.InternalTemplateString.Name: "opa_template_string", ast.NumbersRange.Name: "opa_numbers_range", ast.ToNumber.Name: "opa_to_number", ast.WalkBuiltin.Name: "opa_value_transitive_closure", @@ -414,7 +416,7 @@ func (c *Compiler) initModule() error { }, }, }, - Init: bytes.Repeat([]byte{0}, int(heapBase-offset)), + Init: make([]byte, int(heapBase-offset)), }) return nil @@ -1058,9 +1060,11 @@ func (c *Compiler) compileBlock(block *ir.Block) ([]instruction.Instruction, err }, }) case *ir.AssignIntStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Target)}) - instrs = append(instrs, instruction.I64Const{Value: stmt.Value}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueNumberSetInt)}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.Target)}, + instruction.I64Const{Value: stmt.Value}, + instruction.Call{Index: c.function(opaValueNumberSetInt)}, + ) case *ir.ScanStmt: if err := c.compileScan(stmt, &instrs); err != nil { return nil, err @@ -1073,12 +1077,14 @@ func (c *Compiler) compileBlock(block *ir.Block) ([]instruction.Instruction, err } case *ir.DotStmt: if loc, ok := stmt.Source.Value.(ir.Local); ok { - instrs = append(instrs, instruction.GetLocal{Index: c.local(loc)}) - instrs = append(instrs, c.instrRead(stmt.Key)) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueGet)}) - instrs = append(instrs, instruction.TeeLocal{Index: c.local(stmt.Target)}) - instrs = append(instrs, instruction.I32Eqz{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(loc)}, + c.instrRead(stmt.Key), + instruction.Call{Index: c.function(opaValueGet)}, + instruction.TeeLocal{Index: c.local(stmt.Target)}, + instruction.I32Eqz{}, + instruction.BrIf{Index: 0}, + ) } else { // Booleans and string sources would lead to the BrIf (since opa_value_get // on them returns 0), so let's skip trying that. @@ -1086,97 +1092,131 @@ func (c *Compiler) compileBlock(block *ir.Block) ([]instruction.Instruction, err break } case *ir.LenStmt: - instrs = append(instrs, c.instrRead(stmt.Source)) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueLength)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaNumberSize)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + c.instrRead(stmt.Source), + instruction.Call{Index: c.function(opaValueLength)}, + instruction.Call{Index: c.function(opaNumberSize)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.EqualStmt: - instrs = append(instrs, c.instrRead(stmt.A)) - instrs = append(instrs, c.instrRead(stmt.B)) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueCompare)}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + c.instrRead(stmt.A), + c.instrRead(stmt.B), + instruction.Call{Index: c.function(opaValueCompare)}, + instruction.BrIf{Index: 0}, + ) case *ir.NotEqualStmt: - instrs = append(instrs, c.instrRead(stmt.A)) - instrs = append(instrs, c.instrRead(stmt.B)) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueCompare)}) - instrs = append(instrs, instruction.I32Eqz{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + c.instrRead(stmt.A), + c.instrRead(stmt.B), + instruction.Call{Index: c.function(opaValueCompare)}, + instruction.I32Eqz{}, + instruction.BrIf{Index: 0}, + ) case *ir.MakeNullStmt: - instrs = append(instrs, instruction.Call{Index: c.function(opaNull)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.Call{Index: c.function(opaNull)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.MakeNumberIntStmt: - instrs = append(instrs, instruction.I64Const{Value: stmt.Value}) - instrs = append(instrs, instruction.Call{Index: c.function(opaNumberInt)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.I64Const{Value: stmt.Value}, + instruction.Call{Index: c.function(opaNumberInt)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.MakeNumberRefStmt: - instrs = append(instrs, instruction.I32Const{Value: c.stringAddr(stmt.Index)}) - instrs = append(instrs, instruction.I32Const{Value: int32(len(c.policy.Static.Strings[stmt.Index].Value))}) - instrs = append(instrs, instruction.Call{Index: c.function(opaNumberRef)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.I32Const{Value: c.stringAddr(stmt.Index)}, + instruction.I32Const{Value: int32(len(c.policy.Static.Strings[stmt.Index].Value))}, + instruction.Call{Index: c.function(opaNumberRef)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.MakeArrayStmt: - instrs = append(instrs, instruction.I32Const{Value: stmt.Capacity}) - instrs = append(instrs, instruction.Call{Index: c.function(opaArrayWithCap)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.I32Const{Value: stmt.Capacity}, + instruction.Call{Index: c.function(opaArrayWithCap)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.MakeObjectStmt: - instrs = append(instrs, instruction.Call{Index: c.function(opaObject)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.Call{Index: c.function(opaObject)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.MakeSetStmt: - instrs = append(instrs, instruction.Call{Index: c.function(opaSet)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.Call{Index: c.function(opaSet)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.IsArrayStmt: if loc, ok := stmt.Source.Value.(ir.Local); ok { - instrs = append(instrs, instruction.GetLocal{Index: c.local(loc)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueType)}) - instrs = append(instrs, instruction.I32Const{Value: opaTypeArray}) - instrs = append(instrs, instruction.I32Ne{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(loc)}, + instruction.Call{Index: c.function(opaValueType)}, + instruction.I32Const{Value: opaTypeArray}, + instruction.I32Ne{}, + instruction.BrIf{Index: 0}, + ) } else { instrs = append(instrs, instruction.Br{Index: 0}) break } case *ir.IsObjectStmt: if loc, ok := stmt.Source.Value.(ir.Local); ok { - instrs = append(instrs, instruction.GetLocal{Index: c.local(loc)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueType)}) - instrs = append(instrs, instruction.I32Const{Value: opaTypeObject}) - instrs = append(instrs, instruction.I32Ne{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(loc)}, + instruction.Call{Index: c.function(opaValueType)}, + instruction.I32Const{Value: opaTypeObject}, + instruction.I32Ne{}, + instruction.BrIf{Index: 0}, + ) } else { instrs = append(instrs, instruction.Br{Index: 0}) break } case *ir.IsSetStmt: if loc, ok := stmt.Source.Value.(ir.Local); ok { - instrs = append(instrs, instruction.GetLocal{Index: c.local(loc)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueType)}) - instrs = append(instrs, instruction.I32Const{Value: opaTypeSet}) - instrs = append(instrs, instruction.I32Ne{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(loc)}, + instruction.Call{Index: c.function(opaValueType)}, + instruction.I32Const{Value: opaTypeSet}, + instruction.I32Ne{}, + instruction.BrIf{Index: 0}, + ) } else { instrs = append(instrs, instruction.Br{Index: 0}) break } case *ir.IsUndefinedStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Source)}) - instrs = append(instrs, instruction.I32Const{Value: 0}) - instrs = append(instrs, instruction.I32Ne{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.Source)}, + instruction.I32Const{Value: 0}, + instruction.I32Ne{}, + instruction.BrIf{Index: 0}, + ) case *ir.ResetLocalStmt: - instrs = append(instrs, instruction.I32Const{Value: 0}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.I32Const{Value: 0}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.IsDefinedStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Source)}) - instrs = append(instrs, instruction.I32Eqz{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.Source)}, + instruction.I32Eqz{}, + instruction.BrIf{Index: 0}, + ) case *ir.ArrayAppendStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Array)}) - instrs = append(instrs, c.instrRead(stmt.Value)) - instrs = append(instrs, instruction.Call{Index: c.function(opaArrayAppend)}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.Array)}, + c.instrRead(stmt.Value), + instruction.Call{Index: c.function(opaArrayAppend)}, + ) case *ir.ObjectInsertStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Object)}) - instrs = append(instrs, c.instrRead(stmt.Key)) - instrs = append(instrs, c.instrRead(stmt.Value)) - instrs = append(instrs, instruction.Call{Index: c.function(opaObjectInsert)}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.Object)}, + c.instrRead(stmt.Key), + c.instrRead(stmt.Value), + instruction.Call{Index: c.function(opaObjectInsert)}, + ) case *ir.ObjectInsertOnceStmt: tmp := c.genLocal() instrs = append(instrs, instruction.Block{ @@ -1203,14 +1243,18 @@ func (c *Compiler) compileBlock(block *ir.Block) ([]instruction.Instruction, err }, }) case *ir.ObjectMergeStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.A)}) - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.B)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueMerge)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.A)}, + instruction.GetLocal{Index: c.local(stmt.B)}, + instruction.Call{Index: c.function(opaValueMerge)}, + instruction.SetLocal{Index: c.local(stmt.Target)}, + ) case *ir.SetAddStmt: - instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Set)}) - instrs = append(instrs, c.instrRead(stmt.Value)) - instrs = append(instrs, instruction.Call{Index: c.function(opaSetAdd)}) + instrs = append(instrs, + instruction.GetLocal{Index: c.local(stmt.Set)}, + c.instrRead(stmt.Value), + instruction.Call{Index: c.function(opaSetAdd)}, + ) default: var buf bytes.Buffer err := ir.Pretty(&buf, stmt) @@ -1226,8 +1270,7 @@ func (c *Compiler) compileBlock(block *ir.Block) ([]instruction.Instruction, err func (c *Compiler) compileScan(scan *ir.ScanStmt, result *[]instruction.Instruction) error { var instrs = *result - instrs = append(instrs, instruction.I32Const{Value: 0}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(scan.Key)}) + instrs = append(instrs, instruction.I32Const{Value: 0}, instruction.SetLocal{Index: c.local(scan.Key)}) body, err := c.compileScanBlock(scan) if err != nil { return err @@ -1242,23 +1285,22 @@ func (c *Compiler) compileScan(scan *ir.ScanStmt, result *[]instruction.Instruct } func (c *Compiler) compileScanBlock(scan *ir.ScanStmt) ([]instruction.Instruction, error) { - var instrs []instruction.Instruction - - // Execute iterator. - instrs = append(instrs, instruction.GetLocal{Index: c.local(scan.Source)}) - instrs = append(instrs, instruction.GetLocal{Index: c.local(scan.Key)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueIter)}) - - // Check for emptiness. - instrs = append(instrs, instruction.TeeLocal{Index: c.local(scan.Key)}) - instrs = append(instrs, instruction.I32Eqz{}) - instrs = append(instrs, instruction.BrIf{Index: 1}) - - // Load value. - instrs = append(instrs, instruction.GetLocal{Index: c.local(scan.Source)}) - instrs = append(instrs, instruction.GetLocal{Index: c.local(scan.Key)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueGet)}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(scan.Value)}) + //nolint:prealloc // instruction list is known and fixed, clearer as slice literal + instrs := []instruction.Instruction{ + // Execute iterator. + instruction.GetLocal{Index: c.local(scan.Source)}, + instruction.GetLocal{Index: c.local(scan.Key)}, + instruction.Call{Index: c.function(opaValueIter)}, + // Check for emptiness. + instruction.TeeLocal{Index: c.local(scan.Key)}, + instruction.I32Eqz{}, + instruction.BrIf{Index: 1}, + // Load value. + instruction.GetLocal{Index: c.local(scan.Source)}, + instruction.GetLocal{Index: c.local(scan.Key)}, + instruction.Call{Index: c.function(opaValueGet)}, + instruction.SetLocal{Index: c.local(scan.Value)}, + } // Loop body. nested, err := c.compileBlock(scan.Block) @@ -1278,8 +1320,7 @@ func (c *Compiler) compileNot(not *ir.NotStmt, result *[]instruction.Instruction // generate and initialize condition variable cond := c.genLocal() - instrs = append(instrs, instruction.I32Const{Value: 1}) - instrs = append(instrs, instruction.SetLocal{Index: cond}) + instrs = append(instrs, instruction.I32Const{Value: 1}, instruction.SetLocal{Index: cond}) nested, err := c.compileBlock(not.Block) if err != nil { @@ -1287,14 +1328,15 @@ func (c *Compiler) compileNot(not *ir.NotStmt, result *[]instruction.Instruction } // unset condition variable if end of block is reached - nested = append(nested, instruction.I32Const{Value: 0}) - nested = append(nested, instruction.SetLocal{Index: cond}) - instrs = append(instrs, instruction.Block{Instrs: nested}) - - // break out of block if condition variable was unset - instrs = append(instrs, instruction.GetLocal{Index: cond}) - instrs = append(instrs, instruction.I32Eqz{}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + instrs = append(instrs, instruction.Block{Instrs: append(nested, + instruction.I32Const{Value: 0}, + instruction.SetLocal{Index: cond}, + )}, + // break out of block if condition variable was unset + instruction.GetLocal{Index: cond}, + instruction.I32Eqz{}, + instruction.BrIf{Index: 0}, + ) *result = instrs return nil @@ -1304,34 +1346,36 @@ func (c *Compiler) compileWithStmt(with *ir.WithStmt, result *[]instruction.Inst var instrs = *result save := c.genLocal() - instrs = append(instrs, instruction.Call{Index: c.function(opaMemoizePush)}) - instrs = append(instrs, instruction.GetLocal{Index: c.local(with.Local)}) - instrs = append(instrs, instruction.SetLocal{Index: save}) + instrs = append(instrs, + instruction.Call{Index: c.function(opaMemoizePush)}, + instruction.GetLocal{Index: c.local(with.Local)}, + instruction.SetLocal{Index: save}, + ) if len(with.Path) == 0 { - instrs = append(instrs, c.instrRead(with.Value)) - instrs = append(instrs, instruction.SetLocal{Index: c.local(with.Local)}) + instrs = append(instrs, c.instrRead(with.Value), instruction.SetLocal{Index: c.local(with.Local)}) } else { instrs = c.compileUpsert(with.Local, with.Path, with.Value, with.Location, instrs) } undefined := c.genLocal() - instrs = append(instrs, instruction.I32Const{Value: 1}) - instrs = append(instrs, instruction.SetLocal{Index: undefined}) + instrs = append(instrs, instruction.I32Const{Value: 1}, instruction.SetLocal{Index: undefined}) nested, err := c.compileBlock(with.Block) if err != nil { return err } - nested = append(nested, instruction.I32Const{Value: 0}) - nested = append(nested, instruction.SetLocal{Index: undefined}) - instrs = append(instrs, instruction.Block{Instrs: nested}) - instrs = append(instrs, instruction.GetLocal{Index: save}) - instrs = append(instrs, instruction.SetLocal{Index: c.local(with.Local)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaMemoizePop)}) - instrs = append(instrs, instruction.GetLocal{Index: undefined}) - instrs = append(instrs, instruction.BrIf{Index: 0}) + nested = append(nested, instruction.I32Const{Value: 0}, instruction.SetLocal{Index: undefined}) + + instrs = append(instrs, + instruction.Block{Instrs: nested}, + instruction.GetLocal{Index: save}, + instruction.SetLocal{Index: c.local(with.Local)}, + instruction.Call{Index: c.function(opaMemoizePop)}, + instruction.GetLocal{Index: undefined}, + instruction.BrIf{Index: 0}, + ) *result = instrs @@ -1339,37 +1383,38 @@ func (c *Compiler) compileWithStmt(with *ir.WithStmt, result *[]instruction.Inst } func (c *Compiler) compileUpsert(local ir.Local, path []int, value ir.Operand, _ ir.Location, instrs []instruction.Instruction) []instruction.Instruction { - lcopy := c.genLocal() // holds copy of local - instrs = append(instrs, instruction.GetLocal{Index: c.local(local)}) - instrs = append(instrs, instruction.SetLocal{Index: lcopy}) - - // Shallow copy the local if defined otherwise initialize to an empty object. - instrs = append(instrs, instruction.Block{ - Instrs: []instruction.Instruction{ - instruction.Block{Instrs: []instruction.Instruction{ - instruction.GetLocal{Index: lcopy}, - instruction.I32Eqz{}, - instruction.BrIf{Index: 0}, - instruction.GetLocal{Index: lcopy}, - instruction.Call{Index: c.function(opaValueShallowCopy)}, + instrs = append(instrs, + instruction.GetLocal{Index: c.local(local)}, + instruction.SetLocal{Index: lcopy}, + // Shallow copy the local if defined otherwise initialize to an empty object. + instruction.Block{ + Instrs: []instruction.Instruction{ + instruction.Block{Instrs: []instruction.Instruction{ + instruction.GetLocal{Index: lcopy}, + instruction.I32Eqz{}, + instruction.BrIf{Index: 0}, + instruction.GetLocal{Index: lcopy}, + instruction.Call{Index: c.function(opaValueShallowCopy)}, + instruction.TeeLocal{Index: lcopy}, + instruction.SetLocal{Index: c.local(local)}, + instruction.Br{Index: 1}, + }}, + instruction.Call{Index: c.function(opaObject)}, instruction.TeeLocal{Index: lcopy}, instruction.SetLocal{Index: c.local(local)}, - instruction.Br{Index: 1}, - }}, - instruction.Call{Index: c.function(opaObject)}, - instruction.TeeLocal{Index: lcopy}, - instruction.SetLocal{Index: c.local(local)}, - }, - }) + }, + }) // Initialize the locals that specify the path of the upsert operation. lpath := make(map[int]uint32, len(path)) 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]}) + instrs = append(instrs, + instruction.I32Const{Value: c.opaStringAddr(path[i])}, + instruction.SetLocal{Index: lpath[i]}, + ) } // Generate a block that traverses the path of the upsert operation, @@ -1379,36 +1424,34 @@ func (c *Compiler) compileUpsert(local ir.Local, path []int, value ir.Operand, _ ltemp := c.genLocal() for i := range len(path) - 1 { - - // Lookup the next part of the path. - inner = append(inner, instruction.GetLocal{Index: lcopy}) - inner = append(inner, instruction.GetLocal{Index: lpath[i]}) - inner = append(inner, instruction.Call{Index: c.function(opaValueGet)}) - inner = append(inner, instruction.SetLocal{Index: ltemp}) - - // If the next node is missing, break. - inner = append(inner, instruction.GetLocal{Index: ltemp}) - inner = append(inner, instruction.I32Eqz{}) - inner = append(inner, instruction.BrIf{Index: uint32(i)}) - - // If the next node is not an object, break. - inner = append(inner, instruction.GetLocal{Index: ltemp}) - inner = append(inner, instruction.Call{Index: c.function(opaValueType)}) - inner = append(inner, instruction.I32Const{Value: opaTypeObject}) - inner = append(inner, instruction.I32Ne{}) - inner = append(inner, instruction.BrIf{Index: uint32(i)}) - - // Otherwise, shallow copy the next node node and insert into the copy - // before continuing. - inner = append(inner, instruction.GetLocal{Index: ltemp}) - inner = append(inner, instruction.Call{Index: c.function(opaValueShallowCopy)}) - inner = append(inner, instruction.SetLocal{Index: ltemp}) - inner = append(inner, instruction.GetLocal{Index: lcopy}) - inner = append(inner, instruction.GetLocal{Index: lpath[i]}) - inner = append(inner, instruction.GetLocal{Index: ltemp}) - inner = append(inner, instruction.Call{Index: c.function(opaObjectInsert)}) - inner = append(inner, instruction.GetLocal{Index: ltemp}) - inner = append(inner, instruction.SetLocal{Index: lcopy}) + inner = append(inner, + // Lookup the next part of the path. + instruction.GetLocal{Index: lcopy}, + instruction.GetLocal{Index: lpath[i]}, + instruction.Call{Index: c.function(opaValueGet)}, + instruction.SetLocal{Index: ltemp}, + // If the next node is missing, break. + instruction.GetLocal{Index: ltemp}, + instruction.I32Eqz{}, + instruction.BrIf{Index: uint32(i)}, + // If the next node is not an object, break. + instruction.GetLocal{Index: ltemp}, + instruction.Call{Index: c.function(opaValueType)}, + instruction.I32Const{Value: opaTypeObject}, + instruction.I32Ne{}, + instruction.BrIf{Index: uint32(i)}, + // Otherwise, shallow copy the next node node and insert into the copy + // before continuing. + instruction.GetLocal{Index: ltemp}, + instruction.Call{Index: c.function(opaValueShallowCopy)}, + instruction.SetLocal{Index: ltemp}, + instruction.GetLocal{Index: lcopy}, + instruction.GetLocal{Index: lpath[i]}, + instruction.GetLocal{Index: ltemp}, + instruction.Call{Index: c.function(opaObjectInsert)}, + instruction.GetLocal{Index: ltemp}, + instruction.SetLocal{Index: lcopy}, + ) } inner = append(inner, instruction.Br{Index: uint32(len(path) - 1)}) @@ -1418,31 +1461,33 @@ func (c *Compiler) compileUpsert(local ir.Local, path []int, value ir.Operand, _ lval := c.genLocal() 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}) - block = append(block, instruction.GetLocal{Index: lcopy}) - block = append(block, instruction.GetLocal{Index: lpath[i]}) - block = append(block, instruction.GetLocal{Index: lval}) - block = append(block, instruction.Call{Index: c.function(opaObjectInsert)}) - block = append(block, instruction.GetLocal{Index: lval}) - block = append(block, instruction.SetLocal{Index: lcopy}) + block = append(block, + instruction.Block{Instrs: inner}, + instruction.Call{Index: c.function(opaObject)}, + instruction.SetLocal{Index: lval}, + instruction.GetLocal{Index: lcopy}, + instruction.GetLocal{Index: lpath[i]}, + instruction.GetLocal{Index: lval}, + instruction.Call{Index: c.function(opaObjectInsert)}, + instruction.GetLocal{Index: lval}, + instruction.SetLocal{Index: lcopy}, + ) inner = block block = nil } // Finish by inserting the statement's value into the shallow copied node. - instrs = append(instrs, instruction.Block{Instrs: inner}) - instrs = append(instrs, instruction.GetLocal{Index: lcopy}) - instrs = append(instrs, instruction.GetLocal{Index: lpath[len(path)-1]}) - instrs = append(instrs, c.instrRead(value)) - instrs = append(instrs, instruction.Call{Index: c.function(opaObjectInsert)}) - - return instrs + return append(instrs, + instruction.Block{Instrs: inner}, + instruction.GetLocal{Index: lcopy}, + instruction.GetLocal{Index: lpath[len(path)-1]}, + c.instrRead(value), + instruction.Call{Index: c.function(opaObjectInsert)}, + ) } func (c *Compiler) compileCallDynamicStmt(stmt *ir.CallDynamicStmt, result *[]instruction.Instruction) error { - instrs := []instruction.Instruction{} + instrs := make([]instruction.Instruction, 0, 3+3*len(stmt.Path)+len(stmt.Args)+10) larray := c.genLocal() lidx := c.genLocal() @@ -1515,7 +1560,7 @@ func (c *Compiler) compileCallStmt(stmt *ir.CallStmt, result *[]instruction.Inst func (c *Compiler) compileInternalCall(stmt *ir.CallStmt, index uint32, result *[]instruction.Instruction) error { - instrs := []instruction.Instruction{} + instrs := make([]instruction.Instruction, 0, len(stmt.Args)+4) // Prepare function args and call. for _, arg := range stmt.Args { 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 deleted file mode 100644 index 53dfc6d6cb33..000000000000 --- a/vendor/github.com/open-policy-agent/opa/internal/config/config.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2020 The OPA Authors. All rights reserved. -// Use of this source code is governed by an Apache2 -// license that can be found in the LICENSE file. - -// Package config implements helper functions to parse OPA's configuration. -package config - -import ( - "encoding/json" - "fmt" - "os" - "regexp" - "strings" - - "sigs.k8s.io/yaml" - - "github.com/open-policy-agent/opa/internal/strvals" - "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 -type ServiceOptions struct { - Raw json.RawMessage - AuthPlugin rest.AuthPluginLookupFunc - Keys map[string]*keys.Config - Logger logging.Logger - DistributedTacingOpts tracing.Options -} - -// ParseServicesConfig returns a set of named service clients. The service -// clients can be specified either as an array or as a map. Some systems (e.g., -// Helm) do not have proper support for configuration values nested under -// arrays, so just support both here. -func ParseServicesConfig(opts ServiceOptions) (map[string]rest.Client, error) { - - services := map[string]rest.Client{} - - var arr []json.RawMessage - var obj map[string]json.RawMessage - - if err := util.Unmarshal(opts.Raw, &arr); err == nil { - for _, s := range arr { - client, err := rest.New(s, opts.Keys, rest.AuthPluginLookup(opts.AuthPlugin), rest.Logger(opts.Logger), rest.DistributedTracingOpts(opts.DistributedTacingOpts)) - if err != nil { - return nil, err - } - services[client.Service()] = client - } - } else if util.Unmarshal(opts.Raw, &obj) == nil { - for k := range obj { - client, err := rest.New(obj[k], opts.Keys, rest.Name(k), rest.AuthPluginLookup(opts.AuthPlugin), rest.Logger(opts.Logger), rest.DistributedTracingOpts(opts.DistributedTacingOpts)) - if err != nil { - return nil, err - } - services[client.Service()] = client - } - } else { - // Return error from array decode as that is the default format. - return nil, err - } - - return services, nil -} - -// Load implements configuration file loading. The supplied config file will be -// read from disk (if specified) and overrides will be applied. If no config file is -// specified, the overrides can still be applied to an empty config. -func Load(configFile string, overrides []string, overrideFiles []string) ([]byte, error) { - baseConf := map[string]any{} - - // User specified config file - if configFile != "" { - var bytes []byte - var err error - bytes, err = os.ReadFile(configFile) - if err != nil { - return nil, err - } - - processedConf := subEnvVars(string(bytes)) - - if err := yaml.Unmarshal([]byte(processedConf), &baseConf); err != nil { - return nil, fmt.Errorf("failed to parse %s: %s", configFile, err) - } - } - - overrideConf := map[string]any{} - - // User specified a config override via --set - for _, override := range overrides { - processedOverride := subEnvVars(override) - if err := strvals.ParseInto(processedOverride, overrideConf); err != nil { - return nil, fmt.Errorf("failed parsing --set data: %s", err) - } - } - - // User specified a config override value via --set-file - for _, override := range overrideFiles { - reader := func(rs []rune) (any, error) { - bytes, err := os.ReadFile(string(rs)) - value := strings.TrimSpace(string(bytes)) - return value, err - } - if err := strvals.ParseIntoFile(override, overrideConf, reader); err != nil { - return nil, fmt.Errorf("failed parsing --set-file data: %s", err) - } - } - - // Merge together base config file and overrides, prefer the overrides - conf := mergeValues(baseConf, overrideConf) - - // Take the patched config and marshal back to YAML - return yaml.Marshal(conf) -} - -// regex looking for ${...} notation strings -var envRegex = regexp.MustCompile(`(?U:\${.*})`) - -// SubEnvVars will look for any environment variables in the passed in string -// with the syntax of ${VAR_NAME} and replace that string with ENV[VAR_NAME] -func SubEnvVars(s string) string { - return subEnvVars(s) -} - -func subEnvVars(s string) string { - updatedConfig := envRegex.ReplaceAllStringFunc(s, func(s string) string { - // Trim off the '${' and '}' - if len(s) <= 3 { - // This should never happen.. - return "" - } - varName := s[2 : len(s)-1] - - // Lookup the variable in the environment. We do not - // play by bash rules: if its undefined we'll keep it - // as-is, it could be replaced somewhere down the line. - // If it's set to "", we'll return that. - if lu, ok := os.LookupEnv(varName); ok { - return lu - } - return s - }) - - return updatedConfig -} - -// mergeValues will merge source and destination map, preferring values from the source map -func mergeValues(dest map[string]any, src map[string]any) map[string]any { - for k, v := range src { - // If the key doesn't exist already, then just set the key to that value - if _, exists := dest[k]; !exists { - dest[k] = v - continue - } - nextMap, ok := v.(map[string]any) - // If it isn't another map, overwrite the value - if !ok { - dest[k] = v - continue - } - // Edge case: If the key exists in the destination, but isn't a map - destMap, isMap := dest[k].(map[string]any) - // If the source map has a map for this key, prefer it - if !isMap { - dest[k] = v - continue - } - // If we got to this point, it is a map in both, so merge them - dest[k] = mergeValues(destMap, nextMap) - } - return dest -} 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 bfacf3bcea7b..791753528f13 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 @@ -2,10 +2,12 @@ // which supports lookups, sets, appends, insertions, and deletions. package bitvector +import "slices" + // A BitVector is a variable sized vector of bits. It supports // lookups, sets, appends, insertions, and deletions. // -// This class is not thread safe. +// Operations are not thread safe. type BitVector struct { data []byte length int @@ -14,10 +16,25 @@ type BitVector struct { // NewBitVector creates and initializes a new bit vector with length // elements, using data as its initial contents. func NewBitVector(data []byte, length int) *BitVector { - return &BitVector{ - data: data, - length: length, + return &BitVector{data: data, length: length} +} + +func (vector *BitVector) Clear() *BitVector { + if vector == nil { + return nil } + clear(vector.data) + vector.length = 0 + + return vector +} + +func (vector *BitVector) Reset(size, length int) *BitVector { + clear(vector.data) + vector.data = slices.Grow(vector.data, size)[:size] + vector.length = length + + return vector } // Bytes returns a slice of the contents of the bit vector. If the caller changes the returned slice, 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 ebfa875d7523..64511e5eb564 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 @@ -148,13 +148,17 @@ package edittree import ( "errors" "fmt" - "sort" "strings" "github.com/open-policy-agent/opa/internal/edittree/bitvector" "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) +var refPool = util.NewSlicePool[*ast.Term](1) + +var editTreePool = util.NewSyncPool[EditTree]() + // Deletions are encoded with a nil value pointer. type EditTree struct { value *ast.Term @@ -171,31 +175,66 @@ func NewEditTree(term *ast.Term) *EditTree { return nil } - var tree EditTree + return initForTerm(&EditTree{}, term) +} + +func EditTreeFromPool(term *ast.Term) *EditTree { + return initForTerm(editTreePool.Get(), term) +} + +func Dispose(e *EditTree) { + if e != nil { + editTreePool.Put(e.Reset()) + } +} + +func (e *EditTree) Reset() *EditTree { + e.value = nil + clear(e.childKeys) + clear(e.childScalarValues) + clear(e.childCompositeValues) + + e.eliminated = e.eliminated.Clear() + e.insertions = e.insertions.Clear() + + return e +} + +func initForTerm(tree *EditTree, term *ast.Term) *EditTree { + tree.value = term + switch x := term.Value.(type) { case ast.Object, ast.Set: - tree = EditTree{ - value: term, - childKeys: map[int]*ast.Term{}, - childScalarValues: map[int]*ast.Term{}, - childCompositeValues: map[int]*EditTree{}, + if tree.childKeys == nil { + tree.childKeys = map[int]*ast.Term{} + } + if tree.childScalarValues == nil { + tree.childScalarValues = map[int]*ast.Term{} + } + if tree.childCompositeValues == nil { + tree.childCompositeValues = map[int]*EditTree{} } case *ast.Array: - tree = EditTree{ - value: term, - childScalarValues: map[int]*ast.Term{}, - childCompositeValues: map[int]*EditTree{}, + if tree.childScalarValues == nil { + tree.childScalarValues = map[int]*ast.Term{} + } + if tree.childCompositeValues == nil { + tree.childCompositeValues = map[int]*EditTree{} } bytesLength := ((x.Len() - 1) / 8) + 1 // How many bytes to use for the bit-vectors. - tree.eliminated = bitvector.NewBitVector(make([]byte, bytesLength), x.Len()) - tree.insertions = bitvector.NewBitVector(make([]byte, bytesLength), x.Len()) - default: - tree = EditTree{ - value: term, + if tree.eliminated == nil { + tree.eliminated = bitvector.NewBitVector(make([]byte, bytesLength), x.Len()) + } else { + tree.eliminated = tree.eliminated.Reset(bytesLength, x.Len()) + } + if tree.insertions == nil { + tree.insertions = bitvector.NewBitVector(make([]byte, bytesLength), x.Len()) + } else { + tree.insertions = tree.insertions.Reset(bytesLength, x.Len()) } } - return &tree + return tree } // Returns correct (collision-resolved) hash for this term + whether or not @@ -231,17 +270,14 @@ func isComposite(t *ast.Term) bool { } } -//gcassert:inline func (e *EditTree) setChildKey(hash int, key *ast.Term) { e.childKeys[hash] = key } -//gcassert:inline func (e *EditTree) setChildScalarValue(hash int, value *ast.Term) { e.childScalarValues[hash] = value } -//gcassert:inline func (e *EditTree) setChildCompositeValue(hash int, child *EditTree) { e.childCompositeValues[hash] = child } @@ -278,11 +314,10 @@ func (e *EditTree) Insert(key, value *ast.Term) (*EditTree, error) { // We only collapse this Set-typed node if a composite type is involved. if isComposite(key) { // TODO: Investigate re-rendering *only* the immediate composite children. - collapsed := e.Render() - e.value = collapsed - e.childKeys = map[int]*ast.Term{} - e.childScalarValues = map[int]*ast.Term{} - e.childCompositeValues = map[int]*EditTree{} + e.value = e.Render() + clear(e.childKeys) + clear(e.childScalarValues) + clear(e.childCompositeValues) } return e.unsafeInsertSet(key, value), nil case *ast.Array: @@ -301,12 +336,13 @@ func (e *EditTree) Insert(key, value *ast.Term) (*EditTree, error) { } func (e *EditTree) unsafeInsertObject(key, value *ast.Term) *EditTree { - child := NewEditTree(value) keyHash, found := e.getKeyHash(key) if found { e.deleteChildValue(keyHash) } e.setChildKey(keyHash, key) + + child := NewEditTree(value) if isComposite(value) { e.setChildCompositeValue(keyHash, child) } else { @@ -331,10 +367,9 @@ func (e *EditTree) unsafeInsertSet(key, value *ast.Term) *EditTree { } func (e *EditTree) unsafeInsertArray(idx int, value *ast.Term) *EditTree { - child := NewEditTree(value) // Collect insertion indexes above the insertion site for rewriting. - rewritesScalars := []int{} - rewritesComposites := []int{} + var rewritesScalars, rewritesComposites []int + for i := idx; i < e.insertions.Length(); i++ { if e.insertions.Element(i) == 1 { if _, ok := e.childScalarValues[i]; ok { @@ -369,6 +404,8 @@ func (e *EditTree) unsafeInsertArray(idx int, value *ast.Term) *EditTree { } else { e.insertions.Insert(1, idx) } + + child := NewEditTree(value) if isComposite(value) { e.setChildCompositeValue(idx, child) } else { @@ -427,9 +464,9 @@ func (e *EditTree) Delete(key *ast.Term) (*EditTree, error) { // TODO: Investigate re-rendering *only* the immediate composite children. collapsed := e.Render() e.value = collapsed - e.childKeys = map[int]*ast.Term{} - e.childScalarValues = map[int]*ast.Term{} - e.childCompositeValues = map[int]*EditTree{} + clear(e.childKeys) + clear(e.childScalarValues) + clear(e.childCompositeValues) } else { keyHash, found := e.getKeyHash(key) // If child found, replace with delete node. If delete node already existed, error. @@ -539,7 +576,14 @@ func findIndexOfNthZero(n int, bv *bitvector.BitVector) (int, bool) { // Helper function for sets/objects when the key isn't present in either // child map. func (e *EditTree) fallbackDelete(key *ast.Term) (*EditTree, error) { - value, err := e.value.Value.Find(ast.Ref{key}) + // get ref from pool + rptr := refPool.Get(1) + defer refPool.Put(rptr) + + ref := *rptr + ref[0] = key + + value, err := e.value.Value.Find(ref) if err != nil { return nil, fmt.Errorf("cannot delete child key %v that does not exist", key) } @@ -595,14 +639,14 @@ 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{path[0]}); err == nil { + if v, err := x.Find(path[:1]); err == nil { child, err := e.Insert(path[0], ast.NewTerm(v)) if err != nil { return nil, err } return child.Unfold(path[1:]) } - return nil, fmt.Errorf("path %v does not exist in object term %v", ast.Ref{path[0]}, e.value.Value) + return nil, fmt.Errorf("path %v does not exist in object term %v", path[0], e.value.Value) case ast.Set: // Sets' keys *are* their values, so in order to allow accurate // traversal, we have to collapse the tree beneath this node, @@ -611,12 +655,11 @@ func (e *EditTree) Unfold(path ast.Ref) (*EditTree, error) { if isComposite(key) { collapsed := e.Render() e.value = collapsed - e.childKeys = map[int]*ast.Term{} - e.childScalarValues = map[int]*ast.Term{} - e.childCompositeValues = map[int]*EditTree{} + clear(e.childKeys) + clear(e.childScalarValues) + clear(e.childCompositeValues) } else { - keyHash, found := e.getKeyHash(key) - if found { + if keyHash, found := e.getKeyHash(key); found { if term, ok := e.childScalarValues[keyHash]; ok { child := NewEditTree(term) return child.Unfold(path[1:]) @@ -625,14 +668,14 @@ 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 := e.value.Value.Find(ast.Ref{path[0]}); err == nil { + if v, err := e.value.Value.Find(path[:1]); err == nil { child, err := e.Insert(path[0], ast.NewTerm(v)) if err != nil { return nil, err } return child.Unfold(path[1:]) } - return nil, fmt.Errorf("path %v does not exist in set term %v", ast.Ref{path[0]}, e.value.Value) + return nil, fmt.Errorf("path %v does not exist in set term %v", path[:1], e.value.Value) case *ast.Array: idx, err := toIndex(e.insertions.Length(), path[0]) if err != nil { @@ -647,13 +690,17 @@ func (e *EditTree) Unfold(path ast.Ref) (*EditTree, error) { } idxt := ast.InternedTerm(idx) + rptr := refPool.Get(1) + defer refPool.Put(rptr) + + ref := *rptr + ref[0] = idxt // 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{idxt}); err == nil { + if v, err := x.Find(ref); err == nil { // TODO: Consider a more efficient "Replace" function that special-cases this for arrays instead? - _, err := e.Delete(idxt) - if err != nil { + if _, err := e.Delete(idxt); err != nil { return nil, err } child, err := e.Insert(idxt, ast.NewTerm(v)) @@ -662,10 +709,10 @@ func (e *EditTree) Unfold(path ast.Ref) (*EditTree, error) { } return child.Unfold(path[1:]) } - return nil, fmt.Errorf("path %v does not exist in array term %v", ast.Ref{ast.IntNumberTerm(idx)}, e.value.Value) + return nil, fmt.Errorf("path %v does not exist in array term %v", ast.InternedTerm(idx), e.value.Value) default: // Catch all primitive types. - return nil, fmt.Errorf("expected composite type for path %v, found value: %v (type: %T)", ast.Ref{path[0]}, x, x) + return nil, fmt.Errorf("expected composite type for path %v, found value: %v (type: %T)", path[0], x, x) } } @@ -787,8 +834,7 @@ func (e *EditTree) Render() *ast.Term { if t, ok := e.childScalarValues[i]; ok { out = append(out, t) } else if child, ok := e.childCompositeValues[i]; ok { - t := child.Render() - out = append(out, t) + out = append(out, child.Render()) } else { panic(fmt.Errorf("invalid index %d does not exist in array", i)) } @@ -810,9 +856,10 @@ func (e *EditTree) InsertAtPath(path ast.Ref, value *ast.Term) (*EditTree, error if len(path) == 0 { e.value = value - e.childKeys = map[int]*ast.Term{} - e.childScalarValues = map[int]*ast.Term{} - e.childCompositeValues = map[int]*EditTree{} + clear(e.childKeys) + clear(e.childScalarValues) + clear(e.childCompositeValues) + if v, ok := value.Value.(*ast.Array); ok { bytesLength := ((v.Len() - 1) / 8) + 1 // How many bytes to use for the bit-vectors. e.eliminated = bitvector.NewBitVector(make([]byte, bytesLength), v.Len()) @@ -921,24 +968,19 @@ func (e *EditTree) Exists(path ast.Ref) bool { // so that we can accurately unfold it again for an update, // once we know that the key we care about is present. if isComposite(key) { - collapsed := e.Render() - e.value = collapsed - e.childKeys = map[int]*ast.Term{} - e.childScalarValues = map[int]*ast.Term{} - e.childCompositeValues = map[int]*EditTree{} - } else { - keyHash, found := e.getKeyHash(key) - if found { - if _, ok := e.childScalarValues[keyHash]; ok { - return len(path) == 1 - } + e.value = e.Render() + clear(e.childKeys) + clear(e.childScalarValues) + clear(e.childCompositeValues) + } else if keyHash, found := e.getKeyHash(key); found { + if _, ok := e.childScalarValues[keyHash]; ok { + return len(path) == 1 } } // Fallback if child lookup failed. _, err := e.value.Value.Find(path) return err == nil case *ast.Array: - var idx int idx, err := toIndex(e.insertions.Length(), path[0]) if err != nil { return false @@ -951,7 +993,16 @@ 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. - _, err = x.Find(ast.Ref{ast.InternedTerm(idx)}.Concat(path[1:])) + rptr := refPool.Get(len(path)) + + ref := *rptr + ref[0] = ast.InternedTerm(idx) + copy(ref[1:], path[1:]) + + _, err = x.Find(ref) + + refPool.Put(rptr) + return err == nil default: // Catch all primitive types. @@ -978,8 +1029,7 @@ func toIndex(arrayLength int, term *ast.Term) (int, error) { if v == "-" { return arrayLength, nil } - num := ast.Number(v) - if i, ok = num.Int(); !ok { + if i, ok = ast.Number(v).Int(); !ok { return 0, errors.New("invalid string for indexing") } if v != "0" && strings.HasPrefix(string(v), "0") { @@ -1004,6 +1054,14 @@ func (e *EditTree) Filter(paths []ast.Ref) *ast.Term { return nil } + // term pointer and ref pointer for reuse in lookups and iteration below. + tptr, rptr := ast.TermPtrPool.Get(), refPool.Get(1) + defer func() { + tptr.Value = nil + ast.TermPtrPool.Put(tptr) + refPool.Put(rptr) + }() + // Separate out keys for this level. // In the event of paths like "a", "a/b", "a/b/c", the "a" path will win out. // Nil keys, such as "" or [], are not permitted. (legacy behavior) @@ -1026,7 +1084,8 @@ func (e *EditTree) Filter(paths []ast.Ref) *ast.Term { renderNow := ast.NewSet(renderNowList...) // Clear everything out of the pathMap that has a renderNow candidate. for k := range pathMap { - if renderNow.Contains(ast.NewTerm(k)) { + tptr.Value = k + if renderNow.Contains(tptr) { delete(pathMap, k) } } @@ -1035,37 +1094,46 @@ func (e *EditTree) Filter(paths []ast.Ref) *ast.Term { switch e.value.Value.(type) { case ast.Object: out := make([][2]*ast.Term, 0, renderNow.Len()+len(pathMap)) + ref := *rptr + // Render any finished paths. - renderNow.Foreach(func(k *ast.Term) { - if e.Exists(ast.Ref{k}) { - subtreeResult, _ := e.RenderAtPath(ast.Ref{k}) + for _, k := range renderNow.Slice() { + ref[0] = k + if e.Exists(ref) { + subtreeResult, _ := e.RenderAtPath(ref) out = append(out, [2]*ast.Term{k, subtreeResult}) } - }) + } // Recursively descend remaining paths. for k, p := range pathMap { - if e.Exists(ast.Ref{ast.NewTerm(k)}) { - child, _ := e.Unfold(ast.Ref{ast.NewTerm(k)}) + tptr.Value = k + ref[0] = tptr + if e.Exists(ref) { + child, _ := e.Unfold(ref) subtreeResult := child.Filter(p) out = append(out, [2]*ast.Term{ast.NewTerm(k), subtreeResult}) } } + return ast.ObjectTerm(out...) case ast.Set: out := make([]*ast.Term, 0, renderNow.Len()+len(pathMap)) + ref := *rptr // Render any finished paths. - renderNow.Foreach(func(k *ast.Term) { - if e.Exists(ast.Ref{k}) { - subtreeResult, _ := e.RenderAtPath(ast.Ref{k}) + for _, k := range renderNow.Slice() { + ref[0] = k + if e.Exists(ref) { + subtreeResult, _ := e.RenderAtPath(ref) out = append(out, subtreeResult) } - }) + } // Recursively descend remaining paths. for k, p := range pathMap { - if e.Exists(ast.Ref{ast.NewTerm(k)}) { - child, _ := e.Unfold(ast.Ref{ast.NewTerm(k)}) - subtreeResult := child.Filter(p) - out = append(out, subtreeResult) + tptr.Value = k + ref[0] = tptr + if e.Exists(ref) { + child, _ := e.Unfold(ref) + out = append(out, child.Filter(p)) } } return ast.SetTerm(out...) @@ -1073,27 +1141,25 @@ func (e *EditTree) Filter(paths []ast.Ref) *ast.Term { // No early exit here, because we might have just deletes on the // original array. We build a new Array with modified/deleted keys. out := make([]*ast.Term, 0, renderNow.Len()+len(pathMap)) - // Sort array indexes before descending. - idxList := make([]*ast.Term, 0, len(pathMap)) - renderNow.Foreach(func(k *ast.Term) { - idxList = append(idxList, k) - }) + idxList := append(make([]*ast.Term, 0, renderNow.Len()+len(pathMap)), renderNow.Slice()...) for k := range pathMap { idxList = append(idxList, ast.NewTerm(k)) } - sort.Sort(termSlice(idxList)) - // Render child or recursively descend as needed. - for i := range idxList { + + ref := *rptr + + // Render child or recursively descend sorted indexes as needed. + for i := range util.SortedFunc(idxList, ast.TermValueCompare) { k := idxList[i] - if renderNow.Contains(k) { - if e.Exists(ast.Ref{k}) { - subtreeResult, _ := e.RenderAtPath(ast.Ref{k}) + ref[0] = k + if e.Exists(ref) { + if renderNow.Contains(k) { + subtreeResult, _ := e.RenderAtPath(ref) out = append(out, subtreeResult) + } else { + child, _ := e.Unfold(ref) + out = append(out, child.Filter(pathMap[k.Value])) } - } else if e.Exists(ast.Ref{k}) { - child, _ := e.Unfold(ast.Ref{k}) - subtreeResult := child.Filter(pathMap[k.Value]) - out = append(out, subtreeResult) } } return ast.ArrayTerm(out...) @@ -1101,9 +1167,3 @@ func (e *EditTree) Filter(paths []ast.Ref) *ast.Term { return e.value } } - -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) { 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/file/archive/tarball.go b/vendor/github.com/open-policy-agent/opa/internal/file/archive/tarball.go index 6b8ba48d159d..93396aa96f91 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/file/archive/tarball.go +++ b/vendor/github.com/open-policy-agent/opa/internal/file/archive/tarball.go @@ -4,39 +4,72 @@ import ( "archive/tar" "bytes" "compress/gzip" + "encoding/json" + "errors" + "io" "strings" ) -// MustWriteTarGz write the list of file names and content -// into a tarball. -func MustWriteTarGz(files [][2]string) *bytes.Buffer { - var buf bytes.Buffer - gw := gzip.NewWriter(&buf) - defer gw.Close() +type TarGzWriter struct { + *tar.Writer + + gw *gzip.Writer +} + +func NewTarGzWriter(w io.Writer) *TarGzWriter { + gw := gzip.NewWriter(w) tw := tar.NewWriter(gw) - defer tw.Close() - for _, file := range files { - if err := WriteFile(tw, file[0], []byte(file[1])); err != nil { - panic(err) - } + + return &TarGzWriter{ + Writer: tw, + gw: gw, } - return &buf } -// WriteFile adds a file header with content to the given tar writer -func WriteFile(tw *tar.Writer, path string, bs []byte) error { - +func (tgw *TarGzWriter) WriteFile(path string, bs []byte) (err error) { hdr := &tar.Header{ - Name: "/" + strings.TrimLeft(path, "/"), + Name: path, Mode: 0600, Typeflag: tar.TypeReg, Size: int64(len(bs)), } - if err := tw.WriteHeader(hdr); err != nil { - return err + if err = tgw.WriteHeader(hdr); err == nil { + _, err = tgw.Write(bs) } - _, err := tw.Write(bs) return err } + +func (tgw *TarGzWriter) WriteJSONFile(path string, v any) error { + buf := &bytes.Buffer{} + if err := json.NewEncoder(buf).Encode(v); err != nil { + return err + } + + return tgw.WriteFile(path, buf.Bytes()) +} + +func (tgw *TarGzWriter) Close() error { + return errors.Join(tgw.Writer.Close(), tgw.gw.Close()) +} + +// MustWriteTarGz writes the list of file names and content into a tarball. +// Paths are prefixed with "/". +func MustWriteTarGz(files [][2]string) *bytes.Buffer { + buf := &bytes.Buffer{} + tgw := NewTarGzWriter(buf) + defer tgw.Close() + + for _, file := range files { + if !strings.HasPrefix(file[0], "/") { + file[0] = "/" + file[0] + } + + if err := tgw.WriteFile(file[0], []byte(file[1])); err != nil { + panic(err) + } + } + + return buf +} diff --git a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/utils.go b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/utils.go index ca071930f21b..95754fab7f2e 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/utils.go +++ b/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/utils.go @@ -23,7 +23,7 @@ // // created 26-02-2013 -// nolint: deadcode,unused,varcheck // Package in development (2021). +// nolint:unused,varcheck // Package in development (2021). package gojsonschema import ( 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 8d59158717a4..445b5d7c2abd 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 @@ -1768,7 +1768,7 @@ func (p *Planner) planRef(ref ast.Ref, iter planiter) error { return errors.New("illegal ref: non-var head") } - if head.Compare(ast.DefaultRootDocument.Value) == 0 { + if head.Equal(ast.DefaultRootDocument.Value) { virtual := p.rules.Get(ref[0].Value) base := &baseptr{local: p.vars.GetOrEmpty(ast.DefaultRootDocument.Value.(ast.Var))} return p.planRefData(virtual, base, ref, 1, iter) @@ -2070,7 +2070,7 @@ func (p *Planner) planRefDataExtent(virtual *ruletrie, base *baseptr, iter plani } } if anyKeyNonGround { - var rules []*ast.Rule + rules := make([]*ast.Rule, 0, len(virtual.Children())) for _, key := range virtual.Children() { // TODO(sr): skip functions rules = append(rules, virtual.Get(key).Rules()...) 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 07aa568fa2f3..c463ccbff858 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 @@ -158,6 +158,8 @@ func SignV4(headers map[string][]string, method string, theURL *url.URL, body [] // include the values for the signed headers orderedKeys := util.KeysSorted(headersToSign) for _, k := range orderedKeys { + // TODO: fix later + //nolint:perfsprint canonicalReq += k + ":" + strings.Join(headersToSign[k], ",") + "\n" } canonicalReq += "\n" // linefeed to terminate headers 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 653794b0a909..9590b8886bba 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 @@ -7,16 +7,16 @@ package ref import ( "errors" - "strings" "github.com/open-policy-agent/opa/v1/ast" "github.com/open-policy-agent/opa/v1/storage" + "github.com/open-policy-agent/opa/v1/util" ) // ParseDataPath returns a ref from the slash separated path s rooted at data. // All path segments are treated as identifier strings. func ParseDataPath(s string) (ast.Ref, error) { - path, ok := storage.ParsePath("/" + strings.TrimPrefix(s, "/")) + path, ok := storage.ParsePath(util.WithPrefix(s, "/")) if !ok { return nil, errors.New("invalid path") } 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 deleted file mode 100644 index bc71d66a3cce..000000000000 --- a/vendor/github.com/open-policy-agent/opa/internal/report/report.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2020 The OPA Authors. All rights reserved. -// Use of this source code is governed by an Apache2 -// license that can be found in the LICENSE file. - -// Package report provides functions to report OPA's version information to an external service and process the response. -package report - -import ( - "cmp" - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "os" - "runtime" - "strconv" - "strings" - "time" - - "github.com/open-policy-agent/opa/internal/semver" - "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/v1/plugins/rest" - "github.com/open-policy-agent/opa/v1/util" -) - -// ExternalServiceURL is the base HTTP URL for a github instance used -// to query for more recent version. -// If not otherwise specified, it will use the hard-coded default, api.github.com. -// GHRepo is the repository to use, and defaults to "open-policy-agent/opa" -// -// Override at build time via: -// -// -ldflags "-X github.com/open-policy-agent/opa/internal/report.ExternalServiceURL=" -// -ldflags "-X github.com/open-policy-agent/opa/internal/report.GHRepo=" -// -// ExternalServiceURL will be overridden if the OPA_TELEMETRY_SERVICE_URL environment variable -// is provided. -var ExternalServiceURL = "https://api.github.com" -var GHRepo = "open-policy-agent/opa" - -// Reporter reports information such as the version, heap usage about the running OPA instance to an external service -type Reporter interface { - SendReport(ctx context.Context) (*DataResponse, error) - RegisterGatherer(key string, f Gatherer) -} - -// Gatherer represents a mechanism to inject additional data in the telemetry report -type Gatherer func(ctx context.Context) (any, error) - -// DataResponse represents the data returned by the external service -type DataResponse struct { - Latest ReleaseDetails `json:"latest"` -} - -// ReleaseDetails holds information about the latest OPA release -type ReleaseDetails struct { - Download string `json:"download,omitempty"` // link to download the OPA release - ReleaseNotes string `json:"release_notes,omitempty"` // link to the OPA release notes - LatestRelease string `json:"latest_release,omitempty"` // latest OPA released version - OPAUpToDate bool `json:"opa_up_to_date,omitempty"` // is running OPA version greater than or equal to the latest released -} - -// Options supplies parameters to the reporter. -type Options struct { - Logger logging.Logger -} - -type GHVersionCollector struct { - client rest.Client -} - -type GHResponse struct { - TagName string `json:"tag_name,omitempty"` // latest OPA release tag - ReleaseNotes string `json:"html_url,omitempty"` // link to the OPA release notes - Download string `json:"assets_url,omitempty"` // link to download the OPA release -} - -// New returns an instance of the Reporter -func New(opts Options) (Reporter, error) { - r := GHVersionCollector{} - - url := cmp.Or(os.Getenv("OPA_TELEMETRY_SERVICE_URL"), ExternalServiceURL) - - restConfig := fmt.Appendf(nil, `{ - "url": %q, - }`, url) - - client, err := rest.New(restConfig, map[string]*keys.Config{}, rest.Logger(opts.Logger)) - if err != nil { - return nil, err - } - r.client = client - - // heap_usage_bytes is always present, so register it unconditionally - r.RegisterGatherer("heap_usage_bytes", readRuntimeMemStats) - - return &r, nil -} - -// SendReport sends the telemetry report which includes information such as the OPA version, current memory usage to -// the external service -func (r *GHVersionCollector) SendReport(ctx context.Context) (*DataResponse, error) { - rCtx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - resp, err := r.client.Do(rCtx, "GET", fmt.Sprintf("/repos/%s/releases/latest", GHRepo)) - if err != nil { - return nil, err - } - - defer util.Close(resp) - - switch resp.StatusCode { - case http.StatusOK: - if resp.Body != nil { - var result GHResponse - err := json.NewDecoder(resp.Body).Decode(&result) - if err != nil { - return nil, err - } - return createDataResponse(result) - } - return nil, nil - default: - return nil, fmt.Errorf("server replied with HTTP %v", resp.StatusCode) - } -} - -func createDataResponse(ghResp GHResponse) (*DataResponse, error) { - if ghResp.TagName == "" { - return nil, errors.New("server response does not contain tag_name") - } - - v := strings.TrimPrefix(version.Version, "v") - sv, err := semver.NewVersion(v) - if err != nil { - return nil, fmt.Errorf("failed to parse current version %q: %w", v, err) - } - - latestV := strings.TrimPrefix(ghResp.TagName, "v") - latestSV, err := semver.NewVersion(latestV) - if err != nil { - return nil, fmt.Errorf("failed to parse latest version %q: %w", latestV, err) - } - - isLatest := sv.Compare(*latestSV) >= 0 - - // Note: alternatively, we could look through the assets in the GH API response to find a matching asset, - // and use its URL. However, this is not guaranteed to be more robust, and wouldn't use the 'openpolicyagent.org' domain. - downloadLink := fmt.Sprintf("https://openpolicyagent.org/downloads/%v/opa_%v_%v", - ghResp.TagName, runtime.GOOS, runtime.GOARCH) - - if runtime.GOARCH == "arm64" { - downloadLink = fmt.Sprintf("%v_static", downloadLink) - } - - if strings.HasPrefix(runtime.GOOS, "win") { - downloadLink = fmt.Sprintf("%v.exe", downloadLink) - } - - return &DataResponse{ - Latest: ReleaseDetails{ - Download: downloadLink, - ReleaseNotes: ghResp.ReleaseNotes, - LatestRelease: ghResp.TagName, - OPAUpToDate: isLatest, - }, - }, nil -} - -func (*GHVersionCollector) RegisterGatherer(_ string, _ Gatherer) { - // no-op for this implementation -} - -// IsSet returns true if dr is populated. -func (dr *DataResponse) IsSet() bool { - return dr != nil && dr.Latest.LatestRelease != "" && dr.Latest.Download != "" && dr.Latest.ReleaseNotes != "" -} - -// Slice returns the dr as a slice of key-value string pairs. If dr is nil, this function returns an empty slice. -func (dr *DataResponse) Slice() [][2]string { - - if !dr.IsSet() { - return nil - } - - return [][2]string{ - {"Latest Upstream Version", strings.TrimPrefix(dr.Latest.LatestRelease, "v")}, - {"Download", dr.Latest.Download}, - {"Release Notes", dr.Latest.ReleaseNotes}, - } -} - -// Pretty returns OPA release information in a human-readable format. -func (dr *DataResponse) Pretty() string { - if !dr.IsSet() { - return "" - } - - pairs := dr.Slice() - lines := make([]string, 0, len(pairs)) - - for _, pair := range pairs { - lines = append(lines, fmt.Sprintf("%v: %v", pair[0], pair[1])) - } - - return strings.Join(lines, "\n") -} - -func readRuntimeMemStats(_ context.Context) (any, error) { - var m runtime.MemStats - runtime.ReadMemStats(&m) - return strconv.FormatUint(m.Alloc, 10), nil -} 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 deleted file mode 100644 index de8ef8740126..000000000000 --- a/vendor/github.com/open-policy-agent/opa/internal/runtime/init/init.go +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2020 The OPA Authors. All rights reserved. -// Use of this source code is governed by an Apache2 -// license that can be found in the LICENSE file. - -// Package init is an internal package with helpers for data and policy loading during initialization. -package init - -import ( - "context" - "fmt" - "io/fs" - "path/filepath" - "strings" - - storedversion "github.com/open-policy-agent/opa/internal/version" - "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. -type InsertAndCompileOptions struct { - Store storage.Store - Txn storage.Transaction - Files loader.Result - Bundles map[string]*bundle.Bundle - MaxErrors int - EnablePrintStatements bool - ParserOptions ast.ParserOptions - BundleActivatorPlugin string -} - -// InsertAndCompileResult contains the output of the operation. -type InsertAndCompileResult struct { - Compiler *ast.Compiler - Metrics metrics.Metrics -} - -// InsertAndCompile writes data and policy into the store and returns a compiler for the -// store contents. -func InsertAndCompile(ctx context.Context, opts InsertAndCompileOptions) (*InsertAndCompileResult, error) { - if len(opts.Files.Documents) > 0 { - if err := opts.Store.Write(ctx, opts.Txn, storage.AddOp, storage.RootPath, opts.Files.Documents); err != nil { - return nil, fmt.Errorf("storage error: %w", err) - } - } - - policies := make(map[string]*ast.Module, len(opts.Files.Modules)) - - for id, parsed := range opts.Files.Modules { - policies[id] = parsed.Parsed - } - - compiler := ast.NewCompiler(). - WithDefaultRegoVersion(opts.ParserOptions.RegoVersion). - SetErrorLimit(opts.MaxErrors). - WithPathConflictsCheck(storage.NonEmpty(ctx, opts.Store, opts.Txn)). - WithEnablePrintStatements(opts.EnablePrintStatements) - m := metrics.New() - - activation := &bundle.ActivateOpts{ - Ctx: ctx, - Store: opts.Store, - Txn: opts.Txn, - Compiler: compiler, - Metrics: m, - Bundles: opts.Bundles, - ExtraModules: policies, - ParserOptions: opts.ParserOptions, - Plugin: opts.BundleActivatorPlugin, - } - - err := bundle.Activate(activation) - if err != nil { - return nil, err - } - - // Policies in bundles will have already been added to the store, but - // modules loaded outside of bundles will need to be added manually. - for id, parsed := range opts.Files.Modules { - if err := opts.Store.UpsertPolicy(ctx, opts.Txn, id, parsed.Raw); err != nil { - return nil, fmt.Errorf("storage error: %w", err) - } - } - - // Set the version in the store last to prevent data files from overwriting. - if err := storedversion.Write(ctx, opts.Store, opts.Txn); err != nil { - return nil, fmt.Errorf("storage error: %w", err) - } - - return &InsertAndCompileResult{Compiler: compiler, Metrics: m}, nil -} - -// LoadPathsResult contains the output loading a set of paths. -type LoadPathsResult struct { - Bundles map[string]*bundle.Bundle - Files loader.Result -} - -// WalkPathsResult contains the output loading a set of paths. -type WalkPathsResult struct { - BundlesLoader []BundleLoader - FileDescriptors []*Descriptor -} - -// BundleLoader contains information about files in a bundle -type BundleLoader struct { - DirectoryLoader bundle.DirectoryLoader - IsDir bool -} - -// Descriptor contains information about a file -type Descriptor struct { - Root string - Path string -} - -// LoadPaths reads data and policy from the given paths and returns a set of bundles or -// raw loader file results. -func LoadPaths(paths []string, - filter loader.Filter, - asBundle bool, - bvc *bundle.VerificationConfig, - skipVerify bool, - bundleLazyLoading bool, - processAnnotations bool, - caps *ast.Capabilities, - fsys fs.FS) (*LoadPathsResult, error) { - return LoadPathsForRegoVersion(ast.RegoV0, paths, filter, asBundle, bvc, skipVerify, bundleLazyLoading, processAnnotations, false, caps, fsys) -} - -func LoadPathsForRegoVersion(regoVersion ast.RegoVersion, - paths []string, - filter loader.Filter, - asBundle bool, - bvc *bundle.VerificationConfig, - skipVerify bool, - bundleLazyLoading bool, - processAnnotations bool, - followSymlinks bool, - caps *ast.Capabilities, - fsys fs.FS) (*LoadPathsResult, error) { - - if caps == nil { - caps = ast.CapabilitiesForThisVersion() - } - - // tar.gz files are automatically loaded as bundles - var likelyBundles, nonBundlePaths []string - if !asBundle { - likelyBundles, nonBundlePaths = splitByTarGzExt(paths) - paths = likelyBundles - } - - var result LoadPathsResult - var err error - if asBundle || len(likelyBundles) > 0 { - result.Bundles = make(map[string]*bundle.Bundle, len(paths)) - for _, path := range paths { - result.Bundles[path], err = loader.NewFileLoader(). - WithFS(fsys). - WithBundleVerificationConfig(bvc). - WithSkipBundleVerification(skipVerify). - WithBundleLazyLoadingMode(bundleLazyLoading). - WithFilter(filter). - WithProcessAnnotation(processAnnotations). - WithCapabilities(caps). - WithRegoVersion(regoVersion). - WithFollowSymlinks(followSymlinks). - AsBundle(path) - if err != nil { - return nil, err - } - } - } - - if asBundle { - return &result, nil - } - - files, err := loader.NewFileLoader(). - WithFS(fsys). - WithBundleLazyLoadingMode(bundleLazyLoading). - WithProcessAnnotation(processAnnotations). - WithCapabilities(caps). - WithRegoVersion(regoVersion). - Filtered(nonBundlePaths, filter) - - if err != nil { - return nil, err - } - - result.Files = *files - - return &result, nil -} - -// splitByTarGzExt splits the paths in 2 groups. Ones with .tar.gz and another with -// non .tar.gz extensions. -func splitByTarGzExt(paths []string) (targzs []string, nonTargzs []string) { - for _, path := range paths { - if strings.HasSuffix(path, ".tar.gz") { - targzs = append(targzs, path) - } else { - nonTargzs = append(nonTargzs, path) - } - } - return -} - -// WalkPaths reads data and policy from the given paths and returns a set of bundle directory loaders -// or descriptors that contain information about files. -func WalkPaths(paths []string, filter loader.Filter, asBundle bool) (*WalkPathsResult, error) { - - var result WalkPathsResult - - if asBundle { - result.BundlesLoader = make([]BundleLoader, len(paths)) - for i, path := range paths { - bundleLoader, isDir, err := loader.GetBundleDirectoryLoader(path) - if err != nil { - return nil, err - } - - result.BundlesLoader[i] = BundleLoader{ - DirectoryLoader: bundleLoader, - IsDir: isDir, - } - } - return &result, nil - } - - result.FileDescriptors = []*Descriptor{} - for _, path := range paths { - filePaths, err := loader.FilteredPaths([]string{path}, filter) - if err != nil { - return nil, err - } - - for _, fp := range filePaths { - // Trim off the root directory and return path as if chrooted - cleanedPath := strings.TrimPrefix(fp, path) - if path == "." && filepath.Base(fp) == bundle.ManifestExt { - cleanedPath = fp - } - - if !strings.HasPrefix(cleanedPath, "/") { - cleanedPath = "/" + cleanedPath - } - - result.FileDescriptors = append(result.FileDescriptors, &Descriptor{ - Root: path, - Path: cleanedPath, - }) - } - } - - return &result, nil -} diff --git a/vendor/github.com/open-policy-agent/opa/internal/semver/semver.go b/vendor/github.com/open-policy-agent/opa/internal/semver/semver.go index 23c6c186d9cd..725f86318a77 100644 --- a/vendor/github.com/open-policy-agent/opa/internal/semver/semver.go +++ b/vendor/github.com/open-policy-agent/opa/internal/semver/semver.go @@ -14,237 +14,234 @@ // Semantic Versions http://semver.org -// Package semver has been vendored from: +// This file was originally vendored from: // https://github.com/coreos/go-semver/tree/e214231b295a8ea9479f11b70b35d5acf3556d9b/semver -// A number of the original functions of the package have been removed since -// they are not required for our built-ins. +// There isn't a single line left from the original source today, but being generous about +// attribution won't hurt. package semver import ( - "bytes" "fmt" "regexp" "strconv" "strings" + + "github.com/open-policy-agent/opa/v1/util" ) +// reMetaIdentifier matches pre-release and metadata identifiers against the spec requirements +var reMetaIdentifier = regexp.MustCompile(`^[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*$`) + // Version represents a parsed SemVer type Version struct { Major int64 Minor int64 Patch int64 - PreRelease PreRelease - Metadata string + PreRelease string `json:"PreRelease,omitempty"` + Metadata string `json:"Metadata,omitempty"` } -// PreRelease represents a pre-release suffix string -type PreRelease string +// Parse constructs new semver Version from version string. +func Parse(version string) (v Version, err error) { + version = strings.TrimPrefix(version, "v") -func splitOff(input *string, delim string) (val string) { - parts := strings.SplitN(*input, delim, 2) + version, v.Metadata = cut(version, '+') + if v.Metadata != "" && !reMetaIdentifier.MatchString(v.Metadata) { + return v, fmt.Errorf("invalid metadata identifier: %s", v.Metadata) + } - if len(parts) == 2 { - *input = parts[0] - val = parts[1] + version, v.PreRelease = cut(version, '-') + if v.PreRelease != "" && !reMetaIdentifier.MatchString(v.PreRelease) { + return v, fmt.Errorf("invalid pre-release identifier: %s", v.PreRelease) } - return val -} + if strings.Count(version, ".") != 2 { + return v, fmt.Errorf("%s should contain major, minor, and patch versions", version) + } -// NewVersion constructs new SemVers from strings -func NewVersion(version string) (*Version, error) { - v := Version{} + major, after := cut(version, '.') + if v.Major, err = strconv.ParseInt(major, 10, 64); err != nil { + return v, err + } - if err := v.Set(version); err != nil { - return nil, err + minor, after := cut(after, '.') + if v.Minor, err = strconv.ParseInt(minor, 10, 64); err != nil { + return v, err } - return &v, nil -} + if v.Patch, err = strconv.ParseInt(after, 10, 64); err != nil { + return v, err + } -// Set parses and updates v from the given version string. Implements flag.Value -func (v *Version) Set(version string) error { - metadata := splitOff(&version, "+") - preRelease := PreRelease(splitOff(&version, "-")) - dotParts := strings.SplitN(version, ".", 3) + return v, nil +} - if len(dotParts) != 3 { - return fmt.Errorf("%s is not in dotted-tri format", version) +// MustParse is like Parse but panics if the version string is invalid instead of returning an error. +func MustParse(version string) Version { + v, err := Parse(version) + if err != nil { + panic(err) } - if err := validateIdentifier(string(preRelease)); err != nil { - return fmt.Errorf("failed to validate pre-release: %v", err) - } + return v +} - if err := validateIdentifier(metadata); err != nil { - return fmt.Errorf("failed to validate metadata: %v", err) +// Compare compares two semver strings. +func Compare(a, b string) int { + aV, err := Parse(a) + if err != nil { + return -1 } - parsed := make([]int64, 3) - - for i, v := range dotParts[:3] { - val, err := strconv.ParseInt(v, 10, 64) - parsed[i] = val - if err != nil { - return err - } + bV, err := Parse(b) + if err != nil { + return 1 } - v.Metadata = metadata - v.PreRelease = preRelease - v.Major = parsed[0] - v.Minor = parsed[1] - v.Patch = parsed[2] - return nil + return aV.Compare(bV) } -func (v Version) String() string { - var buffer bytes.Buffer +// AppendText appends the textual representation of the version to b and returns the extended buffer. +// This method conforms to the encoding.TextAppender interface, and is useful for serializing the Version +// without allocating, provided the caller has pre-allocated sufficient space in b. +func (v Version) AppendText(b []byte) ([]byte, error) { + if b == nil { + b = make([]byte, 0, length(v)) + } - fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) + b = append(strconv.AppendInt(b, v.Major, 10), '.') + b = append(strconv.AppendInt(b, v.Minor, 10), '.') + b = strconv.AppendInt(b, v.Patch, 10) if v.PreRelease != "" { - fmt.Fprintf(&buffer, "-%s", v.PreRelease) + b = append(append(b, '-'), v.PreRelease...) } - if v.Metadata != "" { - fmt.Fprintf(&buffer, "+%s", v.Metadata) + b = append(append(b, '+'), v.Metadata...) } - return buffer.String() + return b, nil } -// Compare tests if v is less than, equal to, or greater than versionB, -// returning -1, 0, or +1 respectively. -func (v Version) Compare(versionB Version) int { - if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 { - return cmp - } - return preReleaseCompare(v, versionB) -} - -// Slice converts the comparable parts of the semver into a slice of integers. -func (v Version) Slice() []int64 { - return []int64{v.Major, v.Minor, v.Patch} -} +// String returns the string representation of the version. +func (v Version) String() string { + bs := make([]byte, 0, length(v)) + bs, _ = v.AppendText(bs) -// Slice splits the pre-release suffix string -func (p PreRelease) Slice() []string { - preRelease := string(p) - return strings.Split(preRelease, ".") + return string(bs) } -func preReleaseCompare(versionA Version, versionB Version) int { - a := versionA.PreRelease - b := versionB.PreRelease +// Compare tests if v is less than, equal to, or greater than other, returning -1, 0, or +1 respectively. +// Comparison is based on the SemVer specification (https://semver.org/#spec-item-11). +func (v Version) Compare(other Version) int { + if v.Major > other.Major { + return 1 + } else if v.Major < other.Major { + return -1 + } - /* Handle the case where if two versions are otherwise equal it is the - * one without a PreRelease that is greater */ - if len(a) == 0 && (len(b) > 0) { + if v.Minor > other.Minor { return 1 - } else if len(b) == 0 && (len(a) > 0) { + } else if v.Minor < other.Minor { return -1 } - // If there is a prerelease, check and compare each part. - return recursivePreReleaseCompare(a.Slice(), b.Slice()) -} + if v.Patch > other.Patch { + return 1 + } else if v.Patch < other.Patch { + return -1 + } -func recursiveCompare(versionA []int64, versionB []int64) int { - if len(versionA) == 0 { + if v.PreRelease == other.PreRelease { return 0 } - a := versionA[0] - b := versionB[0] - - if a > b { + // if two versions are otherwise equal it is the one without a pre-release that is greater + if v.PreRelease == "" && other.PreRelease != "" { return 1 - } else if a < b { + } + if other.PreRelease == "" && v.PreRelease != "" { return -1 } - return recursiveCompare(versionA[1:], versionB[1:]) -} + a, afterA := cut(v.PreRelease, '.') + b, afterB := cut(other.PreRelease, '.') -func recursivePreReleaseCompare(versionA []string, versionB []string) int { - // A larger set of pre-release fields has a higher precedence than a smaller set, - // if all of the preceding identifiers are equal. - if len(versionA) == 0 { - if len(versionB) > 0 { + for { + if a == "" && b != "" { return -1 } - return 0 - } else if len(versionB) == 0 { - // We're longer than versionB so return 1. - return 1 - } - - a := versionA[0] - b := versionB[0] - - aInt := false - bInt := false + if a != "" && b == "" { + return 1 + } - aI, err := strconv.Atoi(versionA[0]) - if err == nil { - aInt = true - } + aIsInt := isAllDecimals(a) + bIsInt := isAllDecimals(b) - bI, err := strconv.Atoi(versionB[0]) - if err == nil { - bInt = true - } + // numeric identifiers have lower precedence than non-numeric + if aIsInt && !bIsInt { + return -1 + } else if !aIsInt && bIsInt { + return 1 + } - // Numeric identifiers always have lower precedence than non-numeric identifiers. - if aInt && !bInt { - return -1 - } else if !aInt && bInt { - return 1 - } + if aIsInt && bIsInt { + aInt, _ := strconv.Atoi(a) + bInt, _ := strconv.Atoi(b) + + if aInt > bInt { + return 1 + } else if aInt < bInt { + return -1 + } + } else { + // string comparison + if a > b { + return 1 + } else if a < b { + return -1 + } + } - // Handle Integer Comparison - if aInt && bInt { - if aI > bI { + // a larger set of pre-release fields has a higher precedence than a + // smaller set, if all of the preceding identifiers are equal. + if afterA != "" && afterB == "" { return 1 - } else if aI < bI { + } else if afterA == "" && afterB != "" { return -1 } - } - // Handle String Comparison - if a > b { - return 1 - } else if a < b { - return -1 + a, afterA = cut(afterA, '.') + b, afterB = cut(afterB, '.') } - - return recursivePreReleaseCompare(versionA[1:], versionB[1:]) } -// validateIdentifier makes sure the provided identifier satisfies semver spec -func validateIdentifier(id string) error { - if id != "" && !reIdentifier.MatchString(id) { - return fmt.Errorf("%s is not a valid semver identifier", id) +func isAllDecimals(s string) bool { + for _, r := range s { + if r < '0' || r > '9' { + return false + } } - return nil + return s != "" } -// reIdentifier is a regular expression used to check that pre-release and metadata -// identifiers satisfy the spec requirements -var reIdentifier = regexp.MustCompile(`^[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*$`) - -// Compare compares two semver strings. -func Compare(a, b string) int { - aV, err := NewVersion(strings.TrimPrefix(a, "v")) - if err != nil { - return -1 +// length allows calculating the length of the version for pre-allocation. +func length(v Version) int { + n := util.NumDigitsInt64(v.Major) + util.NumDigitsInt64(v.Minor) + util.NumDigitsInt64(v.Patch) + 2 + if v.PreRelease != "" { + n += len(v.PreRelease) + 1 } - - bV, err := NewVersion(strings.TrimPrefix(b, "v")) - if err != nil { - return 1 + if v.Metadata != "" { + n += len(v.Metadata) + 1 } + return n +} - return aV.Compare(*bV) +// cut is a *slightly* faster version of strings.Cut only accepting +// single byte separators, and skipping the boolean return value. +func cut(s string, sep byte) (before, after string) { + if i := strings.IndexByte(s, sep); i >= 0 { + return s[:i], s[i+1:] + } + return s, "" } diff --git a/vendor/github.com/open-policy-agent/opa/internal/strvals/doc.go b/vendor/github.com/open-policy-agent/opa/internal/strvals/doc.go deleted file mode 100644 index 019dc87bb9b4..000000000000 --- a/vendor/github.com/open-policy-agent/opa/internal/strvals/doc.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright The Helm Authors. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Package strvals provides tools for working with strval lines. - -OPA runtime config supports a compressed format for YAML settings which we call strvals. -The format is roughly like this: - - name=value,topname.subname=value - -The above is equivalent to the YAML document - - name: value - topname: - subname: value - -This package provides a parser and utilities for converting the strvals format -to other formats. -*/ -package strvals 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 deleted file mode 100644 index 6d867262f5bd..000000000000 --- a/vendor/github.com/open-policy-agent/opa/internal/strvals/parser.go +++ /dev/null @@ -1,429 +0,0 @@ -/* -Copyright The Helm Authors. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package strvals - -import ( - "bytes" - "errors" - "fmt" - "io" - "strconv" - "strings" - - "sigs.k8s.io/yaml" -) - -// ErrNotList indicates that a non-list was treated as a list. -var ErrNotList = errors.New("not a list") - -// MaxIndex is the maximum index that will be allowed by setIndex. -// The default value 65536 = 1024 * 64 -const MaxIndex = 65536 - -// ToYAML takes a string of arguments and converts to a YAML document. -func ToYAML(s string) (string, error) { - m, err := Parse(s) - if err != nil { - return "", err - } - d, err := yaml.Marshal(m) - return string(d), err -} - -// Parse parses a set line. -// -// A set line is of the form name1=value1,name2=value2 -func Parse(s string) (map[string]any, error) { - vals := map[string]any{} - scanner := bytes.NewBufferString(s) - t := newParser(scanner, vals, false) - err := t.parse() - return vals, err -} - -// ParseString parses a set line and forces a string value. -// -// A set line is of the form name1=value1,name2=value2 -func ParseString(s string) (map[string]any, error) { - vals := map[string]any{} - scanner := bytes.NewBufferString(s) - t := newParser(scanner, vals, true) - err := t.parse() - return vals, err -} - -// ParseInto parses a strvals line and merges the result into dest. -// -// If the strval string has a key that exists in dest, it overwrites the -// dest version. -func ParseInto(s string, dest map[string]any) error { - scanner := bytes.NewBufferString(s) - t := newParser(scanner, dest, false) - return t.parse() -} - -// ParseIntoFile parses a filevals line and merges the result into dest. -// -// This method always returns a string as the value. -func ParseIntoFile(s string, dest map[string]any, runesToVal runesToVal) error { - scanner := bytes.NewBufferString(s) - t := newFileParser(scanner, dest, runesToVal) - return t.parse() -} - -// ParseIntoString parses a strvals line and merges the result into dest. -// -// This method always returns a string as the value. -func ParseIntoString(s string, dest map[string]any) error { - scanner := bytes.NewBufferString(s) - t := newParser(scanner, dest, true) - return t.parse() -} - -// parser is a simple parser that takes a strvals line and parses it into a -// map representation. -// -// where sc is the source of the original data being parsed -// where data is the final parsed data from the parses with correct types -// where st is a boolean to figure out if we're forcing it to parse values as string -type parser struct { - sc *bytes.Buffer - data map[string]any - runesToVal runesToVal -} - -type runesToVal func([]rune) (any, error) - -func newParser(sc *bytes.Buffer, data map[string]any, stringBool bool) *parser { - rs2v := func(rs []rune) (any, error) { - return typedVal(rs, stringBool), nil - } - return &parser{sc: sc, data: data, runesToVal: rs2v} -} - -func newFileParser(sc *bytes.Buffer, data map[string]any, runesToVal runesToVal) *parser { - return &parser{sc: sc, data: data, runesToVal: runesToVal} -} - -func (t *parser) parse() error { - for { - err := t.key(t.data) - if err == nil { - continue - } - if err == io.EOF { - return nil - } - return err - } -} - -func runeSet(r []rune) map[rune]bool { - s := make(map[rune]bool, len(r)) - for _, rr := range r { - s[rr] = true - } - return s -} - -func (t *parser) key(data map[string]any) error { - stop := runeSet([]rune{'=', '[', ',', '.'}) - for { - switch k, last, err := runesUntil(t.sc, stop); { - case err != nil: - if len(k) == 0 { - return err - } - return fmt.Errorf("key %q has no value", string(k)) - case last == '[': - // We are in a list index context, so we need to set an index. - i, err := t.keyIndex() - if err != nil { - return fmt.Errorf("error parsing index: %s", err) - } - kk := string(k) - // Find or create target list - list := []any{} - if _, ok := data[kk]; ok { - list = data[kk].([]any) - } - - // Now we need to get the value after the ]. - list, err = t.listItem(list, i) - set(data, kk, list) - return err - case last == '=': - // End of key. Consume =, Get value. - // FIXME: Get value list first - vl, e := t.valList() - switch e { - case nil: - set(data, string(k), vl) - return nil - case io.EOF: - set(data, string(k), "") - return e - case ErrNotList: - rs, e := t.val() - if e != nil && e != io.EOF { - return e - } - v, e := t.runesToVal(rs) - set(data, string(k), v) - return e - default: - return e - } - - case last == ',': - // No value given. Set the value to empty string. Return error. - set(data, string(k), "") - return fmt.Errorf("key %q has no value (cannot end with ,)", string(k)) - case last == '.': - // First, create or find the target map. - inner := map[string]any{} - if _, ok := data[string(k)]; ok { - inner = data[string(k)].(map[string]any) - } - - // Recurse - e := t.key(inner) - if len(inner) == 0 { - return fmt.Errorf("key map %q has no value", string(k)) - } - set(data, string(k), inner) - return e - } - } -} - -func set(data map[string]any, key string, val any) { - // If key is empty, don't set it. - if len(key) == 0 { - return - } - data[key] = val -} - -func setIndex(list []any, index int, val any) (l2 []any, err error) { - // There are possible index values that are out of range on a target system - // causing a panic. This will catch the panic and return an error instead. - // The value of the index that causes a panic varies from system to system. - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("error processing index %d: %s", index, r) - } - }() - - if index < 0 { - return list, fmt.Errorf("negative %d index not allowed", index) - } - if index > MaxIndex { - return list, fmt.Errorf("index of %d is greater than maximum supported index of %d", index, MaxIndex) - } - if len(list) <= index { - newlist := make([]any, index+1) - copy(newlist, list) - list = newlist - } - list[index] = val - return list, nil -} - -func (t *parser) keyIndex() (int, error) { - // First, get the key. - stop := runeSet([]rune{']'}) - v, _, err := runesUntil(t.sc, stop) - if err != nil { - return 0, err - } - // v should be the index - return strconv.Atoi(string(v)) - -} -func (t *parser) listItem(list []any, i int) ([]any, error) { - if i < 0 { - return list, fmt.Errorf("negative %d index not allowed", i) - } - stop := runeSet([]rune{'[', '.', '='}) - switch k, last, err := runesUntil(t.sc, stop); { - case len(k) > 0: - return list, fmt.Errorf("unexpected data at end of array index: %q", k) - case err != nil: - return list, err - case last == '=': - vl, e := t.valList() - switch e { - case nil: - return setIndex(list, i, vl) - case io.EOF: - return setIndex(list, i, "") - case ErrNotList: - rs, e := t.val() - if e != nil && e != io.EOF { - return list, e - } - v, e := t.runesToVal(rs) - if e != nil { - return nil, e - } - return setIndex(list, i, v) - default: - return list, e - } - case last == '[': - // now we have a nested list. Read the index and handle. - i, err := t.keyIndex() - if err != nil { - return list, fmt.Errorf("error parsing index: %s", err) - } - // Now we need to get the value after the ]. - list2, err := t.listItem(list, i) - if err != nil { - return nil, err - } - return setIndex(list, i, list2) - case last == '.': - // We have a nested object. Send to t.key - inner := map[string]any{} - if len(list) > i { - var ok bool - inner, ok = list[i].(map[string]any) - if !ok { - // We have indices out of order. Initialize empty value. - list[i] = map[string]any{} - inner = list[i].(map[string]any) - } - } - - // Recurse - e := t.key(inner) - if e != nil { - return list, e - } - return setIndex(list, i, inner) - default: - return nil, fmt.Errorf("parse error: unexpected token %v", last) - } -} - -func (t *parser) val() ([]rune, error) { - stop := runeSet([]rune{','}) - v, _, err := runesUntil(t.sc, stop) - return v, err -} - -func (t *parser) valList() ([]any, error) { - r, _, e := t.sc.ReadRune() - if e != nil { - return []any{}, e - } - - if r != '{' { - e = t.sc.UnreadRune() - if e != nil { - return []any{}, e - } - return []any{}, ErrNotList - } - - list := []any{} - stop := runeSet([]rune{',', '}'}) - for { - switch rs, last, err := runesUntil(t.sc, stop); { - case err != nil: - if err == io.EOF { - err = errors.New("list must terminate with '}'") - } - return list, err - case last == '}': - // If this is followed by ',', consume it. - if r, _, e := t.sc.ReadRune(); e == nil && r != ',' { - e = t.sc.UnreadRune() - if e != nil { - return []any{}, e - } - } - v, e := t.runesToVal(rs) - list = append(list, v) - return list, e - case last == ',': - v, e := t.runesToVal(rs) - if e != nil { - return list, e - } - list = append(list, v) - } - } -} - -func runesUntil(in io.RuneReader, stop map[rune]bool) ([]rune, rune, error) { - var v []rune - for { - switch r, _, e := in.ReadRune(); { - case e != nil: - return v, r, e - case inMap(r, stop): - return v, r, nil - case r == '\\': - next, _, e := in.ReadRune() - if e != nil { - return v, next, e - } - v = append(v, next) - default: - v = append(v, r) - } - } -} - -func inMap(k rune, m map[rune]bool) bool { - _, ok := m[k] - return ok -} - -func typedVal(v []rune, st bool) any { - val := string(v) - - if st { - return val - } - - if strings.EqualFold(val, "true") { - return true - } - - if strings.EqualFold(val, "false") { - return false - } - - if strings.EqualFold(val, "null") { - return struct{}{} - } - - if strings.EqualFold(val, "0") { - return int64(0) - } - - // If this value does not start with zero, try parsing it to an int - if len(val) != 0 && val[0] != '0' { - if iv, err := strconv.ParseInt(val, 10, 64); err == nil { - return iv - } - } - - return val -} 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 0695ce94fe72..a2f23d9a643d 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 @@ -83,7 +83,7 @@ func readModule(r io.Reader) (*module.Module, error) { var m module.Module - if err := readSections(r, &m); err != nil && err != io.EOF { + if err := readSections(r, &m); err != io.EOF { return nil, err } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/annotations.go b/vendor/github.com/open-policy-agent/opa/v1/ast/annotations.go index 36f854c618d8..603ab5cd7734 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/annotations.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/annotations.go @@ -433,18 +433,7 @@ func (a *Annotations) toObject() (*Object, *Error) { } if len(a.Scope) > 0 { - switch a.Scope { - case annotationScopeDocument: - obj.Insert(InternedTerm("scope"), InternedTerm("document")) - case annotationScopePackage: - obj.Insert(InternedTerm("scope"), InternedTerm("package")) - case annotationScopeRule: - obj.Insert(InternedTerm("scope"), InternedTerm("rule")) - case annotationScopeSubpackages: - obj.Insert(InternedTerm("scope"), InternedTerm("subpackages")) - default: - obj.Insert(InternedTerm("scope"), StringTerm(a.Scope)) - } + obj.Insert(InternedTerm("scope"), InternedTerm(a.Scope)) } if len(a.Title) > 0 { @@ -752,10 +741,7 @@ func (c *CompileAnnotation) Compare(other *CompileAnnotation) int { return -1 } - if cmp := slices.CompareFunc(c.Unknowns, other.Unknowns, - func(x, y Ref) int { - return x.Compare(y) - }); cmp != 0 { + if cmp := slices.CompareFunc(c.Unknowns, other.Unknowns, RefCompare); cmp != 0 { return cmp } return c.MaskRule.Compare(other.MaskRule) diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/builtins.go b/vendor/github.com/open-policy-agent/opa/v1/ast/builtins.go index 3d72aeab1f60..7e30a8051c27 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/builtins.go @@ -26,11 +26,16 @@ func RegisterBuiltin(b *Builtin) { BuiltinMap[b.Infix] = b InternStringTerm(b.Infix) + InternVarValue(b.Infix) } - InternStringTerm(b.Name) if strings.Contains(b.Name, ".") { - InternStringTerm(strings.Split(b.Name, ".")...) + parts := strings.Split(b.Name, ".") + InternStringTerm(parts...) + InternVarValue(parts[0]) + } else { + InternStringTerm(b.Name) + InternVarValue(b.Name) } } @@ -90,6 +95,7 @@ var DefaultBuiltins = [...]*Builtin{ // Arrays ArrayConcat, + ArrayFlatten, ArraySlice, ArrayReverse, @@ -146,6 +152,7 @@ var DefaultBuiltins = [...]*Builtin{ Sprintf, StringReverse, RenderTemplate, + InternalTemplateString, // Numbers NumbersRange, @@ -887,6 +894,18 @@ var ArrayConcat = &Builtin{ CanSkipBctx: true, } +var ArrayFlatten = &Builtin{ + Name: "array.flatten", + Description: "Non-recursively unpacks array items in arr into the flattened array. Other types are appended as-is.", + Decl: types.NewFunction( + types.Args( + types.Named("arr", types.NewArray(nil, types.A)).Description("the array to be flattened"), + ), + types.Named("flattened", types.NewArray(nil, types.A)).Description("array flattened one level"), + ), + CanSkipBctx: true, +} + var ArraySlice = &Builtin{ Name: "array.slice", Description: "Returns a slice of a given array. If `start` is greater or equal than `stop`, `slice` is `[]`.", @@ -1104,7 +1123,7 @@ var Concat = &Builtin{ types.Named("output", types.S).Description("the joined string"), ), Categories: stringsCat, - CanSkipBctx: true, + CanSkipBctx: false, } var FormatInt = &Builtin{ @@ -1272,7 +1291,7 @@ var Replace = &Builtin{ types.Named("y", types.S).Description("string with replaced substrings"), ), Categories: stringsCat, - CanSkipBctx: true, + CanSkipBctx: false, } var ReplaceN = &Builtin{ @@ -1292,7 +1311,7 @@ The old string comparisons are done in argument order.`, ), types.Named("output", types.S).Description("string with replaced substrings"), ), - CanSkipBctx: true, + CanSkipBctx: false, } var RegexReplace = &Builtin{ @@ -1656,7 +1675,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).Description("the object to patch"), // TODO(sr): types.A? + types.Named("target", types.A).Description("the object, array or set to patch"), types.Named("patches", types.NewArray( nil, types.NewObject( @@ -1817,7 +1836,8 @@ var ObjectKeys = &Builtin{ /* * Encoding */ -var encoding = category("encoding") +// Not using 'encoding' to avoid having to alias stdlib "encoding" imports +var catEncoding = category("encoding") var JSONMarshal = &Builtin{ Name: "json.marshal", @@ -1828,7 +1848,7 @@ var JSONMarshal = &Builtin{ ), types.Named("y", types.S).Description("the JSON string representation of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1850,7 +1870,7 @@ var JSONMarshalWithOptions = &Builtin{ ), types.Named("y", types.S).Description("the JSON string representation of `x`, with configured prefix/indent string(s) as appropriate"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1863,7 +1883,7 @@ var JSONUnmarshal = &Builtin{ ), types.Named("y", types.A).Description("the term deserialized from `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1876,7 +1896,7 @@ var JSONIsValid = &Builtin{ ), types.Named("result", types.B).Description("`true` if `x` is valid JSON, `false` otherwise"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1889,7 +1909,7 @@ var Base64Encode = &Builtin{ ), types.Named("y", types.S).Description("base64 serialization of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1902,7 +1922,7 @@ var Base64Decode = &Builtin{ ), types.Named("y", types.S).Description("base64 deserialization of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1915,7 +1935,7 @@ var Base64IsValid = &Builtin{ ), types.Named("result", types.B).Description("`true` if `x` is valid base64 encoded value, `false` otherwise"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1928,7 +1948,7 @@ var Base64UrlEncode = &Builtin{ ), types.Named("y", types.S).Description("base64url serialization of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1941,7 +1961,7 @@ var Base64UrlEncodeNoPad = &Builtin{ ), types.Named("y", types.S).Description("base64url serialization of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1954,7 +1974,7 @@ var Base64UrlDecode = &Builtin{ ), types.Named("y", types.S).Description("base64url deserialization of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1967,7 +1987,7 @@ var URLQueryDecode = &Builtin{ ), types.Named("y", types.S).Description("URL-encoding deserialization of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -1980,7 +2000,7 @@ var URLQueryEncode = &Builtin{ ), types.Named("y", types.S).Description("URL-encoding serialization of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -2004,7 +2024,7 @@ var URLQueryEncodeObject = &Builtin{ ), types.Named("y", types.S).Description("the URL-encoded serialization of `object`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -2019,7 +2039,7 @@ var URLQueryDecodeObject = &Builtin{ types.S, types.NewArray(nil, types.S)))).Description("the resulting object"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -2032,7 +2052,7 @@ var YAMLMarshal = &Builtin{ ), types.Named("y", types.S).Description("the YAML string representation of `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -2045,7 +2065,7 @@ var YAMLUnmarshal = &Builtin{ ), types.Named("y", types.A).Description("the term deserialized from `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -2059,7 +2079,7 @@ var YAMLIsValid = &Builtin{ ), types.Named("result", types.B).Description("`true` if `x` is valid YAML, `false` otherwise"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -2072,7 +2092,7 @@ var HexEncode = &Builtin{ ), types.Named("y", types.S).Description("serialization of `x` using hex-encoding"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -2085,7 +2105,7 @@ var HexDecode = &Builtin{ ), types.Named("y", types.S).Description("deserialized from `x`"), ), - Categories: encoding, + Categories: catEncoding, CanSkipBctx: true, } @@ -3383,6 +3403,12 @@ var InternalTestCase = &Builtin{ Decl: types.NewFunction([]types.Type{types.NewArray(nil, types.A)}, nil), } +var InternalTemplateString = &Builtin{ + Name: "internal.template_string", + Decl: types.NewFunction([]types.Type{types.NewArray(nil, types.A)}, types.S), + CanSkipBctx: true, // Uses bctx.Location for error reporting, but that is always provided in eval +} + /** * Deprecated built-ins. */ @@ -3397,7 +3423,7 @@ var SetDiff = &Builtin{ ), types.SetOfAny, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3411,7 +3437,7 @@ var NetCIDROverlap = &Builtin{ ), types.B, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3423,7 +3449,7 @@ var CastArray = &Builtin{ types.Args(types.A), types.NewArray(nil, types.A), ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3437,7 +3463,7 @@ var CastSet = &Builtin{ types.Args(types.A), types.SetOfAny, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3449,7 +3475,7 @@ var CastString = &Builtin{ types.Args(types.A), types.S, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3460,7 +3486,7 @@ var CastBoolean = &Builtin{ types.Args(types.A), types.B, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3471,7 +3497,7 @@ var CastNull = &Builtin{ types.Args(types.A), types.Nl, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3482,11 +3508,11 @@ var CastObject = &Builtin{ types.Args(types.A), types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } -// RegexMatchDeprecated declares `re_match` which has been deprecated. Use `regex.match` instead. +// RegexMatchDeprecated declares `re_match` which has been Deprecated. Use `regex.match` instead. var RegexMatchDeprecated = &Builtin{ Name: "re_match", Decl: types.NewFunction( @@ -3496,7 +3522,7 @@ var RegexMatchDeprecated = &Builtin{ ), types.B, ), - deprecated: true, + Deprecated: true, CanSkipBctx: false, } @@ -3513,7 +3539,7 @@ var All = &Builtin{ ), types.B, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3530,7 +3556,7 @@ var Any = &Builtin{ ), types.B, ), - deprecated: true, + Deprecated: true, CanSkipBctx: true, } @@ -3548,7 +3574,7 @@ type Builtin struct { Decl *types.Function `json:"decl"` // Built-in function type declaration. Infix string `json:"infix,omitempty"` // Unique name of infix operator. Default should be unset. Relation bool `json:"relation,omitempty"` // Indicates if the built-in acts as a relation. - deprecated bool `json:"-"` // Indicates if the built-in has been deprecated. + Deprecated bool `json:"deprecated,omitempty"` // Indicates if the built-in has been deprecated. CanSkipBctx bool `json:"-"` // Built-in needs no data from the built-in context. Nondeterministic bool `json:"nondeterministic,omitempty"` // Indicates if the built-in returns non-deterministic results. } @@ -3573,12 +3599,12 @@ func (b *Builtin) Minimal() *Builtin { return &cpy } -// IsDeprecated returns true if the Builtin function is deprecated and will be removed in a future release. +// IsDeprecated returns true if the Builtin function is Deprecated and will be removed in a future release. func (b *Builtin) IsDeprecated() bool { - return b.deprecated + return b.Deprecated } -// IsDeterministic returns true if the Builtin function returns non-deterministic results. +// IsNondeterministic returns true if the Builtin function returns non-deterministic results. func (b *Builtin) IsNondeterministic() bool { return b.Nondeterministic } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/capabilities.go b/vendor/github.com/open-policy-agent/opa/v1/ast/capabilities.go index 844cb66f0bab..170f0bf17612 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/capabilities.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/capabilities.go @@ -58,12 +58,14 @@ const FeatureRefHeads = "rule_head_refs" const FeatureRegoV1 = "rego_v1" const FeatureRegoV1Import = "rego_v1_import" const FeatureKeywordsInRefs = "keywords_in_refs" +const FeatureTemplateStrings = "template_strings" // Features carries the default features supported by this version of OPA. // Use RegisterFeatures to add to them. var Features = []string{ FeatureRegoV1, FeatureKeywordsInRefs, + FeatureTemplateStrings, } // RegisterFeatures lets applications wrapping OPA register features, to be @@ -228,13 +230,8 @@ func LoadCapabilitiesVersions() ([]string, error) { // MinimumCompatibleVersion returns the minimum compatible OPA version based on // the built-ins, features, and keywords in c. func (c *Capabilities) MinimumCompatibleVersion() (string, bool) { - var maxVersion semver.Version - // this is the oldest OPA release that includes capabilities - if err := maxVersion.Set("0.17.0"); err != nil { - panic("unreachable") - } - + maxVersion := semver.MustParse("0.17.0") minVersionIndex := minVersionIndexOnce() for _, bi := range c.Builtins { @@ -274,6 +271,12 @@ func (c *Capabilities) ContainsFeature(feature string) bool { return slices.Contains(c.Features, feature) } +func (c *Capabilities) ContainsBuiltin(name string) bool { + return slices.ContainsFunc(c.Builtins, func(builtin *Builtin) bool { + return builtin.Name == name + }) +} + // addBuiltinSorted inserts a built-in into c in sorted order. An existing built-in with the same name // will be overwritten. func (c *Capabilities) addBuiltinSorted(bi *Builtin) { diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/check.go b/vendor/github.com/open-policy-agent/opa/v1/ast/check.go index 0da7e26514f4..6e4d8ddd74b1 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/check.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/check.go @@ -6,8 +6,8 @@ package ast import ( "fmt" + "regexp" "slices" - "sort" "strings" "github.com/open-policy-agent/opa/v1/types" @@ -16,11 +16,6 @@ import ( type varRewriter func(Ref) Ref -// exprChecker defines the interface for executing type checking on a single -// expression. The exprChecker must update the provided TypeEnv with inferred -// types of vars. -type exprChecker func(*TypeEnv, *Expr) *Error - // typeChecker implements type checking on queries and rules. Errors are // accumulated on the typeChecker so that a single run can report multiple // issues. @@ -28,7 +23,6 @@ type typeChecker struct { builtins map[string]*Builtin required *Capabilities errs Errors - exprCheckers map[string]exprChecker varRewriter varRewriter ss *SchemaSet allowNet []string @@ -39,11 +33,7 @@ type typeChecker struct { // newTypeChecker returns a new typeChecker object that has no errors. func newTypeChecker() *typeChecker { - return &typeChecker{ - exprCheckers: map[string]exprChecker{ - "eq": checkExprEq, - }, - } + return &typeChecker{} } func (tc *typeChecker) newEnv(exist *TypeEnv) *TypeEnv { @@ -126,43 +116,39 @@ func (tc *typeChecker) Env(builtins map[string]*Builtin) *TypeEnv { // are found. The resulting TypeEnv wraps the provided one. The resulting // TypeEnv will be able to resolve types of vars contained in the body. func (tc *typeChecker) CheckBody(env *TypeEnv, body Body) (*TypeEnv, Errors) { + var errors []*Error - errors := []*Error{} env = tc.newEnv(env) vis := newRefChecker(env, tc.varRewriter) - - WalkExprs(body, func(expr *Expr) bool { - - closureErrs := tc.checkClosures(env, expr) - for _, err := range closureErrs { - errors = append(errors, err) - } - - hasClosureErrors := len(closureErrs) > 0 - - // reset errors from previous iteration - vis.errs = nil - NewGenericVisitor(vis.Visit).Walk(expr) - for _, err := range vis.errs { - errors = append(errors, err) - } - - hasRefErrors := len(vis.errs) > 0 - - if err := tc.checkExpr(env, expr); err != nil { - // Suppress this error if a more actionable one has occurred. In - // this case, if an error occurred in a ref or closure contained in - // this expression, and the error is due to a nil type, then it's - // likely to be the result of the more specific error. - skip := (hasClosureErrors || hasRefErrors) && causedByNilType(err) - if !skip { - errors = append(errors, err) + gv := NewGenericVisitor(vis.Visit) + + for _, bexpr := range body { + WalkExprs(bexpr, func(expr *Expr) bool { + closureErrs := tc.checkClosures(env, expr) + errors = append(errors, closureErrs...) + + // reset errors from previous iteration + vis.errs = nil + gv.Walk(expr) + errors = append(errors, vis.errs...) + + if err := tc.checkExpr(env, expr); err != nil { + hasClosureErrors := len(closureErrs) > 0 + hasRefErrors := len(vis.errs) > 0 + // Suppress this error if a more actionable one has occurred. In + // this case, if an error occurred in a ref or closure contained in + // this expression, and the error is due to a nil type, then it's + // likely to be the result of the more specific error. + skip := (hasClosureErrors || hasRefErrors) && causedByNilType(err) + if !skip { + errors = append(errors, err) + } } - } - return true - }) + return true + }) + } - tc.err(errors) + tc.err(errors...) return env, errors } @@ -243,7 +229,7 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { for _, schemaAnnot := range schemaAnnots { refType, err := tc.getSchemaType(schemaAnnot, rule) if err != nil { - tc.err([]*Error{err}) + tc.err(err) continue } @@ -259,7 +245,7 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { } else { newType, err := override(ref[len(prefixRef):], t, refType, rule) if err != nil { - tc.err([]*Error{err}) + tc.err(err) continue } env.tree.Put(prefixRef, newType) @@ -281,23 +267,25 @@ func (tc *typeChecker) checkRule(env *TypeEnv, as *AnnotationSet, rule *Rule) { var tpe types.Type 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.GetByValue(v) == nil { - cpy.tree.PutOne(v, types.A) - } - return false - }) + for _, arg := range rule.Head.Args { + // If args are not referred to in body, infer as any. + WalkTerms(arg, func(t *Term) bool { + if _, ok := t.Value.(Var); ok { + if cpy.GetByValue(t.Value) == nil { + cpy.tree.PutOne(t.Value, types.A) + } + } + return false + }) + } // Construct function type. args := make([]types.Type, len(rule.Head.Args)) - for i := range len(rule.Head.Args) { + for i := range rule.Head.Args { args[i] = cpy.GetByValue(rule.Head.Args[i].Value) } - f := types.NewFunction(args, cpy.Get(rule.Head.Value)) - - tpe = f + tpe = types.NewFunction(args, cpy.GetByValue(rule.Head.Value.Value)) } else { switch rule.Head.RuleKind() { case SingleValue: @@ -310,7 +298,7 @@ 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, "%s", err.Error())}) + tc.err(NewError(TypeErr, rule.Head.Location, "%s", err.Error())) tpe = nil } } else if typeV != nil { @@ -374,19 +362,14 @@ func (tc *typeChecker) checkExpr(env *TypeEnv, expr *Expr) *Error { } } - checker := tc.exprCheckers[operator] - if checker != nil { - return checker(env, expr) + if operator == "eq" { + return checkExprEq(env, expr) } return tc.checkExprBuiltin(env, expr) } func (tc *typeChecker) checkExprBuiltin(env *TypeEnv, expr *Expr) *Error { - - args := expr.Operands() - pre := getArgTypes(env, args) - // NOTE(tsandall): undefined functions will have been caught earlier in the // compiler. We check for undefined functions before the safety check so // that references to non-existent functions result in undefined function @@ -405,10 +388,12 @@ func (tc *typeChecker) checkExprBuiltin(env *TypeEnv, expr *Expr) *Error { return NewError(TypeErr, expr.Location, "undefined function %v", name) } - // check if the expression refers to a function that contains an error - _, ok := tpe.(types.Any) - if ok { - return nil + if t, ok := tpe.(types.Any); ok { + // A type.Any with a len(0) is created by using types.A , this represents a potential non-local reference + // This is the exception when checking if the type represents a function + if len(t) == 0 { + return nil + } } ftpe, ok := tpe.(*types.Function) @@ -424,12 +409,14 @@ func (tc *typeChecker) checkExprBuiltin(env *TypeEnv, expr *Expr) *Error { namedFargs.Args = append(namedFargs.Args, ftpe.NamedResult()) } + args := expr.Operands() + if len(args) > len(fargs.Args) && fargs.Variadic == nil { - return newArgError(expr.Location, name, "too many arguments", pre, namedFargs) + return newArgError(expr.Location, name, "too many arguments", getArgTypes(env, args), namedFargs) } if len(args) < len(ftpe.FuncArgs().Args) { - return newArgError(expr.Location, name, "too few arguments", pre, namedFargs) + return newArgError(expr.Location, name, "too few arguments", getArgTypes(env, args), namedFargs) } for i := range args { @@ -601,7 +588,7 @@ func unify1(env *TypeEnv, term *Term, tpe types.Type, union bool) bool { return unifies } return false - case Set: + case *set: switch tpe := tpe.(type) { case *types.Set: return unify1Set(env, v, tpe, union) @@ -676,14 +663,14 @@ func unify1Object(env *TypeEnv, val Object, tpe *types.Object, union bool) bool return !stop } -func unify1Set(env *TypeEnv, val Set, tpe *types.Set, union bool) bool { +func unify1Set(env *TypeEnv, val *set, tpe *types.Set, union bool) bool { of := types.Values(tpe) return !val.Until(func(elem *Term) bool { return !unify1(env, elem, of, union) }) } -func (tc *typeChecker) err(errors []*Error) { +func (tc *typeChecker) err(errors ...*Error) { tc.errs = append(tc.errs, errors...) } @@ -704,7 +691,6 @@ func newRefChecker(env *TypeEnv, f varRewriter) *refChecker { return &refChecker{ env: env, - errs: nil, varRewriter: f, } } @@ -716,8 +702,9 @@ func (rc *refChecker) Visit(x any) bool { case *Expr: switch terms := x.Terms.(type) { case []*Term: + vis := NewGenericVisitor(rc.Visit) for i := 1; i < len(terms); i++ { - NewGenericVisitor(rc.Visit).Walk(terms[i]) + vis.Walk(terms[i]) } return true case *Term: @@ -807,7 +794,6 @@ func (rc *refChecker) checkRef(curr *TypeEnv, node *typeTreeNode, ref Ref, idx i } func (rc *refChecker) checkRefLeaf(tpe types.Type, ref Ref, idx int) *Error { - if idx == len(ref) { return nil } @@ -822,16 +808,16 @@ func (rc *refChecker) checkRefLeaf(tpe types.Type, ref Ref, idx int) *Error { switch value := head.Value.(type) { case Var: - if exist := rc.env.GetByValue(value); exist != nil { + if exist := rc.env.GetByValue(head.Value); exist != nil { if !unifies(exist, keys) { return newRefErrInvalid(ref[0].Location, rc.varRewriter(ref), idx, exist, keys, getOneOfForType(tpe)) } } else { - rc.env.tree.PutOne(value, types.Keys(tpe)) + rc.env.tree.PutOne(head.Value, types.Keys(tpe)) } case Ref: - if exist := rc.env.Get(value); exist != nil { + if exist := rc.env.GetByRef(value); exist != nil { if !unifies(exist, keys) { return newRefErrInvalid(ref[0].Location, rc.varRewriter(ref), idx, exist, keys, getOneOfForType(tpe)) } @@ -1104,7 +1090,21 @@ func newRefErrInvalid(loc *Location, ref Ref, idx int, have, want types.Type, on } func newRefErrUnsupported(loc *Location, ref Ref, idx int, have types.Type) *Error { - err := newRefError(loc, ref) + var err *Error + switch have.(type) { + case *types.Function: + var function string + // drop any trailing references to unidentified parameters (e.g. __local1__) + if match, err := regexp.MatchString(`__local[0-9]+__`, ref[len(ref)-1].Value.String()); err == nil && match { + function = ref[:len(ref)-1].String() + } else { + function = ref.String() + } + + err = NewError(TypeErr, loc, "function %s used as reference, not called", function) + default: + err = newRefError(loc, ref) + } err.Details = &RefErrUnsupportedDetail{ Ref: ref, Pos: idx, @@ -1132,7 +1132,7 @@ func getOneOfForNode(node *typeTreeNode) (result []Value) { return false }) - sortValueSlice(result) + slices.SortFunc(result, Value.Compare) return result } @@ -1155,16 +1155,10 @@ func getOneOfForType(tpe types.Type) (result []Value) { } result = removeDuplicate(result) - sortValueSlice(result) + slices.SortFunc(result, Value.Compare) return result } -func sortValueSlice(sl []Value) { - sort.Slice(sl, func(i, j int) bool { - return sl[i].Compare(sl[j]) < 0 - }) -} - func removeDuplicate(list []Value) []Value { seen := make(map[Value]bool) var newResult []Value @@ -1188,13 +1182,13 @@ func getArgTypes(env *TypeEnv, args []*Term) []types.Type { // getPrefix returns the shortest prefix of ref that exists in env func getPrefix(env *TypeEnv, ref Ref) (Ref, types.Type) { if len(ref) == 1 { - t := env.Get(ref) + t := env.GetByRef(ref) if t != nil { return ref, t } } for i := 1; i < len(ref); i++ { - t := env.Get(ref[:i]) + t := env.GetByRef(ref[:i]) if t != nil { return ref[:i], t } @@ -1202,12 +1196,14 @@ func getPrefix(env *TypeEnv, ref Ref) (Ref, types.Type) { return nil, nil } +var dynamicAnyAny = types.NewDynamicProperty(types.A, types.A) + // override takes a type t and returns a type obtained from t where the path represented by ref within it has type o (overriding the original type of that path) func override(ref Ref, t types.Type, o types.Type, rule *Rule) (types.Type, *Error) { var newStaticProps []*types.StaticProperty obj, ok := t.(*types.Object) if !ok { - newType, err := getObjectType(ref, o, rule, types.NewDynamicProperty(types.A, types.A)) + newType, err := getObjectType(ref, o, rule, dynamicAnyAny) if err != nil { return nil, err } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/compare.go b/vendor/github.com/open-policy-agent/opa/v1/ast/compare.go index 663ad5ae057b..8cd2bf9dc410 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/compare.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/compare.go @@ -96,6 +96,9 @@ func Compare(a, b any) int { return -1 } return 1 + case *TemplateString: + b := b.(*TemplateString) + return a.Compare(b) case Var: return VarCompare(a, b.(Var)) case Ref: @@ -179,26 +182,28 @@ func sortOrder(x any) int { return 2 case String: return 3 - case Var: + case *TemplateString: return 4 - case Ref: + case Var: return 5 - case *Array: + case Ref: return 6 - case Object: + case *Array: return 7 - case Set: + case Object: return 8 - case *ArrayComprehension: + case Set: return 9 - case *ObjectComprehension: + case *ArrayComprehension: return 10 - case *SetComprehension: + case *ObjectComprehension: return 11 - case Call: + case *SetComprehension: return 12 - case Args: + case Call: return 13 + case Args: + return 14 case *Expr: return 100 case *SomeDecl: @@ -322,14 +327,6 @@ func TermValueEqual(a, b *Term) bool { } 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) @@ -345,6 +342,8 @@ func ValueEqual(a, b Value) bool { return v.Equal(b) case *Array: return v.Equal(b) + case *TemplateString: + return v.Equal(b) } return a.Compare(b) == 0 diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/compile.go b/vendor/github.com/open-policy-agent/opa/v1/ast/compile.go index 62e22bf93768..a9455145ef77 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/compile.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/compile.go @@ -11,8 +11,8 @@ import ( "maps" "slices" "sort" - "strconv" "strings" + "sync" "github.com/open-policy-agent/opa/internal/debug" "github.com/open-policy-agent/opa/internal/gojsonschema" @@ -27,7 +27,7 @@ import ( const CompileErrorLimitDefault = 10 var ( - errLimitReached = NewError(CompileErr, nil, "error limit reached") + errLimitReached = newErrorString(CompileErr, nil, "error limit reached") doubleEq = Equal.Ref() ) @@ -128,10 +128,11 @@ type Compiler struct { localvargen *localVarGenerator moduleLoader ModuleLoader - ruleIndices *util.HasherMap[Ref, RuleIndex] stages []stage maxErrs int - sorted []string // list of sorted module names + errCount uint32 + mu *sync.Mutex // Mutex to protect both 'errCount' and 'Errors' + sorted []string // list of sorted module names pathExists func([]string) (bool, error) pathConflictCheckRoots []string after map[string][]CompilerStageDefinition @@ -157,6 +158,8 @@ type Compiler struct { evalMode CompilerEvalMode // rewriteTestRulesForTracing bool // rewrite test rules to capture dynamic values for tracing. defaultRegoVersion RegoVersion + skipStages map[StageID]struct{} // stages to skip during compilation + plan *executionPlan // computed execution plan (cached) } func (c *Compiler) DefaultRegoVersion() RegoVersion { @@ -166,6 +169,93 @@ func (c *Compiler) DefaultRegoVersion() RegoVersion { // CompilerStage defines the interface for stages in the compiler. type CompilerStage func(*Compiler) *Error +// StageID uniquely identifies a compiler stage. +type StageID string + +// Compiler stage identifiers. +// Please use them when you depend on a compiler stage, like via [ast.Compiler.WithStageAfterID]. +// There is no guarantee that they are stable across OPA versions, but using the identifiers +// at least lets you know what your attention is needed when you depend on the stages. +const ( + StageResolveRefs StageID = "ResolveRefs" + StageInitLocalVarGen StageID = "InitLocalVarGen" + StageRewriteRuleHeadRefs StageID = "RewriteRuleHeadRefs" + StageCheckKeywordOverrides StageID = "CheckKeywordOverrides" + StageCheckDuplicateImports StageID = "CheckDuplicateImports" + StageRemoveImports StageID = "RemoveImports" + StageSetModuleTree StageID = "SetModuleTree" + StageSetRuleTree StageID = "SetRuleTree" + StageRewriteLocalVars StageID = "RewriteLocalVars" + StageRewriteTemplateStrings StageID = "RewriteTemplateStrings" + StageCheckVoidCalls StageID = "CheckVoidCalls" + StageRewritePrintCalls StageID = "RewritePrintCalls" + StageRewriteExprTerms StageID = "RewriteExprTerms" + StageParseMetadataBlocks StageID = "ParseMetadataBlocks" + StageSetAnnotationSet StageID = "SetAnnotationSet" + StageRewriteRegoMetadataCalls StageID = "RewriteRegoMetadataCalls" + StageSetGraph StageID = "SetGraph" + StageRewriteComprehensionTerms StageID = "RewriteComprehensionTerms" + StageRewriteRefsInHead StageID = "RewriteRefsInHead" + StageRewriteWithValues StageID = "RewriteWithValues" + StageCheckRuleConflicts StageID = "CheckRuleConflicts" + StageCheckUndefinedFuncs StageID = "CheckUndefinedFuncs" + StageCheckSafetyRuleHeads StageID = "CheckSafetyRuleHeads" + StageCheckSafetyRuleBodies StageID = "CheckSafetyRuleBodies" + StageRewriteEquals StageID = "RewriteEquals" + StageRewriteDynamicTerms StageID = "RewriteDynamicTerms" + StageRewriteTestRulesForTracing StageID = "RewriteTestRulesForTracing" + StageCheckRecursion StageID = "CheckRecursion" + StageCheckTypes StageID = "CheckTypes" + StageCheckUnsafeBuiltins StageID = "CheckUnsafeBuiltins" + StageCheckDeprecatedBuiltins StageID = "CheckDeprecatedBuiltins" + StageBuildRuleIndices StageID = "BuildRuleIndices" + StageBuildComprehensionIndices StageID = "BuildComprehensionIndices" + StageBuildRequiredCapabilities StageID = "BuildRequiredCapabilities" + + // These only exist in the [ast.QueryCompiler]: + StageCheckSafety StageID = "CheckSafety" +) + +// AllStages returns the complete list of compiler stages in execution order. +func AllStages() []StageID { + return []StageID{ + StageResolveRefs, + StageInitLocalVarGen, + StageRewriteRuleHeadRefs, + StageCheckKeywordOverrides, + StageCheckDuplicateImports, + StageRemoveImports, + StageSetModuleTree, + StageSetRuleTree, + StageRewriteLocalVars, + StageRewriteTemplateStrings, + StageCheckVoidCalls, + StageRewritePrintCalls, + StageRewriteExprTerms, + StageParseMetadataBlocks, + StageSetAnnotationSet, + StageRewriteRegoMetadataCalls, + StageSetGraph, + StageRewriteComprehensionTerms, + StageRewriteRefsInHead, + StageRewriteWithValues, + StageCheckRuleConflicts, + StageCheckUndefinedFuncs, + StageCheckSafetyRuleHeads, + StageCheckSafetyRuleBodies, + StageRewriteEquals, + StageRewriteDynamicTerms, + StageRewriteTestRulesForTracing, + StageCheckRecursion, + StageCheckTypes, + StageCheckUnsafeBuiltins, + StageCheckDeprecatedBuiltins, + StageBuildRuleIndices, + StageBuildComprehensionIndices, + StageBuildRequiredCapabilities, + } +} + // CompilerEvalMode allows toggling certain stages that are only // needed for certain modes, Concretely, only "topdown" mode will // have the compiler build comprehension and rule indices. @@ -188,6 +278,18 @@ type CompilerStageDefinition struct { Stage CompilerStage } +// executionPlan represents the complete ordered list of stages to execute. +type executionPlan struct { + stages []plannedStage +} + +// plannedStage represents a single stage in the execution plan. +type plannedStage struct { + name string + metricName string + f func() +} + // RulesOptions defines the options for retrieving rules by Ref from the // compiler. type RulesOptions struct { @@ -272,8 +374,15 @@ type QueryCompiler interface { // WithStageAfter registers a stage to run during query compilation after // the named stage. + // + // Caution: Use [ast.QueryCompiler.WithStageAfterID] instead. It provides + // more (Golang) compile-time safety WithStageAfter(after string, stage QueryCompilerStageDefinition) QueryCompiler + // WithStageAfterID registers a stage to run during query compilation after + // the named stage. + WithStageAfterID(after StageID, stage QueryCompilerStageDefinition) QueryCompiler + // RewrittenVars maps generated vars in the compiled query to vars from the // parsed query. For example, given the query "input := 1" the rewritten // query would be "__local0__ = 1". The mapping would then be {__local0__: input}. @@ -298,7 +407,7 @@ type QueryCompilerStageDefinition struct { } type stage struct { - name string + name StageID metricName string f func() } @@ -310,8 +419,8 @@ func NewCompiler() *Compiler { Modules: map[string]*Module{}, RewrittenVars: map[Var]Var{}, Required: &Capabilities{}, - ruleIndices: util.NewHasherMap[Ref, RuleIndex](RefEqual), maxErrs: CompileErrorLimitDefault, + mu: &sync.Mutex{}, after: map[string][]CompilerStageDefinition{}, unsafeBuiltinsMap: map[string]struct{}{}, deprecatedBuiltinsMap: map[string]struct{}{}, @@ -327,42 +436,43 @@ func NewCompiler() *Compiler { // Reference resolution should run first as it may be used to lazily // load additional modules. If any stages run before resolution, they // need to be re-run after resolution. - {"ResolveRefs", "compile_stage_resolve_refs", c.resolveAllRefs}, + {StageResolveRefs, "compile_stage_resolve_refs", c.resolveAllRefs}, // The local variable generator must be initialized after references are // resolved and the dynamic module loader has run but before subsequent // stages that need to generate variables. - {"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_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 - {"RewriteLocalVars", "compile_stage_rewrite_local_vars", c.rewriteLocalVars}, - {"CheckVoidCalls", "compile_stage_check_void_calls", c.checkVoidCalls}, - {"RewritePrintCalls", "compile_stage_rewrite_print_calls", c.rewritePrintCalls}, - {"RewriteExprTerms", "compile_stage_rewrite_expr_terms", c.rewriteExprTerms}, - {"ParseMetadataBlocks", "compile_stage_parse_metadata_blocks", c.parseMetadataBlocks}, - {"SetAnnotationSet", "compile_stage_set_annotationset", c.setAnnotationSet}, - {"RewriteRegoMetadataCalls", "compile_stage_rewrite_rego_metadata_calls", c.rewriteRegoMetadataCalls}, - {"SetGraph", "compile_stage_set_graph", c.setGraph}, - {"RewriteComprehensionTerms", "compile_stage_rewrite_comprehension_terms", c.rewriteComprehensionTerms}, - {"RewriteRefsInHead", "compile_stage_rewrite_refs_in_head", c.rewriteRefsInHead}, - {"RewriteWithValues", "compile_stage_rewrite_with_values", c.rewriteWithModifiers}, - {"CheckRuleConflicts", "compile_stage_check_rule_conflicts", c.checkRuleConflicts}, - {"CheckUndefinedFuncs", "compile_stage_check_undefined_funcs", c.checkUndefinedFuncs}, - {"CheckSafetyRuleHeads", "compile_stage_check_safety_rule_heads", c.checkSafetyRuleHeads}, - {"CheckSafetyRuleBodies", "compile_stage_check_safety_rule_bodies", c.checkSafetyRuleBodies}, - {"RewriteEquals", "compile_stage_rewrite_equals", c.rewriteEquals}, - {"RewriteDynamicTerms", "compile_stage_rewrite_dynamic_terms", c.rewriteDynamicTerms}, - {"RewriteTestRulesForTracing", "compile_stage_rewrite_test_rules_for_tracing", c.rewriteTestRuleEqualities}, // must run after RewriteDynamicTerms - {"CheckRecursion", "compile_stage_check_recursion", c.checkRecursion}, - {"CheckTypes", "compile_stage_check_types", c.checkTypes}, // must be run after CheckRecursion - {"CheckUnsafeBuiltins", "compile_state_check_unsafe_builtins", c.checkUnsafeBuiltins}, - {"CheckDeprecatedBuiltins", "compile_state_check_deprecated_builtins", c.checkDeprecatedBuiltins}, - {"BuildRuleIndices", "compile_stage_rebuild_indices", c.buildRuleIndices}, - {"BuildComprehensionIndices", "compile_stage_rebuild_comprehension_indices", c.buildComprehensionIndices}, - {"BuildRequiredCapabilities", "compile_stage_build_required_capabilities", c.buildRequiredCapabilities}, + {StageInitLocalVarGen, "compile_stage_init_local_var_gen", c.initLocalVarGen}, + {StageRewriteRuleHeadRefs, "compile_stage_rewrite_rule_head_refs", c.rewriteRuleHeadRefs}, + {StageCheckKeywordOverrides, "compile_stage_check_keyword_overrides", c.checkKeywordOverrides}, + {StageCheckDuplicateImports, "compile_stage_check_imports", c.checkImports}, + {StageRemoveImports, "compile_stage_remove_imports", c.removeImports}, + {StageSetModuleTree, "compile_stage_set_module_tree", c.setModuleTree}, + {StageSetRuleTree, "compile_stage_set_rule_tree", c.setRuleTree}, // depends on RewriteRuleHeadRefs + {StageRewriteLocalVars, "compile_stage_rewrite_local_vars", c.rewriteLocalVars}, + {StageRewriteTemplateStrings, "compile_stage_rewrite_template_strings", c.rewriteTemplateStrings}, + {StageCheckVoidCalls, "compile_stage_check_void_calls", c.checkVoidCalls}, + {StageRewritePrintCalls, "compile_stage_rewrite_print_calls", c.rewritePrintCalls}, + {StageRewriteExprTerms, "compile_stage_rewrite_expr_terms", c.rewriteExprTerms}, + {StageParseMetadataBlocks, "compile_stage_parse_metadata_blocks", c.parseMetadataBlocks}, + {StageSetAnnotationSet, "compile_stage_set_annotationset", c.setAnnotationSet}, + {StageRewriteRegoMetadataCalls, "compile_stage_rewrite_rego_metadata_calls", c.rewriteRegoMetadataCalls}, + {StageSetGraph, "compile_stage_set_graph", c.setGraph}, + {StageRewriteComprehensionTerms, "compile_stage_rewrite_comprehension_terms", c.rewriteComprehensionTerms}, + {StageRewriteRefsInHead, "compile_stage_rewrite_refs_in_head", c.rewriteRefsInHead}, + {StageRewriteWithValues, "compile_stage_rewrite_with_values", c.rewriteWithModifiers}, + {StageCheckRuleConflicts, "compile_stage_check_rule_conflicts", c.checkRuleConflicts}, + {StageCheckUndefinedFuncs, "compile_stage_check_undefined_funcs", c.checkUndefinedFuncs}, + {StageCheckSafetyRuleHeads, "compile_stage_check_safety_rule_heads", c.checkSafetyRuleHeads}, + {StageCheckSafetyRuleBodies, "compile_stage_check_safety_rule_bodies", c.checkSafetyRuleBodies}, + {StageRewriteEquals, "compile_stage_rewrite_equals", c.rewriteEquals}, + {StageRewriteDynamicTerms, "compile_stage_rewrite_dynamic_terms", c.rewriteDynamicTerms}, + {StageRewriteTestRulesForTracing, "compile_stage_rewrite_test_rules_for_tracing", c.rewriteTestRuleEqualities}, // must run after RewriteDynamicTerms + {StageCheckRecursion, "compile_stage_check_recursion", c.checkRecursion}, + {StageCheckTypes, "compile_stage_check_types", c.checkTypes}, // must be run after CheckRecursion + {StageCheckUnsafeBuiltins, "compile_state_check_unsafe_builtins", c.checkUnsafeBuiltins}, + {StageCheckDeprecatedBuiltins, "compile_state_check_deprecated_builtins", c.checkDeprecatedBuiltins}, + {StageBuildRuleIndices, "compile_stage_rebuild_indices", c.buildRuleIndices}, + {StageBuildComprehensionIndices, "compile_stage_rebuild_comprehension_indices", c.buildComprehensionIndices}, + {StageBuildRequiredCapabilities, "compile_stage_build_required_capabilities", c.buildRequiredCapabilities}, } return c @@ -402,11 +512,45 @@ func (c *Compiler) WithPathConflictsCheckRoots(rootPaths []string) *Compiler { // WithStageAfter registers a stage to run during compilation after // the named stage. +// +// Caution: Consider using [ast.QueryCompiler.WithStageAfterID] instead. It provides +// more (Golang) compile-time safety func (c *Compiler) WithStageAfter(after string, stage CompilerStageDefinition) *Compiler { c.after[after] = append(c.after[after], stage) + c.plan = nil // invalidate cached plan + return c +} + +// WithStageAfterID registers a stage to run during compilation after +// the identified stage. +func (c *Compiler) WithStageAfterID(after StageID, stage CompilerStageDefinition) *Compiler { + return c.WithStageAfter(string(after), stage) +} + +// WithSkipStages configures the compiler to skip the specified stages during +// compilation. This invalidates any cached execution plan. +func (c *Compiler) WithSkipStages(stages ...StageID) *Compiler { + if c.skipStages == nil { + c.skipStages = make(map[StageID]struct{}, len(stages)) + } + for _, s := range stages { + c.skipStages[s] = struct{}{} + } + c.plan = nil // invalidate cached plan return c } +// WithOnlyStagesUpTo configures the compiler to run only stages up to and +// including the specified target stage. All stages after the target will be skipped. +func (c *Compiler) WithOnlyStagesUpTo(target StageID) *Compiler { + allStages := AllStages() + i := slices.Index(allStages, target) + if i == -1 { + return c + } + return c.WithSkipStages(allStages[i+1:]...) +} + // WithMetrics will set a metrics.Metrics and be used for profiling // the Compiler instance. func (c *Compiler) WithMetrics(metrics metrics.Metrics) *Compiler { @@ -440,6 +584,7 @@ func (c *Compiler) WithDebug(sink io.Writer) *Compiler { } // WithBuiltins is deprecated. +// // Deprecated: Use WithCapabilities instead. func (c *Compiler) WithBuiltins(builtins map[string]*Builtin) *Compiler { c.customBuiltins = maps.Clone(builtins) @@ -447,6 +592,7 @@ func (c *Compiler) WithBuiltins(builtins map[string]*Builtin) *Compiler { } // WithUnsafeBuiltins is deprecated. +// // Deprecated: Use WithCapabilities instead. func (c *Compiler) WithUnsafeBuiltins(unsafeBuiltins map[string]struct{}) *Compiler { maps.Copy(c.unsafeBuiltinsMap, unsafeBuiltins) @@ -590,7 +736,7 @@ func (c *Compiler) GetRulesExact(ref Ref) (rules []*Rule) { } } - return extractRules(node.Values) + return node.Values } // GetRulesForVirtualDocument returns a slice of rules that produce the virtual @@ -617,11 +763,11 @@ func (c *Compiler) GetRulesForVirtualDocument(ref Ref) (rules []*Rule) { return nil } if len(node.Values) > 0 { - return extractRules(node.Values) + return node.Values } } - return extractRules(node.Values) + return node.Values } // GetRulesWithPrefix returns a slice of rules that share the prefix ref. @@ -652,7 +798,7 @@ func (c *Compiler) GetRulesWithPrefix(ref Ref) (rules []*Rule) { var acc func(node *TreeNode) acc = func(node *TreeNode) { - rules = append(rules, extractRules(node.Values)...) + rules = append(rules, node.Values...) for _, child := range node.Children { if child.Hide { continue @@ -666,14 +812,6 @@ func (c *Compiler) GetRulesWithPrefix(ref Ref) (rules []*Rule) { return rules } -func extractRules(s []any) []*Rule { - rules := make([]*Rule, len(s)) - for i := range s { - rules[i] = s[i].(*Rule) - } - return rules -} - // GetRules returns a slice of rules that are referred to by ref. // // E.g., given the following module: @@ -809,9 +947,9 @@ func (c *Compiler) GetRulesDynamicWithOpts(ref Ref, opts RulesOptions) []*Rule { } // Utility: add all rule values to the set. -func insertRules(set map[*Rule]struct{}, rules []any) { +func insertRules(set map[*Rule]struct{}, rules []*Rule) { for _, rule := range rules { - set[rule.(*Rule)] = struct{}{} + set[rule] = struct{}{} } } @@ -820,11 +958,10 @@ func insertRules(set map[*Rule]struct{}, rules []any) { // data.a.b.c.p, refs data.a.b.c.p.x and data.a.b.c would not return a // RuleIndex built for the rule. func (c *Compiler) RuleIndex(path Ref) RuleIndex { - r, ok := c.ruleIndices.Get(path) - if !ok { - return nil + if node := c.RuleTree.Find(path); node != nil { + return node.Index } - return r + return nil } // PassesTypeCheck determines whether the given body passes type checking @@ -837,7 +974,7 @@ func (c *Compiler) PassesTypeCheck(body Body) bool { // PassesTypeCheckRules determines whether the given rules passes type checking func (c *Compiler) PassesTypeCheckRules(rules []*Rule) Errors { - elems := []util.T{} + elems := make([]util.T, 0, len(rules)) for _, rule := range rules { elems = append(elems, rule) @@ -854,7 +991,7 @@ func (c *Compiler) PassesTypeCheckRules(rules []*Rule) Errors { tpe, err := loadSchema(schema, allowNet) if err != nil { - return Errors{NewError(TypeErr, nil, "%s", err.Error())} + return Errors{newErrorString(TypeErr, nil, err.Error())} } c.inputType = tpe } @@ -911,6 +1048,61 @@ func (c *Compiler) WithDefaultRegoVersion(regoVersion RegoVersion) *Compiler { return c } +// buildExecutionPlan creates the unified list of stages to execute, including +// both main stages and "after" stages, with filtering applied. +func (c *Compiler) buildExecutionPlan() *executionPlan { + plan := &executionPlan{ + stages: make([]plannedStage, 0, len(c.stages)*2), + } + + for _, s := range c.stages { + if _, skip := c.skipStages[s.name]; skip { + continue + } + + plan.stages = append(plan.stages, plannedStage{name: string(s.name), metricName: s.metricName, f: s.f}) + + for _, a := range c.after[string(s.name)] { + if _, skip := c.skipStages[StageID(a.Name)]; skip { + continue + } + + afterStage := a // Capture variables in closure properly + plan.stages = append(plan.stages, plannedStage{ + name: afterStage.Name, + metricName: afterStage.MetricName, + f: func() { + if err := afterStage.Stage(c); err != nil { + c.err(err) + } + }, + }) + } + } + + return plan +} + +// getOrBuildPlan ensures we have a valid execution plan. +func (c *Compiler) getOrBuildPlan() *executionPlan { + if c.plan == nil { + c.plan = c.buildExecutionPlan() + } + return c.plan +} + +// StagesToRun returns the list of stage IDs that will be executed during +// compilation, in execution order. This includes both main stages and any +// registered "after" stages. +func (c *Compiler) StagesToRun() []StageID { + plan := c.getOrBuildPlan() + result := make([]StageID, len(plan.stages)) + for i, s := range plan.stages { + result[i] = StageID(s.name) + } + return result +} + func (c *Compiler) counterAdd(name string, n uint64) { if c.metrics == nil { return @@ -924,11 +1116,15 @@ func (c *Compiler) buildRuleIndices() { if len(node.Values) == 0 { return false } - rules := extractRules(node.Values) + rules := node.Values hasNonGroundRef := false for _, r := range rules { hasNonGroundRef = !r.Head.Ref().IsGround() + if hasNonGroundRef { + break + } } + if hasNonGroundRef { // Collect children to ensure that all rules within the extent of a rule with a general ref // are found on the same index. E.g. the following rules should be indexed under data.a.b.c: @@ -939,7 +1135,7 @@ func (c *Compiler) buildRuleIndices() { // b.c.d2.e[x] := 3 { x := input.x } for _, child := range node.Children { child.DepthFirst(func(c *TreeNode) bool { - rules = append(rules, extractRules(c.Values)...) + rules = append(rules, c.Values...) return false }) } @@ -949,25 +1145,29 @@ func (c *Compiler) buildRuleIndices() { return isVirtual(c.RuleTree, ref.GroundPrefix()) }) if index.Build(rules) { - c.ruleIndices.Put(rules[0].Ref().GroundPrefix(), index) + node.Index = index } return hasNonGroundRef // currently, we don't allow those branches to go deeper }) - } func (c *Compiler) buildComprehensionIndices() { + vis := varVisitorPool.Get() + for _, name := range c.sorted { WalkRules(c.Modules[name], func(r *Rule) bool { - candidates := ReservedVars.Copy() + vis = vis.Clear() + vis.vars.Update(ReservedVars) if len(r.Head.Args) > 0 { - candidates.Update(r.Head.Args.Vars()) + vis.WalkArgs(r.Head.Args) } - n := buildComprehensionIndices(c.debug, c.GetArity, candidates, c.RewrittenVars, r.Body, c.comprehensionIndices) + n := buildComprehensionIndices(c.debug, c.GetArity, vis.vars, c.RewrittenVars, r.Body, c.comprehensionIndices) c.counterAdd(compileStageComprehensionIndexBuild, n) return false }) } + + varVisitorPool.Put(vis) } var futureKeywordsPrefix = Ref{FutureRootDocument, InternedTerm("keywords")} @@ -986,16 +1186,15 @@ func (c *Compiler) buildRequiredCapabilities() { 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): - if !c.moduleIsRegoV1(mod) { + if !c.moduleIsRegoV1(c.Modules[name]) { features[FeatureRegoV1Import] = struct{}{} } case path.HasPrefix(futureKeywordsPrefix): if len(path) == 2 { - if c.moduleIsRegoV1(mod) { + if c.moduleIsRegoV1(c.Modules[name]) { for kw := range futureKeywords { keywords[kw] = struct{}{} } @@ -1006,7 +1205,7 @@ func (c *Compiler) buildRequiredCapabilities() { } } else { kw := string(path[2].Value.(String)) - if c.moduleIsRegoV1(mod) { + if c.moduleIsRegoV1(c.Modules[name]) { for allowedKw := range futureKeywords { if kw == allowedKw { keywords[kw] = struct{}{} @@ -1049,11 +1248,15 @@ func (c *Compiler) buildRequiredCapabilities() { } } - c.Required.Features = util.KeysSorted(features) - for i, bi := range c.Required.Builtins { c.Required.Builtins[i] = bi.Minimal() + + if bi.Name == InternalTemplateString.Name { + features[FeatureTemplateStrings] = struct{}{} + } } + + c.Required.Features = util.KeysSorted(features) } // checkRecursion ensures that there are no recursive definitions, i.e., there are @@ -1065,7 +1268,7 @@ func (c *Compiler) checkRecursion() { c.RuleTree.DepthFirst(func(node *TreeNode) bool { for _, rule := range node.Values { - for node := rule.(*Rule); node != nil; node = node.Else { + for node := rule; node != nil; node = node.Else { c.checkSelfPath(node.Loc(), eq, node, node) } } @@ -1080,7 +1283,9 @@ func (c *Compiler) checkSelfPath(loc *Location, eq func(a, b util.T) bool, a, b for _, x := range p { n = append(n, astNodeToString(x)) } - c.err(NewError(RecursionErr, loc, "rule %v is recursive: %v", astNodeToString(a), strings.Join(n, " -> "))) + if !c.err(NewError(RecursionErr, loc, "rule %v is recursive: %v", astNodeToString(a), strings.Join(n, " -> "))) { + return + } } } @@ -1106,7 +1311,7 @@ func (c *Compiler) checkRuleConflicts() { defaultRules := make([]*Rule, 0) for _, rule := range node.Values { - r := rule.(*Rule) + r := rule ref := r.Ref() name = rw(ref.CopyNonGround()).String() // varRewriter operates in-place kinds[r.Head.RuleKind()] = struct{}{} @@ -1163,26 +1368,24 @@ func (c *Compiler) checkRuleConflicts() { switch { case conflicts != nil: - c.err(NewError(TypeErr, node.Values[0].(*Rule).Loc(), "rule %v conflicts with %v", name, conflicts)) + return !c.err(NewError(TypeErr, node.Values[0].Loc(), "rule %v conflicts with %v", name, conflicts)) 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)) + return !c.err(NewError(TypeErr, node.Values[0].Loc(), "conflicting rules %v found", name)) case len(defaultRules) > 1: + buf := append(append(append(make([]byte, 0, 64), "multiple default rules "...), name...), " found at "...) + buf, _ = defaultRules[0].Loc().AppendText(buf) - defaultRuleLocations := strings.Builder{} - defaultRuleLocations.WriteString(defaultRules[0].Loc().String()) - for i := 1; i < len(defaultRules); i++ { - defaultRuleLocations.WriteString(", ") - defaultRuleLocations.WriteString(defaultRules[i].Loc().String()) + for _, next := range defaultRules[1:] { + buf, _ = next.Loc().AppendText(append(buf, ", "...)) } - c.err(NewError( - TypeErr, - defaultRules[0].Module.Package.Loc(), - "multiple default rules %s found at %s", - name, defaultRuleLocations.String()), - ) + return !c.err(&Error{ + Code: TypeErr, + Location: defaultRules[0].Module.Package.Loc(), + Message: util.ByteSliceToString(buf), + }) } return false @@ -1212,8 +1415,9 @@ func (c *Compiler) checkRuleConflicts() { if childMod.Equal(mod) { 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(), "%s", msg)) + if !c.err(NewError(TypeErr, mod.Package.Loc(), "%v conflicts with rule %v defined at %v", childMod.Package, rule.Head.Ref(), rule.Loc())) { + return true + } } } } @@ -1225,9 +1429,7 @@ func (c *Compiler) checkRuleConflicts() { func (c *Compiler) checkUndefinedFuncs() { for _, name := range c.sorted { m := c.Modules[name] - for _, err := range checkUndefinedFuncs(c.TypeEnv, m, c.GetArity, c.RewrittenVars) { - c.err(err) - } + c.err(checkUndefinedFuncs(c.TypeEnv, m, c.GetArity, c.RewrittenVars)...) } } @@ -1283,25 +1485,29 @@ func arityMismatchError(env *TypeEnv, f Ref, expr *Expr, exp, act int) *Error { // positions of built-in expressions will be bound when evaluating the rule from left // to right, re-ordering as necessary. func (c *Compiler) checkSafetyRuleBodies() { + vis := varVisitorPool.Get() + for _, name := range c.sorted { m := c.Modules[name] WalkRules(m, func(r *Rule) bool { - safe := ReservedVars.Copy() + vis = vis.Clear() + // vis.vars == safe + vis.vars.Update(ReservedVars) if len(r.Head.Args) > 0 { - safe.Update(r.Head.Args.Vars()) + vis.WalkArgs(r.Head.Args) } - r.Body = c.checkBodySafety(safe, r.Body) + r.Body = c.checkBodySafety(vis.vars, r.Body) return false }) } + + varVisitorPool.Put(vis) } func (c *Compiler) checkBodySafety(safe VarSet, b Body) Body { reordered, unsafe := reorderBodyForSafety(c.builtins, c.GetArity, safe, b) if errs := safetyErrorSlice(unsafe, c.RewrittenVars); len(errs) > 0 { - for _, err := range errs { - c.err(err) - } + c.err(errs...) return b } return reordered @@ -1318,22 +1524,30 @@ var SafetyCheckVisitorParams = VarVisitorParams{ // checkSafetyRuleHeads ensures that variables appearing in the head of a // rule also appear in the body. func (c *Compiler) checkSafetyRuleHeads() { + vis := varVisitorPool.Get() + for _, name := range c.sorted { WalkRules(c.Modules[name], func(r *Rule) bool { - safe := r.Body.Vars(SafetyCheckVisitorParams) - if len(r.Head.Args) > 0 { - safe.Update(r.Head.Args.Vars()) - } if headMayHaveVars(r.Head) { + vis = vis.Clear().WithParams(SafetyCheckVisitorParams) + vis.WalkBody(r.Body) + + vis = vis.WithParams(VarVisitorParams{}) + if len(r.Head.Args) > 0 { + vis.WalkArgs(r.Head.Args) + } + vars := r.Head.Vars() - if vars.DiffCount(safe) > 0 { - unsafe := vars.Diff(safe) + if vars.DiffCount(vis.vars) > 0 { + unsafe := vars.Diff(vis.vars) for v := range unsafe { if w, ok := c.RewrittenVars[v]; ok { v = w } if !v.IsGenerated() { - c.err(NewError(UnsafeVarErr, r.Loc(), "var %v is unsafe", v)) + if !c.err(NewError(UnsafeVarErr, vars[v].Location, "var %v is unsafe", v)) { + return true + } } } } @@ -1341,6 +1555,8 @@ func (c *Compiler) checkSafetyRuleHeads() { return false }) } + + varVisitorPool.Put(vis) } func compileSchema(goSchema any, allowNet []string) (*gojsonschema.Schema, error) { @@ -1629,9 +1845,8 @@ func (c *Compiler) checkDeprecatedBuiltins() { } for _, name := range c.sorted { - mod := c.Modules[name] - if c.strict || mod.regoV1Compatible() { - errs := checkDeprecatedBuiltins(c.deprecatedBuiltinsMap, mod) + if c.strict || c.Modules[name].regoV1Compatible() { + errs := checkDeprecatedBuiltins(c.deprecatedBuiltinsMap, c.Modules[name]) for _, err := range errs { c.err(err) } @@ -1639,49 +1854,22 @@ func (c *Compiler) checkDeprecatedBuiltins() { } } -func (c *Compiler) runStage(metricName string, f func()) { - if c.metrics != nil { - c.metrics.Timer(metricName).Start() - defer c.metrics.Timer(metricName).Stop() - } - f() -} - -func (c *Compiler) runStageAfter(metricName string, s CompilerStage) *Error { - if c.metrics != nil { - c.metrics.Timer(metricName).Start() - defer c.metrics.Timer(metricName).Stop() - } - return s(c) -} - func (c *Compiler) compile() { + plan := c.getOrBuildPlan() - defer func() { - if r := recover(); r != nil && r != errLimitReached { - panic(r) - } - }() - - for _, s := range c.stages { - if c.evalMode == EvalModeIR { - switch s.name { - case "BuildRuleIndices", "BuildComprehensionIndices": - continue // skip these stages + if c.metrics != nil { + for _, s := range plan.stages { + c.metrics.Timer(s.metricName).Start() + s.f() + c.metrics.Timer(s.metricName).Stop() + if c.Failed() { + return } } - - if c.allowUndefinedFuncCalls && (s.name == "CheckUndefinedFuncs" || s.name == "CheckSafetyRuleBodies") { - continue - } - - c.runStage(s.metricName, s.f) - if c.Failed() { - return - } - for _, a := range c.after[s.name] { - if err := c.runStageAfter(a.MetricName, a.Stage); err != nil { - c.err(err) + } else { + for _, s := range plan.stages { + s.f() + if c.Failed() { return } } @@ -1739,7 +1927,9 @@ 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, "%s", err.Error())) + if !c.err(newErrorString(TypeErr, nil, err.Error())) { + return + } } else { c.inputType = tpe } @@ -1751,26 +1941,58 @@ func (c *Compiler) init() { WithInputType(c.inputType). Env(c.builtins) + // Configure default stage skips based on existing configuration + if c.evalMode == EvalModeIR { + c.WithSkipStages(StageBuildRuleIndices, StageBuildComprehensionIndices) + } + if c.allowUndefinedFuncCalls { + c.WithSkipStages(StageCheckUndefinedFuncs, StageCheckSafetyRuleBodies) + } + c.initialized = true } -func (c *Compiler) err(err *Error) { - if c.maxErrs > 0 && len(c.Errors) >= c.maxErrs { +func (c *Compiler) err(errs ...*Error) bool { // returns if we should continue + if len(errs) == 0 { + return true + } + + c.mu.Lock() + defer c.mu.Unlock() + + if c.maxErrs <= 0 { + c.Errors = append(c.Errors, errs...) + return true + } + + remaining := c.maxErrs - int(c.errCount) + if remaining <= 0 { + // The error limit has already been reached or exceeded. + // No more errors should be added. + return false + } + + numToTake := min(remaining, len(errs)) + + // The limit is reached if, after adding numToTake errors, the total count + // is equal to c.maxErrs. + isLimitReachedInThisCall := (int(c.errCount)+numToTake == c.maxErrs) + + c.errCount += uint32(numToTake) + c.Errors = append(c.Errors, errs[:numToTake]...) + if isLimitReachedInThisCall { c.Errors = append(c.Errors, errLimitReached) - panic(errLimitReached) } - c.Errors = append(c.Errors, err) + + return !isLimitReachedInThisCall // Return false if the limit was reached, true otherwise. } func (c *Compiler) getExports() *util.HasherMap[Ref, []Ref] { - rules := util.NewHasherMap[Ref, []Ref](RefEqual) for _, name := range c.sorted { - mod := c.Modules[name] - - for _, rule := range mod.Rules { - hashMapAdd(rules, mod.Package.Path, rule.Head.Ref().GroundPrefix()) + for _, rule := range c.Modules[name].Rules { + hashMapAdd(rules, c.Modules[name].Package.Path, rule.Head.Ref().GroundPrefix()) } } @@ -1814,32 +2036,27 @@ func (c *Compiler) checkImports() { c.capabilities.ContainsFeature(FeatureRegoV1) for _, name := range c.sorted { - mod := c.Modules[name] - - for _, imp := range mod.Imports { + for _, imp := range c.Modules[name].Imports { if !supportsRegoV1Import && RegoV1CompatibleRef.Equal(imp.Path.Value) { - c.err(NewError(CompileErr, imp.Loc(), "rego.v1 import is not supported")) + if !c.err(NewError(CompileErr, imp.Loc(), "rego.v1 import is not supported")) { + continue + } } } - if c.strict || c.moduleIsRegoV1Compatible(mod) { - modules = append(modules, mod) + if c.strict || c.moduleIsRegoV1Compatible(c.Modules[name]) { + modules = append(modules, c.Modules[name]) } } - errs := checkDuplicateImports(modules) - for _, err := range errs { - c.err(err) - } + c.err(checkDuplicateImports(modules)...) } func (c *Compiler) checkKeywordOverrides() { for _, name := range c.sorted { - mod := c.Modules[name] - if c.strict || c.moduleIsRegoV1Compatible(mod) { - errs := checkRootDocumentOverrides(mod) - for _, err := range errs { - c.err(err) + if c.strict || c.moduleIsRegoV1Compatible(c.Modules[name]) { + if !c.err(checkRootDocumentOverrides(c.Modules[name])...) { + continue } } } @@ -1891,12 +2108,10 @@ func (c *Compiler) moduleIsRegoV1Compatible(mod *Module) bool { // // The reference "c.d.e" would be resolved to "data.a.b.c.d.e". func (c *Compiler) resolveAllRefs() { - rules := c.getExports() for _, name := range c.sorted { mod := c.Modules[name] - var ruleExports []Ref if x, ok := rules.Get(mod.Package.Path); ok { ruleExports = x @@ -1907,7 +2122,7 @@ func (c *Compiler) resolveAllRefs() { WalkRules(mod, func(rule *Rule) bool { err := resolveRefsInRule(globals, rule) if err != nil { - c.err(NewError(CompileErr, rule.Location, "%s", err.Error())) + return c.err(newErrorString(CompileErr, rule.Location, err.Error())) } return false }) @@ -1921,7 +2136,9 @@ func (c *Compiler) resolveAllRefs() { for v, u := range globals { if v.Equal(imp.Name()) && !u.used { - c.err(NewError(CompileErr, imp.Location, "%s unused", imp.String())) + if !c.err(NewError(CompileErr, imp.Location, "%s unused", imp.String())) { + return + } } } } @@ -1932,7 +2149,7 @@ func (c *Compiler) resolveAllRefs() { parsed, err := c.moduleLoader(c.Modules) if err != nil { - c.err(NewError(CompileErr, nil, "%s", err.Error())) + c.err(newErrorString(CompileErr, nil, err.Error())) return } @@ -1968,15 +2185,13 @@ func (c *Compiler) initLocalVarGen() { func (c *Compiler) rewriteComprehensionTerms() { f := newEqualityFactory(c.localvargen) for _, name := range c.sorted { - mod := c.Modules[name] - _, _ = rewriteComprehensionTerms(f, mod) // ignore error + _, _ = rewriteComprehensionTerms(f, c.Modules[name]) // ignore error } } func (c *Compiler) rewriteExprTerms() { for _, name := range c.sorted { - mod := c.Modules[name] - WalkRules(mod, func(rule *Rule) bool { + WalkRules(c.Modules[name], func(rule *Rule) bool { rewriteExprTermsInHead(c.localvargen, rule) rule.Body = rewriteExprTermsInBody(c.localvargen, rule.Body) return false @@ -2019,7 +2234,9 @@ func (c *Compiler) rewriteRuleHeadRefs() { for i := 1; i < len(ref); i++ { if cannotSpeakGeneralRefs && (rule.Head.RuleKind() == MultiValue || i != len(ref)-1) { // last if _, ok := ref[i].Value.(String); !ok { - c.err(NewError(TypeErr, rule.Loc(), "rule heads with general refs (containing variables) are not supported: %v", rule.Head.Reference)) + if !c.err(NewError(TypeErr, rule.Loc(), "rule heads with general refs (containing variables) are not supported: %v", rule.Head.Reference)) { + return true + } continue } } @@ -2034,7 +2251,7 @@ func (c *Compiler) rewriteRuleHeadRefs() { rule.Head.Key = expr.Operand(0) } rule.Head.Reference[i] = expr.Operand(0) - rule.Body.Append(expr) + rule.Body = appendToBody(rule.Body, expr) } } @@ -2044,12 +2261,296 @@ func (c *Compiler) rewriteRuleHeadRefs() { } func (c *Compiler) checkVoidCalls() { + for _, name := range c.sorted { + c.err(checkVoidCalls(c.TypeEnv, c.Modules[name])...) + } +} + +func (c *Compiler) builtinLoc(ref Ref) *Builtin { + n := ref.String() + if b, ok := c.builtins[n]; ok { + return b + } + if b, ok := c.customBuiltins[n]; ok { + return b + } + return nil +} + +// isRefToKnownDefinedRule answers whether a rule (counting all incremental definitions) reference +// is known to evaluate to a value (not undefined). A rule reference is considered safe if it references +// a rule with no arguments (i.e. not a function) and: +// - The rule has a `default` value assigned +// - The rule is a multi-value rule — it generates a set that may be empty but not undefined +// - The rule is a "constant", meaning it has a single definition, a ground value and no body +func (c *Compiler) isRefToKnownDefinedRule(ref Ref) bool { + var matched *TreeNode + if len(ref) < 2 || !ref.HasPrefix(DefaultRootRef) { + return false + } + if matched = c.RuleTree.Find(ref); matched == nil || len(matched.Values) == 0 { + return false + } + first := matched.Values[0] + if len(first.Head.Args) > 0 { + return false + } + if first.Default || first.Head.RuleKind() == MultiValue { + return true + } + if len(matched.Values) == 1 { + return isConstantRule(first) + } + return slices.ContainsFunc(matched.Values[1:], func(r *Rule) bool { + return r.Default + }) +} + +// templateStringRewriter +type templateStringRewriter struct { + rule *Rule + gen *localVarGenerator + vis *VarVisitor + rewritten map[Var]Var + arity func(Ref) int + safeRuleRef func(Ref) bool + builtins builtinLocator + capsSupport bool +} + +func rewriterFromCompiler(c *Compiler) *templateStringRewriter { + return &templateStringRewriter{ + vis: NewVarVisitor(), + gen: c.localvargen, + builtins: c.builtinLoc, + arity: c.GetArity, + safeRuleRef: c.isRefToKnownDefinedRule, + rewritten: c.RewrittenVars, + capsSupport: c.capabilities.ContainsFeature(FeatureTemplateStrings) && + c.capabilities.ContainsBuiltin(InternalTemplateString.Name), + } +} + +func rewriterFromQueryCompiler(qc *queryCompiler, gen *localVarGenerator) *templateStringRewriter { + rw := rewriterFromCompiler(qc.compiler) + rw.gen = gen + return rw +} + +func (tsr *templateStringRewriter) Clear() *templateStringRewriter { + tsr.rule = nil + tsr.vis = tsr.vis.Clear() + return tsr +} + +// rewriteTemplateStrings rewrites template-string calls as they appear in bodies; e.g. rules, comprehensions, etc. +func (c *Compiler) rewriteTemplateStrings() { + tsr := rewriterFromCompiler(c) + modified := false for _, name := range c.sorted { mod := c.Modules[name] - for _, err := range checkVoidCalls(c.TypeEnv, mod) { - c.err(err) + WalkRules(mod, func(r *Rule) bool { + tsr = tsr.Clear() + safe := r.Head.Args.Vars() + + if len(r.Head.Args) > 0 { + tsr.vis = tsr.vis.WithParams(VarVisitorParams{SkipTemplateStrings: true}) + tsr.vis.WalkArgs(r.Head.Args) + } + + safe.Update(ReservedVars) + + modrec, safe, errs := rewriteTemplateStrings(tsr, safe, r.Body) + if modrec { + modified = true + } + c.err(errs...) + + if modrec, _, errs = rewriteTemplateStrings(tsr, safe, r.Head); modrec { + modified = true + } + c.err(errs...) + + return false + }) + } + if modified { + c.Required.addBuiltinSorted(InternalTemplateString) + } +} + +func rewriteTemplateStrings(tsr *templateStringRewriter, globals VarSet, x any) (bool, VarSet, Errors) { + var errs Errors + var modified bool + + // All output vars in the current body are safe, recursively + var safe VarSet + if b, ok := x.(Body); ok { + safe = outputVarsForBody(b, tsr.arity, globals, tsr.vis) + safe.Update(globals) + } else { + safe = globals.Copy() + } + + vis := &GenericVisitor{func(x any) bool { + var modrec bool + var errsrec Errors + switch x := x.(type) { + case *Term: + if _, ok := x.Value.(*TemplateString); ok { + modrec, errsrec = rewriteTemplateStringTerm(tsr, safe, x) + } + case *SetComprehension: + var s VarSet + modrec, s, errsrec = rewriteTemplateStrings(tsr, safe, x.Body) + if modrec { + modified = true + } + errs = append(errs, errsrec...) + + modrec, errsrec = rewriteTemplateStringTerm(tsr, s, x.Term) + case *ArrayComprehension: + var s VarSet + modrec, s, errsrec = rewriteTemplateStrings(tsr, safe, x.Body) + if modrec { + modified = true + } + errs = append(errs, errsrec...) + + modrec, errsrec = rewriteTemplateStringTerm(tsr, s, x.Term) + case *ObjectComprehension: + var s VarSet + modrec, s, errsrec = rewriteTemplateStrings(tsr, safe, x.Body) + if modrec { + modified = true + } + errs = append(errs, errsrec...) + + modrec, errsrec = rewriteTemplateStringTerm(tsr, s, x.Key) + if modrec { + modified = true + } + errs = append(errs, errsrec...) + + modrec, errsrec = rewriteTemplateStringTerm(tsr, s, x.Value) + case *Every: + modrec, errsrec = rewriteTemplateStringTerm(tsr, safe, x.Domain) + if modrec { + modified = true + } + errs = append(errs, errsrec...) + + s := safe.Copy() + s.Update(x.KeyValueVars()) + modrec, _, errsrec = rewriteTemplateStrings(tsr, s, x.Body) } + if modrec { + modified = true + } + errs = append(errs, errsrec...) + return false + }} + vis.Walk(x) + + return modified, safe, errs +} + +func rewriteTemplateStringTerm(tsr *templateStringRewriter, globals VarSet, t *Term) (bool, Errors) { + if ts, ok := t.Value.(*TemplateString); ok { + call, errs := rewriteTemplateString(tsr, globals, t.Loc(), ts) + if len(errs) != 0 { + return false, errs + } + t.Value = call + return true, nil } + return false, nil +} + +type builtinLocator func(Ref) *Builtin + +func rewriteTemplateString(tsr *templateStringRewriter, safe VarSet, loc *Location, ts *TemplateString) (Call, Errors) { + if !tsr.capsSupport { + return nil, Errors{NewError(CompileErr, loc, "template-strings are not supported")} + } + + var errs Errors + terms := make([]*Term, 0, len(ts.Parts)) + + if len(ts.Parts) == 0 { + terms = append(terms, NewTerm(InternedEmptyStringValue).SetLocation(loc)) + } else { + vis := ClearOrNewVarVisitor(nil).WithParams(SafetyCheckVisitorParams) + for _, p := range ts.Parts { + switch p := p.(type) { + case *Expr: + var t *Term + if p.IsCall() { + // Assert that the call isn't for a known relation built-in + if bi := tsr.builtins(p.Operator()); bi != nil && bi.Relation { + errs = append(errs, NewError( + CompileErr, + t.Loc(), + "illegal call to relation built-in '%s' that may cause multiple outputs", bi.Name, + )) + continue + } + t = CallTerm(p.Terms.([]*Term)...) + } else { + var ok bool + t, ok = p.Terms.(*Term) + if !ok { + errs = append(errs, NewError( + CompileErr, + p.Location, + "unexpected template-string expression type: %T", p.Terms)) + continue + } + } + + if ref, ok := t.Value.(Ref); ok && tsr.safeRuleRef(ref) { + terms = append(terms, SetTerm(t)) + continue + } + + if _, ok := t.Value.(Var); ok { + terms = append(terms, SetTerm(t)) + continue + } + + vis = ClearOrNewVarVisitor(vis).WithParams(SafetyCheckVisitorParams) + vis.Walk(t) + vars := vis.Vars() + if vars.DiffCount(safe) > 0 { + unsafe := vars.Diff(safe) + for _, v := range unsafe.Sorted() { + if w, ok := tsr.rewritten[v]; ok { + v = w + } + errs = append(errs, NewError(CompileErr, t.Loc(), "var %v is undeclared", v)) + } + } + + loc := t.Loc() + x := NewTerm(tsr.gen.Generate()).SetLocation(loc) + capture := Equality.Expr(x, t).SetLocation(loc) + capture.With = p.With + terms = append(terms, SetComprehensionTerm(x, NewBody(capture)).SetLocation(loc)) + case *Term: + terms = append(terms, p) + default: + errs = append(errs, NewError( + CompileErr, + loc, + "expected only term or expression parts in template-string, got %T", p, + )) + return nil, errs + } + } + } + + call := InternalTemplateString.Call(ArrayTerm(terms...)).Value.(Call) + return call, errs } func (c *Compiler) rewritePrintCalls() { @@ -2061,26 +2562,33 @@ func (c *Compiler) rewritePrintCalls() { } } } else { + vis := varVisitorPool.Get() + for _, name := range c.sorted { - mod := c.Modules[name] - WalkRules(mod, func(r *Rule) bool { - safe := r.Head.Args.Vars() - safe.Update(ReservedVars) - vis := func(b Body) bool { - modrec, errs := rewritePrintCalls(c.localvargen, c.GetArity, safe, b) + WalkRules(c.Modules[name], func(r *Rule) bool { + vis = vis.Clear() + vis.vars.Update(ReservedVars) + if len(r.Head.Args) > 0 { + vis.WalkArgs(r.Head.Args) + } + + bodyVis := func(b Body) bool { + modrec, errs := rewritePrintCalls(c.localvargen, c.GetArity, vis.vars, b) if modrec { modified = true } - for _, err := range errs { - c.err(err) + if !c.err(errs...) { + return true } return false } - WalkBodies(r.Head, vis) - WalkBodies(r.Body, vis) + WalkBodies(r.Head, bodyVis) + WalkBodies(r.Body, bodyVis) return false }) } + + varVisitorPool.Put(vis) } if modified { c.Required.addBuiltinSorted(Print) @@ -2124,7 +2632,7 @@ func rewritePrintCalls(gen *localVarGenerator, getArity func(Ref) int, globals V // those bodies only close over variables that are safe. for i := range body { if ContainsClosures(body[i]) { - safe := outputVarsForBody(body[:i], getArity, globals) + safe := outputVarsForBody(body[:i], getArity, globals, nil) safe.Update(globals) WalkClosures(body[i], func(x any) bool { var modrec bool @@ -2161,7 +2669,7 @@ func rewritePrintCalls(gen *localVarGenerator, getArity func(Ref) int, globals V modified = true var errs Errors - safe := outputVarsForBody(body[:i], getArity, globals) + safe := outputVarsForBody(body[:i], getArity, globals, nil) safe.Update(globals) // Fixes Issue #7647 by adding generated variables to the safe set @@ -2175,8 +2683,13 @@ func rewritePrintCalls(gen *localVarGenerator, getArity func(Ref) int, globals V args := body[i].Operands() var vis *VarVisitor + if len(args) > 0 { + vis = varVisitorPool.Get() + defer varVisitorPool.Put(vis) + } + for j := range args { - vis = vis.ClearOrNew().WithParams(SafetyCheckVisitorParams) + vis = vis.Clear().WithParams(SafetyCheckVisitorParams) vis.Walk(args[j]) vars := vis.Vars() if vars.DiffCount(safe) > 0 { @@ -2294,23 +2807,22 @@ func isPrintCall(x *Expr) bool { func (c *Compiler) rewriteRefsInHead() { f := newEqualityFactory(c.localvargen) for _, name := range c.sorted { - mod := c.Modules[name] - WalkRules(mod, func(rule *Rule) bool { + WalkRules(c.Modules[name], func(rule *Rule) bool { if requiresEval(rule.Head.Key) { expr := f.Generate(rule.Head.Key) rule.Head.Key = expr.Operand(0) - rule.Body.Append(expr) + rule.Body = appendToBody(rule.Body, expr) } if requiresEval(rule.Head.Value) { expr := f.Generate(rule.Head.Value) rule.Head.Value = expr.Operand(0) - rule.Body.Append(expr) + rule.Body = appendToBody(rule.Body, expr) } for i := 0; i < len(rule.Head.Args); i++ { if requiresEval(rule.Head.Args[i]) { expr := f.Generate(rule.Head.Args[i]) rule.Head.Args[i] = expr.Operand(0) - rule.Body.Append(expr) + rule.Body = appendToBody(rule.Body, expr) } } return false @@ -2365,8 +2877,7 @@ func (c *Compiler) rewriteTestRuleEqualities() { f := newEqualityFactory(c.localvargen) for _, name := range c.sorted { - mod := c.Modules[name] - WalkRules(mod, func(rule *Rule) bool { + WalkRules(c.Modules[name], func(rule *Rule) bool { if strings.HasPrefix(string(rule.Head.Name), "test_") { rule.Body = rewriteTestEqualities(f, rule.Body) } @@ -2379,8 +2890,7 @@ func (c *Compiler) parseMetadataBlocks() { // Only parse annotations if rego.metadata built-ins are called regoMetadataCalled := false for _, name := range c.sorted { - mod := c.Modules[name] - WalkExprs(mod, func(expr *Expr) bool { + WalkExprs(c.Modules[name], func(expr *Expr) bool { if isRegoMetadataChainCall(expr) || isRegoMetadataRuleCall(expr) { regoMetadataCalled = true } @@ -2396,13 +2906,11 @@ func (c *Compiler) parseMetadataBlocks() { // NOTE: Possible optimization: only parse annotations for modules on the path of rego.metadata-calling module for _, name := range c.sorted { mod := c.Modules[name] - if len(mod.Annotations) == 0 { var errs Errors mod.Annotations, errs = parseAnnotations(mod.Comments) - errs = append(errs, attachAnnotationsNodes(mod)...) - for _, err := range errs { - c.err(err) + if !c.err(errs...) || !c.err(attachAnnotationsNodes(mod)...) { + return } attachRuleAnnotations(mod) @@ -2418,11 +2926,8 @@ func (c *Compiler) rewriteRegoMetadataCalls() { _, ruleFuncAllowed := c.builtins[RegoMetadataRule.Name] for _, name := range c.sorted { - mod := c.Modules[name] - - WalkRules(mod, func(rule *Rule) bool { - var firstChainCall *Expr - var firstRuleCall *Expr + WalkRules(c.Modules[name], func(rule *Rule) bool { + var firstChainCall, firstRuleCall *Expr WalkExprs(rule, func(expr *Expr) bool { if chainFuncAllowed && firstChainCall == nil && isRegoMetadataChainCall(expr) { @@ -2445,14 +2950,13 @@ func (c *Compiler) rewriteRegoMetadataCalls() { chain, err := createMetadataChain(c.annotationSet.Chain(rule)) if err != nil { - c.err(err) - return false + return !c.err(err) } chain.Location = firstChainCall.Location eq := eqFactory.Generate(chain) metadataChainVar = eq.Operands()[0].Value.(Var) - body.Append(eq) + body = appendToBody(body, eq) } var metadataRuleVar Var @@ -2465,8 +2969,7 @@ func (c *Compiler) rewriteRegoMetadataCalls() { if a != nil { annotObj, err := a.toObject() if err != nil { - c.err(err) - return false + return !c.err(err) } metadataRuleTerm = NewTerm(*annotObj) } else { @@ -2477,19 +2980,14 @@ func (c *Compiler) rewriteRegoMetadataCalls() { metadataRuleTerm.Location = firstRuleCall.Location eq := eqFactory.Generate(metadataRuleTerm) metadataRuleVar = eq.Operands()[0].Value.(Var) - body.Append(eq) + body = appendToBody(body, eq) } - for _, expr := range rule.Body { - body.Append(expr) - } + body = appendToBody(body, rule.Body...) rule.Body = body vis := func(b Body) bool { - for _, err := range rewriteRegoMetadataCalls(&metadataChainVar, &metadataRuleVar, b, &c.RewrittenVars) { - c.err(err) - } - return false + return !c.err(rewriteRegoMetadataCalls(&metadataChainVar, &metadataRuleVar, b, &c.RewrittenVars)...) } WalkBodies(rule.Head, vis) WalkBodies(rule.Body, vis) @@ -2620,6 +3118,9 @@ func (c *Compiler) rewriteLocalVars() { // across else-branches. for rule := rule; rule != nil; rule = rule.Else { stack, errs := c.rewriteLocalVarsInRule(rule, unusedArgs, argsStack, gen) + if !c.err(errs...) { + return true + } if stack.assignment { assignment = true } @@ -2629,17 +3130,15 @@ func (c *Compiler) rewriteLocalVars() { delete(unusedArgs, arg) } } - - for _, err := range errs { - c.err(err) - } } if c.strict { // Report an error for each unused function argument for arg := range unusedArgs { if !arg.IsWildcard() { - c.err(NewError(CompileErr, rule.Head.Location, "unused argument %v. (hint: use _ (wildcard variable) instead)", arg)) + if !c.err(NewError(CompileErr, rule.Head.Location, "unused argument %v. (hint: use _ (wildcard variable) instead)", arg)) { + return true + } } } } @@ -2676,31 +3175,32 @@ func (c *Compiler) rewriteLocalVarsInRule(rule *Rule, unusedArgs VarSet, argsSta } NewGenericVisitor(nestedXform.Visit).Walk(rule.Head) - - for _, err := range nestedXform.errs { - c.err(err) - } + c.err(nestedXform.errs...) // NB(sr): This is a bit bogus -- Why not return them? // Rewrite assignments in body. - used = NewVarSet() + vis := NewVarVisitor() for _, t := range rule.Head.Ref()[1:] { - used.Update(t.Vars()) + if !IsScalar(t.Value) { + vis.Walk(t) + } } - if rule.Head.Key != nil { - used.Update(rule.Head.Key.Vars()) + if rule.Head.Key != nil && !IsScalar(rule.Head.Key.Value) { + vis.Walk(rule.Head.Key) } - if rule.Head.Value != nil { + if rule.Head.Value != nil && !IsScalar(rule.Head.Value.Value) { valueVars := rule.Head.Value.Vars() - used.Update(valueVars) + vis.vars.Update(valueVars) for arg := range unusedArgs { if valueVars.Contains(arg) { delete(unusedArgs, arg) } } } + + used = vis.Vars() } stack := argsStack.Copy() @@ -2775,19 +3275,21 @@ func (xform *rewriteNestedHeadVarLocalTransform) Visit(x any) bool { switch x := term.Value.(type) { case *object: + vis := NewGenericVisitor(xform.Visit) cpy, _ := x.Map(func(k, v *Term) (*Term, *Term, error) { kcpy := k.Copy() - NewGenericVisitor(xform.Visit).Walk(kcpy) + vis.Walk(kcpy) vcpy := v.Copy() - NewGenericVisitor(xform.Visit).Walk(vcpy) + vis.Walk(vcpy) return kcpy, vcpy, nil }) term.Value = cpy stop = true case *set: + vis := NewGenericVisitor(xform.Visit) cpy, _ := x.Map(func(v *Term) (*Term, error) { vcpy := v.Copy() - NewGenericVisitor(xform.Visit).Walk(vcpy) + vis.Walk(vcpy) return vcpy, nil }) term.Value = cpy @@ -2801,6 +3303,9 @@ func (xform *rewriteNestedHeadVarLocalTransform) Visit(x any) bool { case *ObjectComprehension: xform.errs = rewriteDeclaredVarsInObjectComprehension(xform.gen, stack, x, xform.errs, xform.strict) stop = true + case *TemplateString: + xform.errs = rewriteDeclaredVarsInTemplateString(xform.gen, stack, x, xform.errs, xform.strict) + stop = true } maps.Copy(xform.RewrittenVars, stack.rewritten) @@ -2825,7 +3330,6 @@ func (xform rewriteHeadVarLocalTransform) Transform(x any) (any, error) { } func (c *Compiler) rewriteLocalArgVars(gen *localVarGenerator, stack *localDeclaredVars, rule *Rule) { - vis := &ruleArgLocalRewriter{ stack: stack, gen: gen, @@ -2835,9 +3339,7 @@ func (c *Compiler) rewriteLocalArgVars(gen *localVarGenerator, stack *localDecla Walk(vis, rule.Head.Args[i]) } - for i := range vis.errs { - c.err(vis.errs[i]) - } + c.err(vis.errs...) } type ruleArgLocalRewriter struct { @@ -2870,13 +3372,13 @@ func (vis *ruleArgLocalRewriter) Visit(x any) Visitor { Walk(vis, vcpy) return k, vcpy, nil }); err != nil { - vis.errs = append(vis.errs, NewError(CompileErr, t.Location, "%s", err.Error())) + vis.errs = append(vis.errs, newErrorString(CompileErr, t.Location, err.Error())) } else { t.Value = cpy } return nil - case Null, Boolean, Number, String, *ArrayComprehension, *SetComprehension, *ObjectComprehension, Set: - // Scalars are no-ops. Comprehensions are handled above. Sets must not + case Null, Boolean, Number, String, *ArrayComprehension, *SetComprehension, *ObjectComprehension, Set, *TemplateString: + // Scalars are no-ops. Comprehensions and template-strings are handled above. Sets must not // contain variables. return nil case Call: @@ -2965,6 +3467,10 @@ func (qc *queryCompiler) WithStageAfter(after string, stage QueryCompilerStageDe return qc } +func (qc *queryCompiler) WithStageAfterID(after StageID, stage QueryCompilerStageDefinition) QueryCompiler { + return qc.WithStageAfter(string(after), stage) +} + func (qc *queryCompiler) WithUnsafeBuiltins(unsafe map[string]struct{}) QueryCompiler { qc.unsafeBuiltins = unsafe return qc @@ -3000,7 +3506,7 @@ func (qc *queryCompiler) runStageAfter(metricName string, query Body, s QueryCom } type queryStage = struct { - name string + name StageID metricName string f func(*QueryContext, Body) (Body, error) } @@ -3013,20 +3519,21 @@ func (qc *queryCompiler) Compile(query Body) (Body, error) { query = query.Copy() stages := []queryStage{ - {"CheckKeywordOverrides", "query_compile_stage_check_keyword_overrides", qc.checkKeywordOverrides}, - {"ResolveRefs", "query_compile_stage_resolve_refs", qc.resolveRefs}, - {"RewriteLocalVars", "query_compile_stage_rewrite_local_vars", qc.rewriteLocalVars}, - {"CheckVoidCalls", "query_compile_stage_check_void_calls", qc.checkVoidCalls}, - {"RewritePrintCalls", "query_compile_stage_rewrite_print_calls", qc.rewritePrintCalls}, - {"RewriteExprTerms", "query_compile_stage_rewrite_expr_terms", qc.rewriteExprTerms}, - {"RewriteComprehensionTerms", "query_compile_stage_rewrite_comprehension_terms", qc.rewriteComprehensionTerms}, - {"RewriteWithValues", "query_compile_stage_rewrite_with_values", qc.rewriteWithModifiers}, - {"CheckUndefinedFuncs", "query_compile_stage_check_undefined_funcs", qc.checkUndefinedFuncs}, - {"CheckSafety", "query_compile_stage_check_safety", qc.checkSafety}, - {"RewriteDynamicTerms", "query_compile_stage_rewrite_dynamic_terms", qc.rewriteDynamicTerms}, - {"CheckTypes", "query_compile_stage_check_types", qc.checkTypes}, - {"CheckUnsafeBuiltins", "query_compile_stage_check_unsafe_builtins", qc.checkUnsafeBuiltins}, - {"CheckDeprecatedBuiltins", "query_compile_stage_check_deprecated_builtins", qc.checkDeprecatedBuiltins}, + {StageCheckKeywordOverrides, "query_compile_stage_check_keyword_overrides", qc.checkKeywordOverrides}, + {StageResolveRefs, "query_compile_stage_resolve_refs", qc.resolveRefs}, + {StageRewriteLocalVars, "query_compile_stage_rewrite_local_vars", qc.rewriteLocalVars}, + {StageRewriteTemplateStrings, "compile_stage_rewrite_template_strings", qc.rewriteTemplateStrings}, + {StageCheckVoidCalls, "query_compile_stage_check_void_calls", qc.checkVoidCalls}, + {StageRewritePrintCalls, "query_compile_stage_rewrite_print_calls", qc.rewritePrintCalls}, + {StageRewriteExprTerms, "query_compile_stage_rewrite_expr_terms", qc.rewriteExprTerms}, + {StageRewriteComprehensionTerms, "query_compile_stage_rewrite_comprehension_terms", qc.rewriteComprehensionTerms}, + {StageRewriteWithValues, "query_compile_stage_rewrite_with_values", qc.rewriteWithModifiers}, + {StageCheckUndefinedFuncs, "query_compile_stage_check_undefined_funcs", qc.checkUndefinedFuncs}, + {StageCheckSafety, "query_compile_stage_check_safety", qc.checkSafety}, + {StageRewriteDynamicTerms, "query_compile_stage_rewrite_dynamic_terms", qc.rewriteDynamicTerms}, + {StageCheckTypes, "query_compile_stage_check_types", qc.checkTypes}, + {StageCheckUnsafeBuiltins, "query_compile_stage_check_unsafe_builtins", qc.checkUnsafeBuiltins}, + {StageCheckDeprecatedBuiltins, "query_compile_stage_check_deprecated_builtins", qc.checkDeprecatedBuiltins}, } if qc.compiler.evalMode == EvalModeTopdown { stages = append(stages, queryStage{"BuildComprehensionIndex", "query_compile_stage_build_comprehension_index", qc.buildComprehensionIndices}) @@ -3040,7 +3547,7 @@ func (qc *queryCompiler) Compile(query Body) (Body, error) { if err != nil { return nil, qc.applyErrorLimit(err) } - for _, s := range qc.after[s.name] { + for _, s := range qc.after[string(s.name)] { query, err = qc.runStageAfter(s.MetricName, query, s.Stage) if err != nil { return nil, qc.applyErrorLimit(err) @@ -3139,6 +3646,15 @@ func (qc *queryCompiler) rewriteLocalVars(_ *QueryContext, body Body) (Body, err return body, nil } +func (qc *queryCompiler) rewriteTemplateStrings(_ *QueryContext, body Body) (Body, error) { + gen := newLocalVarGenerator("q", body) + tsr := rewriterFromQueryCompiler(qc, gen) + if _, _, errs := rewriteTemplateStrings(tsr, ReservedVars, body); len(errs) > 0 { + return nil, errs + } + return body, nil +} + func (qc *queryCompiler) rewritePrintCalls(_ *QueryContext, body Body) (Body, error) { if !qc.enablePrintStatements { _, cpy := erasePrintCallsInBody(body) @@ -3249,6 +3765,10 @@ func (ci *ComprehensionIndex) String() string { func buildComprehensionIndices(dbg debug.Debug, arity func(Ref) int, candidates VarSet, rwVars map[Var]Var, node Body, result map[*Term]*ComprehensionIndex) uint64 { var n uint64 cpy := candidates.Copy() + vis := varVisitorPool.Get() + + defer varVisitorPool.Put(vis) + WalkBodies(node, func(b Body) bool { for _, expr := range b { index := getComprehensionIndex(dbg, arity, cpy, rwVars, expr) @@ -3258,7 +3778,9 @@ func buildComprehensionIndices(dbg debug.Debug, arity func(Ref) int, candidates } // Any variables appearing in the expressions leading up to the comprehension // are fair-game to be used as index keys. - cpy.Update(expr.Vars(VarVisitorParams{SkipClosures: true, SkipRefCallHead: true})) + vis = vis.Clear().WithParams(VarVisitorParams{SkipClosures: true, SkipRefCallHead: true}) + vis.Walk(expr) + cpy.Update(vis.Vars()) } return false }) @@ -3266,7 +3788,6 @@ func buildComprehensionIndices(dbg debug.Debug, arity func(Ref) int, candidates } func getComprehensionIndex(dbg debug.Debug, arity func(Ref) int, candidates VarSet, rwVars map[Var]Var, expr *Expr) *ComprehensionIndex { - // Ignore everything except = expressions. Extract // the comprehension term from the expression. if !expr.IsEquality() || expr.Negated || len(expr.With) > 0 { @@ -3319,7 +3840,7 @@ func getComprehensionIndex(dbg debug.Debug, arity func(Ref) int, candidates VarS body = x.Body } - outputs := outputVarsForBody(body, arity, ReservedVars) + outputs := outputVarsForBody(body, arity, ReservedVars, nil) unsafe := body.Vars(SafetyCheckVisitorParams).Diff(outputs).Diff(ReservedVars) if len(unsafe) > 0 { @@ -3358,11 +3879,9 @@ func getComprehensionIndex(dbg debug.Debug, arity func(Ref) int, candidates VarS } result := make([]*Term, 0, len(indexVars)) - for v := range indexVars { result = append(result, NewTerm(v)) } - slices.SortFunc(result, TermValueCompare) debugRes := make([]*Term, len(result)) @@ -3453,9 +3972,11 @@ func (vis *comprehensionIndexNestedCandidateVisitor) visit(x any) bool { } if v, ok := x.(Value); ok && IsComprehension(v) { - varVis := NewVarVisitor().WithParams(VarVisitorParams{SkipRefHead: true}) + varVis := varVisitorPool.Get().WithParams(VarVisitorParams{SkipRefHead: true}) varVis.Walk(v) vis.found = len(varVis.Vars().Intersect(vis.candidates)) > 0 + varVisitorPool.Put(varVis) + return true } @@ -3494,7 +4015,7 @@ func NewModuleTree(mods map[string]*Module) *ModuleTreeNode { c, ok := node.Children[x.Value] if !ok { var hide bool - if i == 1 && x.Value.Compare(SystemDocumentKey) == 0 { + if i == 1 && SystemDocumentKey.Equal(x.Value) { hide = true } c = &ModuleTreeNode{ @@ -3564,10 +4085,11 @@ func (n *ModuleTreeNode) DepthFirst(f func(*ModuleTreeNode) bool) { // rule path. type TreeNode struct { Key Value - Values []any + Values []*Rule Children map[Value]*TreeNode Sorted []Value Hide bool + Index RuleIndex } func (n *TreeNode) String() string { @@ -3600,7 +4122,7 @@ func NewRuleTree(mtree *ModuleTreeNode) *TreeNode { } root.DepthFirst(func(x *TreeNode) bool { - x.sort() + slices.SortFunc(x.Sorted, Value.Compare) return false }) @@ -3622,12 +4144,11 @@ func (n *TreeNode) add(path Ref, rule *Rule) { } // Size returns the number of rules in the tree. -func (n *TreeNode) Size() int { - s := len(n.Values) +func (n *TreeNode) Size() (s int) { for _, c := range n.Children { s += c.Size() } - return s + return s + len(n.Values) } // Child returns n's child with key k. @@ -3681,10 +4202,6 @@ func (n *TreeNode) DepthFirst(f func(*TreeNode) bool) { } } -func (n *TreeNode) sort() { - slices.SortFunc(n.Sorted, Value.Compare) -} - func treeNodeFromRef(ref Ref, rule *Rule) *TreeNode { depth := len(ref) - 1 key := ref[depth].Value @@ -3693,7 +4210,7 @@ func treeNodeFromRef(ref Ref, rule *Rule) *TreeNode { Children: nil, } if rule != nil { - node.Values = []any{rule} + node.Values = []*Rule{rule} } for i := len(ref) - 2; i >= 0; i-- { @@ -3713,15 +4230,14 @@ func (n *TreeNode) flattenChildren() []Ref { for _, sub := range n.Children { // we only want the children, so don't use n.DepthFirst() right away sub.DepthFirst(func(x *TreeNode) bool { for _, r := range x.Values { - rule := r.(*Rule) + rule := r ret.AddPrefix(rule.Ref()) } return false }) } - slices.SortFunc(ret.s, RefCompare) - return ret.s + return util.SortedFunc(ret.s, RefCompare) } // Graph represents the graph of dependencies between rules. @@ -3891,11 +4407,7 @@ func NewGraphTraversal(graph *Graph) *GraphTraversal { // Edges lists all dependency connections for a given node func (g *GraphTraversal) Edges(x util.T) []util.T { - r := []util.T{} - for v := range g.graph.Dependencies(x) { - r = append(r, v) - } - return r + return util.Keys(g.graph.Dependencies(x)) } // Visited returns whether a node has been visited, setting a node to visited if not @@ -3919,9 +4431,9 @@ type unsafeVars map[*Expr]VarSet func (vs unsafeVars) Add(e *Expr, v Var) { if u, ok := vs[e]; ok { - u[v] = struct{}{} + u[v] = struct{ *Location }{} } else { - vs[e] = VarSet{v: struct{}{}} + vs[e] = VarSet{v: struct{ *Location }{}} } } @@ -3939,7 +4451,6 @@ func (vs unsafeVars) Update(o unsafeVars) { } func (vs unsafeVars) Vars() (result []unsafeVarLoc) { - locs := map[Var]*Location{} // If var appears in multiple sets then pick first by location. @@ -3952,17 +4463,12 @@ func (vs unsafeVars) Vars() (result []unsafeVarLoc) { } for v, loc := range locs { - result = append(result, unsafeVarLoc{ - Var: v, - Loc: loc, - }) + result = append(result, unsafeVarLoc{Var: v, Loc: loc}) } - slices.SortFunc(result, func(a, b unsafeVarLoc) int { + return util.SortedFunc(result, func(a, b unsafeVarLoc) int { return a.Loc.Compare(b.Loc) }) - - return result } func (vs unsafeVars) Slice() (result []unsafePair) { @@ -3996,7 +4502,8 @@ func reorderBodyForSafety(builtins map[string]*Builtin, arity func(Ref) int, glo unsafe := make(unsafeVars, len(bodyVars)-len(safe)) for _, e := range body { - vis.Clear().WithParams(SafetyCheckVisitorParams).Walk(e) + vis = vis.Clear().WithParams(SafetyCheckVisitorParams) + vis.Walk(e) for v := range vis.Vars() { if _, ok := safe[v]; !ok { unsafe.Add(e, v) @@ -4005,7 +4512,8 @@ func reorderBodyForSafety(builtins map[string]*Builtin, arity func(Ref) int, glo } reordered := make(Body, 0, len(body)) - output := VarSet{} + output := NewVarSet() + unsVis := varVisitorPool.Get() for { n := len(reordered) @@ -4015,13 +4523,15 @@ func reorderBodyForSafety(builtins map[string]*Builtin, arity func(Ref) int, glo continue } - ovs := outputVarsForExpr(e, arity, safe, output) + ovs := outputVarsForExpr(e, arity, safe, output, vis) // check closures: is this expression closing over variables that // haven't been made safe by what's already included in `reordered`? - vs := unsafeVarsInClosures(e) - cv := vs.Intersect(bodyVars).Diff(globals) - ob := outputVarsForBody(reordered, arity, safe) + unsafeVarsInClosures(e, unsVis) + cv := unsVis.Vars().Intersect(bodyVars).Diff(globals) + unsVis.Clear() + + ob := outputVarsForBody(reordered, arity, safe, vis) if cv.DiffCount(ob) > 0 { uv := cv.Diff(ob) @@ -4049,26 +4559,25 @@ func reorderBodyForSafety(builtins map[string]*Builtin, arity func(Ref) int, glo } } + varVisitorPool.Put(unsVis) + // Recursively visit closures and perform the safety checks on them. // Update the globals at each expression to include the variables that could // be closed over. g := globals.Copy() - xform := &bodySafetyTransformer{ - builtins: builtins, - arity: arity, - } - gvis := &GenericVisitor{} + xform := newBodySafetyTransformer(builtins, arity) + xform.gv = NewGenericVisitor(xform.Visit) + for i, e := range reordered { if i > 0 { + vis = vis.Clear().WithParams(SafetyCheckVisitorParams) vis.Walk(reordered[i-1]) g.Update(vis.Vars()) - vis.Clear().WithParams(SafetyCheckVisitorParams) } xform.current = e xform.globals = g xform.unsafe = unsafe - gvis.f = xform.Visit - gvis.Walk(e) + xform.gv.Walk(e) } return reordered, unsafe @@ -4080,18 +4589,29 @@ type bodySafetyTransformer struct { current *Expr globals VarSet unsafe unsafeVars + gv *GenericVisitor +} + +func newBodySafetyTransformer(builtins map[string]*Builtin, arity func(Ref) int) *bodySafetyTransformer { + return &bodySafetyTransformer{ + builtins: builtins, + arity: arity, + } } func (xform *bodySafetyTransformer) Visit(x any) bool { + if xform.gv == nil { + xform.gv = NewGenericVisitor(xform.Visit) + } switch term := x.(type) { case *Term: switch x := term.Value.(type) { case *object: cpy, _ := x.Map(func(k, v *Term) (*Term, *Term, error) { kcpy := k.Copy() - NewGenericVisitor(xform.Visit).Walk(kcpy) + xform.gv.Walk(kcpy) vcpy := v.Copy() - NewGenericVisitor(xform.Visit).Walk(vcpy) + xform.gv.Walk(vcpy) return kcpy, vcpy, nil }) term.Value = cpy @@ -4099,7 +4619,7 @@ func (xform *bodySafetyTransformer) Visit(x any) bool { case *set: cpy, _ := x.Map(func(v *Term) (*Term, error) { vcpy := v.Copy() - NewGenericVisitor(xform.Visit).Walk(vcpy) + xform.gv.Walk(vcpy) return vcpy, nil }) term.Value = cpy @@ -4160,10 +4680,8 @@ func (xform *bodySafetyTransformer) reorderSetComprehensionSafety(sc *SetCompreh // unsafeVarsInClosures collects vars that are contained in closures within // this expression. -func unsafeVarsInClosures(e *Expr) VarSet { - vs := VarSet{} +func unsafeVarsInClosures(e *Expr, vis *VarVisitor) { WalkClosures(e, func(x any) bool { - vis := &VarVisitor{vars: vs} if ev, ok := x.(*Every); ok { vis.WalkBody(ev.Body) return true @@ -4171,21 +4689,23 @@ func unsafeVarsInClosures(e *Expr) VarSet { vis.Walk(x) return true }) - return vs } // OutputVarsFromBody returns all variables which are the "output" for // the given body. For safety checks this means that they would be // made safe by the body. func OutputVarsFromBody(c *Compiler, body Body, safe VarSet) VarSet { - return outputVarsForBody(body, c.GetArity, safe) + return outputVarsForBody(body, c.GetArity, safe, nil) } -func outputVarsForBody(body Body, arity func(Ref) int, safe VarSet) VarSet { +func outputVarsForBody(body Body, arity func(Ref) int, safe VarSet, vis *VarVisitor) VarSet { o := safe.Copy() output := VarSet{} + + vis = ClearOrNewVarVisitor(vis) + for _, e := range body { - o.Update(outputVarsForExpr(e, arity, o, output)) + o.Update(outputVarsForExpr(e, arity, o, output, vis)) } return o.Diff(safe) } @@ -4194,20 +4714,22 @@ func outputVarsForBody(body Body, arity func(Ref) int, safe VarSet) VarSet { // the given expression. For safety checks this means that they would be // made safe by the expr. func OutputVarsFromExpr(c *Compiler, expr *Expr, safe VarSet) VarSet { - return outputVarsForExpr(expr, c.GetArity, safe, VarSet{}) + return outputVarsForExpr(expr, c.GetArity, safe, VarSet{}, nil) } -func outputVarsForExpr(expr *Expr, arity func(Ref) int, safe VarSet, output VarSet) VarSet { +func outputVarsForExpr(expr *Expr, arity func(Ref) int, safe VarSet, output VarSet, vis *VarVisitor) VarSet { // Negated expressions must be safe. if expr.Negated { return VarSet{} } - var vis *VarVisitor + if len(expr.With) > 0 { + vis = ClearOrNewVarVisitor(vis).WithParams(SafetyCheckVisitorParams) + } // With modifier inputs must be safe. for _, with := range expr.With { - vis = vis.ClearOrNew().WithParams(SafetyCheckVisitorParams) + vis = vis.Clear().WithParams(SafetyCheckVisitorParams) vis.Walk(with) if vis.Vars().DiffCount(safe) > 0 { return VarSet{} @@ -4215,8 +4737,11 @@ func outputVarsForExpr(expr *Expr, arity func(Ref) int, safe VarSet, output VarS } switch terms := expr.Terms.(type) { + case *TemplateString: + // Template-expressions have no output vars + return VarSet{} case *Term: - return outputVarsForTerms(expr, safe) + return outputVarsForTerms(expr, safe, nil) case []*Term: if expr.IsEquality() { return outputVarsForExprEq(expr, safe, output) @@ -4234,7 +4759,7 @@ func outputVarsForExpr(expr *Expr, arity func(Ref) int, safe VarSet, output VarS return outputVarsForExprCall(expr, ar, safe, terms, vis, output) case *Every: - return outputVarsForTerms(terms.Domain, safe) + return outputVarsForTerms(terms.Domain, safe, output) default: panic("illegal expression") } @@ -4245,7 +4770,7 @@ func outputVarsForExprEq(expr *Expr, safe VarSet, output VarSet) VarSet { return safe } - output.Update(outputVarsForTerms(expr, safe)) + output = outputVarsForTerms(expr, safe, output) output.Update(safe) output.Update(Unify(output, expr.Operand(0), expr.Operand(1))) @@ -4259,7 +4784,7 @@ func outputVarsForExprEq(expr *Expr, safe VarSet, output VarSet) VarSet { func outputVarsForExprCall(expr *Expr, arity int, safe VarSet, terms []*Term, vis *VarVisitor, output VarSet) VarSet { clear(output) - output.Update(outputVarsForTerms(expr, safe)) + output = outputVarsForTerms(expr, safe, output) numInputTerms := arity + 1 if numInputTerms >= len(terms) { @@ -4272,7 +4797,8 @@ func outputVarsForExprCall(expr *Expr, arity int, safe VarSet, terms []*Term, vi SkipObjectKeys: true, SkipRefHead: true, } - vis = vis.ClearOrNew().WithParams(params) + + vis = ClearOrNewVarVisitor(vis).WithParams(params) vis.WalkArgs(Args(terms[:numInputTerms])) unsafe := vis.Vars().Diff(output).DiffCount(safe) @@ -4286,11 +4812,13 @@ func outputVarsForExprCall(expr *Expr, arity int, safe VarSet, terms []*Term, vi return output } -func outputVarsForTerms(expr any, safe VarSet) VarSet { - output := VarSet{} +func outputVarsForTerms(expr any, safe, output VarSet) VarSet { + if output == nil { + output = VarSet{} + } WalkTerms(expr, func(x *Term) bool { switch r := x.Value.(type) { - case *SetComprehension, *ArrayComprehension, *ObjectComprehension: + case *SetComprehension, *ArrayComprehension, *ObjectComprehension, *TemplateString: return true case Ref: if !isRefSafe(r, safe) { @@ -4339,22 +4867,26 @@ func newLocalVarGeneratorForModuleSet(sorted []string, modules map[string]*Modul for _, key := range sorted { vis.Walk(modules[key]) } - return &localVarGenerator{exclude: vis.vars, next: 0} + return &localVarGenerator{exclude: vis.vars, suffix: LocalVarPrefix} } func newLocalVarGenerator(suffix string, node any) *localVarGenerator { vis := NewVarVisitor() vis.Walk(node) - return &localVarGenerator{exclude: vis.vars, suffix: suffix, next: 0} + return &localVarGenerator{exclude: vis.vars, suffix: LocalVarPrefix + suffix} } func (l *localVarGenerator) Generate() Var { + buf := make([]byte, 0, len(l.suffix)+util.NumDigitsInt(l.next)+2) for { - result := Var(LocalVarPrefix + l.suffix + strconv.Itoa(l.next) + "__") + buf = append(util.AppendInt(append(buf, l.suffix...), l.next), "__"...) + result := Var(util.ByteSliceToString(buf)) l.next++ if !l.exclude.Contains(result) { return result } + + buf = buf[:0] } } @@ -4385,8 +4917,7 @@ func requiresEval(x *Term) bool { } func resolveRef(globals map[Var]*usedRef, ignore *declaredVarStack, ref Ref) Ref { - - r := Ref{} + r := make(Ref, 0, len(ref)) for i, x := range ref { switch v := x.Value.(type) { case Var: @@ -4604,6 +5135,21 @@ func resolveRefsInTerm(globals map[Var]*usedRef, ignore *declaredVarStack, term cpy.Value = sc ignore.Pop() return &cpy + case *TemplateString: + ts := &TemplateString{} + if len(v.Parts) > 0 { + ts.Parts = make([]Node, 0, len(v.Parts)) + } + for _, p := range v.Parts { + if expr, ok := p.(*Expr); ok { + ts.Parts = append(ts.Parts, resolveRefsInExpr(globals, ignore, expr)) + } else { + ts.Parts = append(ts.Parts, p) + } + } + cpy := *term + cpy.Value = ts + return &cpy default: return term } @@ -4707,26 +5253,26 @@ func rewriteComprehensionTerms(f *equalityFactory, node any) (any, error) { if requiresEval(x.Term) { expr := f.Generate(x.Term) x.Term = expr.Operand(0) - x.Body.Append(expr) + x.Body = appendToBody(x.Body, expr) } return x, nil case *SetComprehension: if requiresEval(x.Term) { expr := f.Generate(x.Term) x.Term = expr.Operand(0) - x.Body.Append(expr) + x.Body = appendToBody(x.Body, expr) } return x, nil case *ObjectComprehension: if requiresEval(x.Key) { expr := f.Generate(x.Key) x.Key = expr.Operand(0) - x.Body.Append(expr) + x.Body = appendToBody(x.Body, expr) } if requiresEval(x.Value) { expr := f.Generate(x.Value) x.Value = expr.Operand(0) - x.Body.Append(expr) + x.Body = appendToBody(x.Body, expr) } return x, nil } @@ -4781,7 +5327,7 @@ func rewriteTestEqualities(f *equalityFactory, body Body) Body { every.Body = rewriteTestEqualities(f, every.Body) } } - result = appendExpr(result, expr) + result = appendToBody(result, expr) } return result } @@ -4826,19 +5372,15 @@ func rewriteDynamics(f *equalityFactory, body Body) Body { return result } -func appendExpr(body Body, expr *Expr) Body { - body.Append(expr) - return body -} - func rewriteDynamicsEqExpr(f *equalityFactory, expr *Expr, result Body) Body { if !validEqAssignArgCount(expr) { - return appendExpr(result, expr) + return appendToBody(result, expr) } terms := expr.Terms.([]*Term) result, terms[1] = rewriteDynamicsInTerm(expr, f, terms[1], result) result, terms[2] = rewriteDynamicsInTerm(expr, f, terms[2], result) - return appendExpr(result, expr) + result.Append(expr) + return result } func rewriteDynamicsCallExpr(f *equalityFactory, expr *Expr, result Body) Body { @@ -4846,20 +5388,23 @@ func rewriteDynamicsCallExpr(f *equalityFactory, expr *Expr, result Body) Body { for i := 1; i < len(terms); i++ { result, terms[i] = rewriteDynamicsOne(expr, f, terms[i], result) } - return appendExpr(result, expr) + result.Append(expr) + return result } func rewriteDynamicsEveryExpr(f *equalityFactory, expr *Expr, result Body) Body { ev := expr.Terms.(*Every) result, ev.Domain = rewriteDynamicsOne(expr, f, ev.Domain, result) ev.Body = rewriteDynamics(f, ev.Body) - return appendExpr(result, expr) + result.Append(expr) + return result } func rewriteDynamicsTermExpr(f *equalityFactory, expr *Expr, result Body) Body { term := expr.Terms.(*Term) result, expr.Terms = rewriteDynamicsInTerm(expr, f, term, result) - return appendExpr(result, expr) + result.Append(expr) + return result } func rewriteDynamicsInTerm(original *Expr, f *equalityFactory, term *Term, result Body) (Body, *Term) { @@ -4946,27 +5491,69 @@ func rewriteDynamicsComprehensionBody(original *Expr, f *equalityFactory, body B func rewriteExprTermsInHead(gen *localVarGenerator, rule *Rule) { for i := range rule.Head.Args { support, output := expandExprTerm(gen, rule.Head.Args[i]) - for j := range support { - rule.Body.Append(support[j]) - } + rule.Body = appendToBody(rule.Body, support...) rule.Head.Args[i] = output } if rule.Head.Key != nil { support, output := expandExprTerm(gen, rule.Head.Key) - for i := range support { - rule.Body.Append(support[i]) - } + rule.Body = appendToBody(rule.Body, support...) rule.Head.Key = output } if rule.Head.Value != nil { support, output := expandExprTerm(gen, rule.Head.Value) - for i := range support { - rule.Body.Append(support[i]) - } + rule.Body = appendToBody(rule.Body, support...) rule.Head.Value = output } } +// isEmptyBody true for a rule like `pi := 3.14 if { true}` +func isEmptyBody(body Body) bool { + if len(body) == 1 { + if term, ok := body[0].Terms.(*Term); ok { + return Boolean(true).Equal(term.Value) + } + } + + return false +} + +func isConstantRule(rule *Rule) bool { + if isEmptyBody(rule.Body) { + switch v := rule.Head.Value.Value.(type) { + case String, Var, Number, Boolean, Null: + return true + case *Array, *object, Set: + return v.IsGround() + } + } + return false +} + +// appendToBody inlines Body.Append and adds additional logic for +// replacing a single 'true' expression (i.e an empty body) with +// the first expression to be appended, while appending the rest +// of the expressions as normal. Additionally accepts multiple +// expressions to append, which potentially reduces allocations +// in larger appends. +func appendToBody(body Body, exprs ...*Expr) Body { + if len(exprs) == 0 { + return body + } + + blen := len(body) + if blen == 1 && isEmptyBody(body) { + // body will no longer be empty, so instead of appending, + // replace the 'true' expression with the new expression. + exprs[0].Index = 0 + body[0], exprs = exprs[0], exprs[1:] + } + for i, expr := range exprs { + expr.Index = blen + i + } + + return append(body, exprs...) +} + func rewriteExprTermsInBody(gen *localVarGenerator, body Body) Body { cpy := make(Body, 0, len(body)) for i := range body { @@ -4991,9 +5578,8 @@ func expandExpr(gen *localVarGenerator, expr *Expr) (result []*Expr) { extras[i].With = expr.With } } - result = append(result, extras...) expr.Terms = term - result = append(result, expr) + result = append(append(result, extras...), expr) case []*Term: for i := 1; i < len(terms); i++ { var extras []*Expr @@ -5033,6 +5619,7 @@ func connectGeneratedExprs(parent *Expr, children ...*Expr) { func expandExprTerm(gen *localVarGenerator, term *Term) (support []*Expr, output *Term) { output = term + switch v := term.Value.(type) { case Call: for i := 1; i < len(v); i++ { @@ -5066,30 +5653,19 @@ func expandExprTerm(gen *localVarGenerator, term *Term) (support []*Expr, output output = NewTerm(cpy).SetLocation(term.Location) case *ArrayComprehension: support, term := expandExprTerm(gen, v.Term) - for i := range support { - v.Body.Append(support[i]) - } v.Term = term - v.Body = rewriteExprTermsInBody(gen, v.Body) + v.Body = rewriteExprTermsInBody(gen, appendToBody(v.Body, support...)) case *SetComprehension: support, term := expandExprTerm(gen, v.Term) - for i := range support { - v.Body.Append(support[i]) - } v.Term = term - v.Body = rewriteExprTermsInBody(gen, v.Body) + v.Body = rewriteExprTermsInBody(gen, appendToBody(v.Body, support...)) case *ObjectComprehension: support, key := expandExprTerm(gen, v.Key) - for i := range support { - v.Body.Append(support[i]) - } + v.Body = appendToBody(v.Body, support...) v.Key = key support, value := expandExprTerm(gen, v.Value) - for i := range support { - v.Body.Append(support[i]) - } v.Value = value - v.Body = rewriteExprTermsInBody(gen, v.Body) + v.Body = rewriteExprTermsInBody(gen, appendToBody(v.Body, support...)) } return } @@ -5507,7 +6083,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(), "%s", err.Error())) + return nil, append(errs, newErrorString(CompileErr, every.Loc(), err.Error())) } every.Key.Value = gv } @@ -5519,7 +6095,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(), "%s", err.Error())) + return nil, append(errs, newErrorString(CompileErr, every.Loc(), err.Error())) } every.Value.Value = gv } @@ -5537,7 +6113,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(), "%s", err.Error())) + return nil, append(errs, newErrorString(CompileErr, decl.Loc(), err.Error())) } case Call: var key, val, container *Term @@ -5563,11 +6139,11 @@ func rewriteSomeDeclStatement(g *localVarGenerator, stack *localDeclaredVars, ex RefTerm(VarTerm(Equality.Name)), val, rhs, } - output := VarSet{} + output := NewVarSet() for _, v0 := range outputVarsForExprEq(e, container.Vars(), output).Sorted() { if _, err := rewriteDeclaredVar(g, stack, v0, declaredVar); err != nil { - return nil, append(errs, NewError(CompileErr, decl.Loc(), "%s", err.Error())) + return nil, append(errs, newErrorString(CompileErr, decl.Loc(), err.Error())) } } return rewriteDeclaredVarsInExpr(g, stack, e, errs, strict) @@ -5621,7 +6197,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, "%s", err.Error())) + errs = append(errs, newErrorString(CompileErr, t.Location, err.Error())) } else { t.Value = gv } @@ -5636,7 +6212,7 @@ 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, "%s", err.Error())) + errs = append(errs, newErrorString(CompileErr, t.Location, err.Error())) } else { t.Value = gv } @@ -5748,9 +6324,20 @@ func rewriteDeclaredVarsInWithRecursive(g *localVarGenerator, stack *localDeclar return rewriteDeclaredVarsInTermRecursive(g, stack, w.Value, errs, strict) } +func rewriteDeclaredVarsInTemplateString(g *localVarGenerator, stack *localDeclaredVars, ts *TemplateString, errs Errors, strict bool) Errors { + for i, p := range ts.Parts { + if expr, ok := p.(*Expr); ok { + stack.Push() + ts.Parts[i], errs = rewriteDeclaredVarsInExpr(g, stack, expr, errs, strict) + stack.Pop() + } + } + + return errs +} + func rewriteDeclaredVarsInArrayComprehension(g *localVarGenerator, stack *localDeclaredVars, v *ArrayComprehension, errs Errors, strict bool) Errors { - used := NewVarSet() - used.Update(v.Term.Vars()) + used := v.Term.Vars() stack.Push() v.Body, errs = rewriteDeclaredVarsInBody(g, stack, used, v.Body, errs, strict) @@ -5760,8 +6347,7 @@ func rewriteDeclaredVarsInArrayComprehension(g *localVarGenerator, stack *localD } func rewriteDeclaredVarsInSetComprehension(g *localVarGenerator, stack *localDeclaredVars, v *SetComprehension, errs Errors, strict bool) Errors { - used := NewVarSet() - used.Update(v.Term.Vars()) + used := v.Term.Vars() stack.Push() v.Body, errs = rewriteDeclaredVarsInBody(g, stack, used, v.Body, errs, strict) @@ -5882,7 +6468,7 @@ func validateWith(c *Compiler, unsafeBuiltinsMap map[string]struct{}, expr *Expr // and edge case anyways. if child := targetNode.Child(ref[len(ref)-1].Value); child != nil { for _, v := range child.Values { - if len(v.(*Rule).Head.Args) > 0 { + if len(v.Head.Args) > 0 { if ok, err := validateWithFunctionValue(c.builtins, unsafeBuiltinsMap, c.RuleTree, value); err != nil || ok { return false, err // err may be nil } @@ -5896,7 +6482,7 @@ func validateWith(c *Compiler, unsafeBuiltinsMap map[string]struct{}, expr *Expr // TODO: check that target ref doesn't exist? if valueNode := c.RuleTree.Find(r); valueNode != nil { for _, v := range valueNode.Values { - if len(v.(*Rule).Head.Args) > 0 { + if len(v.Head.Args) > 0 { return false, nil } } @@ -5904,7 +6490,6 @@ func validateWith(c *Compiler, unsafeBuiltinsMap map[string]struct{}, expr *Expr } case isInputRef(target): // ok, valid case isBuiltinRefOrVar: - // NOTE(sr): first we ensure that parsed Var builtins (`count`, `concat`, etc) // are rewritten to their proper Ref convention if v, ok := target.Value.(Var); ok { @@ -5960,30 +6545,23 @@ func validateWithFunctionValue(bs map[string]*Builtin, unsafeMap map[string]stru } func isInputRef(term *Term) bool { - if ref, ok := term.Value.(Ref); ok { - if ref.HasPrefix(InputRootRef) { - return true - } - } - return false + ref, ok := term.Value.(Ref) + return ok && ref.HasPrefix(InputRootRef) } func isDataRef(term *Term) bool { - if ref, ok := term.Value.(Ref); ok { - if ref.HasPrefix(DefaultRootRef) { - return true - } - } - return false + ref, ok := term.Value.(Ref) + return ok && ref.HasPrefix(DefaultRootRef) } func isBuiltinRefOrVar(bs map[string]*Builtin, unsafeBuiltinsMap map[string]struct{}, term *Term) (bool, *Error) { switch v := term.Value.(type) { case Ref, Var: - if _, ok := unsafeBuiltinsMap[v.String()]; ok { + vs := v.String() + if _, ok := unsafeBuiltinsMap[vs]; ok { return false, NewError(CompileErr, term.Location, "with keyword replacing built-in function: target must not be unsafe: %q", v) } - _, ok := bs[v.String()] + _, ok := bs[vs] return ok, nil } return false, nil @@ -6029,9 +6607,7 @@ func safetyErrorSlice(unsafe unsafeVars, rewritten map[Var]Var) (result Errors) // If the expression contains unsafe generated variables, report which // expressions are unsafe instead of the variables that are unsafe (since // the latter are not meaningful to the user.) - pairs := unsafe.Slice() - - slices.SortFunc(pairs, func(a, b unsafePair) int { + pairs := util.SortedFunc(unsafe.Slice(), func(a, b unsafePair) int { return a.Expr.Location.Compare(b.Expr.Location) }) @@ -6124,6 +6700,5 @@ func (rs *refSet) Sorted() []*Term { for i := range rs.s { terms[i] = NewTerm(rs.s[i]) } - slices.SortFunc(terms, TermValueCompare) - return terms + return util.SortedFunc(terms, TermValueCompare) } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/compilehelper.go b/vendor/github.com/open-policy-agent/opa/v1/ast/compilehelper.go index 7d81d45e6d25..4ea122f3cb55 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/compilehelper.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/compilehelper.go @@ -33,7 +33,8 @@ func CompileModulesWithOpt(modules map[string]string, opts CompileOpts) (*Compil compiler := NewCompiler(). WithDefaultRegoVersion(opts.ParserOptions.RegoVersion). - WithEnablePrintStatements(opts.EnablePrintStatements) + WithEnablePrintStatements(opts.EnablePrintStatements). + WithCapabilities(opts.ParserOptions.Capabilities) compiler.Compile(parsed) if compiler.Failed() { diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/conflicts.go b/vendor/github.com/open-policy-agent/opa/v1/ast/conflicts.go index 685cc6b6943c..b119f80eac80 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/conflicts.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/conflicts.go @@ -63,9 +63,9 @@ func checkDocumentConflicts(node *TreeNode, exists func([]string) (bool, error), if len(node.Values) > 0 { s := strings.Join(path, "/") if ok, err := exists(path); err != nil { - return Errors{NewError(CompileErr, node.Values[0].(*Rule).Loc(), "conflict check for data path %v: %v", s, err.Error())} + return Errors{NewError(CompileErr, node.Values[0].Loc(), "conflict check for data path %v: %v", s, err.Error())} } else if ok { - return Errors{NewError(CompileErr, node.Values[0].(*Rule).Loc(), "conflicting rule for data path %v found", s)} + return Errors{NewError(CompileErr, node.Values[0].Loc(), "conflicting rule for data path %v found", s)} } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/env.go b/vendor/github.com/open-policy-agent/opa/v1/ast/env.go index 12d4be89185f..3a3e79377834 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/env.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/env.go @@ -29,6 +29,7 @@ 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 any) types.Type { if term, ok := x.(*Term); ok { @@ -53,15 +54,14 @@ func (env *TypeEnv) GetByValue(v Value) types.Type { return types.B case Number: return types.N - case String: + case String, *TemplateString: return types.S // Composites. case *Array: static := make([]types.Type, x.Len()) for i := range static { - tpe := env.GetByValue(x.Elem(i).Value) - static[i] = tpe + static[i] = env.GetByValue(x.Elem(i).Value) } var dynamic types.Type @@ -79,17 +79,13 @@ func (env *TypeEnv) GetByValue(v Value) types.Type { x.Foreach(func(k, v *Term) { if IsConstant(k.Value) { - kjson, err := JSON(k.Value) - if err == nil { - tpe := env.GetByValue(v.Value) - static = append(static, types.NewStaticProperty(kjson, tpe)) + if kjson, err := JSON(k.Value); err == nil { + static = append(static, types.NewStaticProperty(kjson, env.GetByValue(v.Value))) return } } // Can't handle it as a static property, fallback to dynamic - typeK := env.GetByValue(k.Value) - typeV := env.GetByValue(v.Value) - dynamic = types.NewDynamicProperty(typeK, typeV) + dynamic = types.NewDynamicProperty(env.GetByValue(k.Value), env.GetByValue(v.Value)) }) if len(static) == 0 && dynamic == nil { @@ -98,7 +94,7 @@ func (env *TypeEnv) GetByValue(v Value) types.Type { return types.NewObject(static, dynamic) - case Set: + case *set: var tpe types.Type x.Foreach(func(elem *Term) { tpe = types.Or(tpe, env.GetByValue(elem.Value)) @@ -161,12 +157,13 @@ func (env *TypeEnv) GetByRef(ref Ref) types.Type { } func (env *TypeEnv) getRefFallback(ref Ref) types.Type { - if env.next != nil { return env.next.GetByRef(ref) } if RootDocumentNames.Contains(ref[0]) { + // types.A is an empty types.Any + // this is used to represent a potential non-local reference return types.A } @@ -298,15 +295,11 @@ func (n *typeTreeNode) PutOne(key Value, tpe types.Type) { func (n *typeTreeNode) Put(path Ref, tpe types.Type) { curr := n for _, term := range path { - c, ok := curr.children.Get(term.Value) - - var child *typeTreeNode + child, ok := curr.children.Get(term.Value) if !ok { child = newTypeTree() child.key = term.Value curr.children.Put(child.key, child) - } else { - child = c } curr = child @@ -320,23 +313,18 @@ func (n *typeTreeNode) Put(path Ref, tpe types.Type) { func (n *typeTreeNode) Insert(path Ref, tpe types.Type, env *TypeEnv) { curr := n for i, term := range path { - c, ok := curr.children.Get(term.Value) - - var child *typeTreeNode + child, ok := curr.children.Get(term.Value) if !ok { child = newTypeTree() child.key = term.Value curr.children.Put(child.key, child) - } else { - 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 { - var err error - child.value, err = insertIntoObject(o, path[i+1:], tpe, env) - if err != nil { - panic(fmt.Errorf("unreachable, insertIntoObject: %w", err)) - } + } else 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 { + var err error + child.value, err = insertIntoObject(o, path[i+1:], tpe, env) + if err != nil { + panic(fmt.Errorf("unreachable, insertIntoObject: %w", err)) } } } @@ -348,8 +336,7 @@ func (n *typeTreeNode) Insert(path Ref, tpe types.Type, env *TypeEnv) { if _, ok := tpe.(*types.Object); ok && curr.children.Len() > 0 { // merge all leafs into the inserted object - leafs := curr.Leafs() - for p, t := range leafs { + for p, t := range curr.Leafs() { var err error curr.value, err = insertIntoObject(curr.value.(*types.Object), *p, t, env) if err != nil { @@ -387,7 +374,8 @@ func mergeTypes(a, b types.Type) types.Type { bDynProps := bObj.DynamicProperties() dynProps := types.NewDynamicProperty( types.Or(aDynProps.Key, bDynProps.Key), - mergeTypes(aDynProps.Value, bDynProps.Value)) + mergeTypes(aDynProps.Value, bDynProps.Value), + ) return types.NewObject(nil, dynProps) } else if bAny, ok := b.(types.Any); ok && len(a.StaticProperties()) == 0 { // If a is an object type with no static components ... @@ -416,14 +404,14 @@ func mergeTypes(a, b types.Type) types.Type { } func (n *typeTreeNode) String() string { - b := strings.Builder{} + b := &strings.Builder{} + key := "-" if k := n.key; k != nil { - b.WriteString(k.String()) - } else { - b.WriteString("-") + key = k.String() } + b.WriteString(key) if v := n.value; v != nil { b.WriteString(": ") b.WriteString(v.String()) @@ -431,9 +419,7 @@ func (n *typeTreeNode) String() string { 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) + b.WriteString(strings.ReplaceAll(child.String(), "\n", "\n\t")) return false }) @@ -484,7 +470,8 @@ func (n *typeTreeNode) Leafs() map[*Ref]types.Type { func collectLeafs(n *typeTreeNode, path Ref, leafs map[*Ref]types.Type) { nPath := append(path, NewTerm(n.key)) if n.Leaf() { - leafs[&nPath] = n.Value() + npc := nPath // copy of else nPath escapes to heap even if !n.Leaf() + leafs[&npc] = n.Value() return } n.children.Iter(func(_ Value, v *typeTreeNode) bool { @@ -512,7 +499,6 @@ func selectConstant(tpe types.Type, term *Term) types.Type { // contains vars or refs, then the returned type will be a union of the // possible types. func selectRef(tpe types.Type, ref Ref) types.Type { - if tpe == nil || len(ref) == 0 { return tpe } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/errors.go b/vendor/github.com/open-policy-agent/opa/v1/ast/errors.go index 75160afc6e14..bf8bca74729d 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/errors.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/errors.go @@ -99,26 +99,35 @@ func (e *Error) Error() string { } } - msg := fmt.Sprintf("%v: %v", e.Code, e.Message) - + sb := strings.Builder{} if len(prefix) > 0 { - msg = prefix + ": " + msg + sb.WriteString(prefix) + sb.WriteString(": ") } + sb.WriteString(e.Code) + sb.WriteString(": ") + sb.WriteString(e.Message) + if e.Details != nil { for _, line := range e.Details.Lines() { - msg += "\n\t" + line + sb.WriteString("\n\t") + sb.WriteString(line) } } - return msg + return sb.String() } // NewError returns a new Error object. func NewError(code string, loc *Location, f string, a ...any) *Error { + return newErrorString(code, loc, fmt.Sprintf(f, a...)) +} + +func newErrorString(code string, loc *Location, m string) *Error { return &Error{ Code: code, Location: loc, - Message: fmt.Sprintf(f, a...), + Message: m, } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/index.go b/vendor/github.com/open-policy-agent/opa/v1/ast/index.go index 845447b6dc45..663072ed83b7 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/index.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/index.go @@ -412,7 +412,7 @@ func (i *refindices) updateGlobMatch(rule *Rule, expr *Expr) { if _, ok := match.Value.(Var); ok { var ref Ref for _, other := range i.rules[rule] { - if _, ok := other.Value.(Var); ok && other.Value.Compare(match.Value) == 0 { + if ov, ok := other.Value.(Var); ok && ov.Equal(match.Value) { ref = other.Ref } } @@ -586,28 +586,24 @@ func newTrieNodeImpl() *trieNode { } func (node *trieNode) Do(walker trieWalker) { + if node == nil { + return + } next := walker.Do(node) if next == nil { return } - if node.any != nil { - node.any.Do(next) - } - if node.undefined != nil { - node.undefined.Do(next) - } + + node.any.Do(next) + node.undefined.Do(next) node.scalars.Iter(func(_ Value, child *trieNode) bool { child.Do(next) return false }) - if node.array != nil { - node.array.Do(next) - } - if node.next != nil { - node.next.Do(next) - } + node.array.Do(next) + node.next.Do(next) } func (node *trieNode) Insert(ref Ref, value Value, mapper *valueMapper) *trieNode { @@ -699,7 +695,6 @@ func (node *trieNode) insertArray(arr *Array) *trieNode { } func (node *trieNode) traverse(resolver ValueResolver, tr *trieTraversalResult) error { - if node == nil { return nil } @@ -712,31 +707,31 @@ func (node *trieNode) traverse(resolver ValueResolver, tr *trieTraversalResult) return err } - if node.undefined != nil { - err = node.undefined.Traverse(resolver, tr) - if err != nil { - return err - } + err = node.undefined.Traverse(resolver, tr) + if err != nil { + return err } if v == nil { return nil } - if node.any != nil { - err = node.any.Traverse(resolver, tr) - if err != nil { - return err - } + err = node.any.Traverse(resolver, tr) + if err != nil { + return err } - if err := node.traverseValue(resolver, tr, v); err != nil { + err = node.traverseValue(resolver, tr, v) + if err != nil { return err } for i := range node.mappers { - if err := node.traverseValue(resolver, tr, node.mappers[i].MapValue(v)); err != nil { - return err + mapped := node.mappers[i].MapValue(v) + if !ValueEqual(mapped, v) { + if err := node.traverseValue(resolver, tr, mapped); err != nil { + return err + } } } @@ -747,9 +742,6 @@ func (node *trieNode) traverseValue(resolver ValueResolver, tr *trieTraversalRes switch value := value.(type) { case *Array: - if node.array == nil { - return nil - } return node.array.traverseArray(resolver, tr, value) case Null, Boolean, Number, String: @@ -764,16 +756,17 @@ func (node *trieNode) traverseValue(resolver ValueResolver, tr *trieTraversalRes } func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalResult, arr *Array) error { + if node == nil { + return nil + } if arr.Len() == 0 { return node.Traverse(resolver, tr) } - if node.any != nil { - err := node.any.traverseArray(resolver, tr, arr.Slice(1, -1)) - if err != nil { - return err - } + err := node.any.traverseArray(resolver, tr, arr.Slice(1, -1)) + if err != nil { + return err } head := arr.Elem(0).Value @@ -784,10 +777,7 @@ func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalRes switch head := head.(type) { case Null, Boolean, Number, String: - child, ok := node.scalars.Get(head) - if !ok { - return nil - } + child, _ := node.scalars.Get(head) return child.traverseArray(resolver, tr, arr.Slice(1, -1)) } @@ -795,7 +785,6 @@ func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalRes } func (node *trieNode) traverseUnknown(resolver ValueResolver, tr *trieTraversalResult) error { - if node == nil { return nil } @@ -884,7 +873,6 @@ func indexValue(b Value) (Value, bool) { } func globDelimiterToString(delim *Term) (string, bool) { - arr, ok := delim.Value.(*Array) if !ok { return "", false @@ -895,14 +883,16 @@ func globDelimiterToString(delim *Term) (string, bool) { if arr.Len() == 0 { result = "." } else { + sb := strings.Builder{} for i := range arr.Len() { term := arr.Elem(i) s, ok := term.Value.(String) if !ok { return "", false } - result += string(s) + sb.WriteString(string(s)) } + result = sb.String() } return result, true diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/internal/scanner/scanner.go b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/scanner/scanner.go index 3741d371886b..6b2b03b27af9 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/internal/scanner/scanner.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/scanner/scanner.go @@ -158,18 +158,42 @@ func (s *Scanner) WithoutKeywords(kws map[string]tokens.Token) (*Scanner, map[st return &cpy, kw } +type ScanOptions struct { + continueTemplateString bool + rawTemplateString bool +} + +type ScanOption func(*ScanOptions) + +// ContinueTemplateString will continue scanning a template string +func ContinueTemplateString(raw bool) ScanOption { + return func(opts *ScanOptions) { + opts.continueTemplateString = true + opts.rawTemplateString = raw + } +} + // Scan will increment the scanners position in the source // code until the next token is found. The token, starting position // of the token, string literal, and any errors encountered are // returned. A token will always be returned, the caller must check // for any errors before using the other values. -func (s *Scanner) Scan() (tokens.Token, Position, string, []Error) { +func (s *Scanner) Scan(opts ...ScanOption) (tokens.Token, Position, string, []Error) { + scanOpts := &ScanOptions{} + for _, opt := range opts { + opt(scanOpts) + } pos := Position{Offset: s.offset - s.width, Row: s.row, Col: s.col, Tabs: s.tabs} var tok tokens.Token var lit string - - if s.isWhitespace() { + if scanOpts.continueTemplateString { + if scanOpts.rawTemplateString { + lit, tok = s.scanRawTemplateString() + } else { + lit, tok = s.scanTemplateString() + } + } else if s.isWhitespace() { // 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 { @@ -275,6 +299,17 @@ func (s *Scanner) Scan() (tokens.Token, Position, string, []Error) { tok = tokens.Semicolon case '.': tok = tokens.Dot + case '$': + switch s.curr { + case '`': + s.next() + lit, tok = s.scanRawTemplateString() + case '"': + s.next() + lit, tok = s.scanTemplateString() + default: + s.error("illegal $ character") + } } } @@ -395,6 +430,116 @@ func (s *Scanner) scanRawString() string { return util.ByteSliceToString(s.bs[start : s.offset-1]) } +func (s *Scanner) scanTemplateString() (string, tokens.Token) { + tok := tokens.TemplateStringPart + start := s.literalStart() + var escapes []int + for { + ch := s.curr + + if ch == '\n' || ch < 0 { + s.error("non-terminated string") + break + } + + s.next() + + if ch == '"' { + tok = tokens.TemplateStringEnd + break + } + + if ch == '{' { + break + } + + if ch == '\\' { + switch s.curr { + case '\\', '"', '/', 'b', 'f', 'n', 'r', 't': + s.next() + case '{': + escapes = append(escapes, s.offset-1) + s.next() + case 'u': + s.next() + s.next() + s.next() + s.next() + default: + s.error("illegal escape sequence") + } + } + } + + // Lazily remove escapes to not unnecessarily allocate a new byte slice + if len(escapes) > 0 { + return util.ByteSliceToString(removeEscapes(s, escapes, start)), tok + } + + return util.ByteSliceToString(s.bs[start : s.offset-1]), tok +} + +func (s *Scanner) scanRawTemplateString() (string, tokens.Token) { + tok := tokens.RawTemplateStringPart + start := s.literalStart() + var escapes []int + for { + ch := s.curr + + if ch < 0 { + s.error("non-terminated string") + break + } + + s.next() + + if ch == '`' { + tok = tokens.RawTemplateStringEnd + break + } + + if ch == '{' { + break + } + + if ch == '\\' { + switch s.curr { + case '{': + escapes = append(escapes, s.offset-1) + s.next() + } + } + } + + // Lazily remove escapes to not unnecessarily allocate a new byte slice + if len(escapes) > 0 { + return util.ByteSliceToString(removeEscapes(s, escapes, start)), tok + } + + return util.ByteSliceToString(s.bs[start : s.offset-1]), tok +} + +func removeEscapes(s *Scanner, escapes []int, start int) []byte { + from := start + bs := make([]byte, 0, s.offset-start-len(escapes)) + + for _, escape := range escapes { + // Append the bytes before the escape sequence. + if escape > from { + bs = append(bs, s.bs[from:escape-1]...) + } + // Skip the escape character. + from = escape + } + + // Append the remaining bytes after the last escape sequence. + if from < s.offset-1 { + bs = append(bs, s.bs[from:s.offset-1]...) + } + + return bs +} + func (s *Scanner) scanComment() string { start := s.literalStart() for s.curr != '\n' && s.curr != -1 { diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/internal/tokens/tokens.go b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/tokens/tokens.go index 4033ba81ae61..2721c3618bbf 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/internal/tokens/tokens.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/internal/tokens/tokens.go @@ -39,6 +39,10 @@ const ( Number String + TemplateStringPart + TemplateStringEnd + RawTemplateStringPart + RawTemplateStringEnd LBrack RBrack @@ -67,6 +71,7 @@ const ( Lte Dot Semicolon + Dollar Every Contains @@ -74,53 +79,58 @@ const ( ) var strings = [...]string{ - Illegal: "illegal", - EOF: "eof", - Whitespace: "whitespace", - Comment: "comment", - Ident: "identifier", - Package: "package", - Import: "import", - As: "as", - Default: "default", - Else: "else", - Not: "not", - Some: "some", - With: "with", - Null: "null", - True: "true", - False: "false", - Number: "number", - String: "string", - LBrack: "[", - RBrack: "]", - LBrace: "{", - RBrace: "}", - LParen: "(", - RParen: ")", - Comma: ",", - Colon: ":", - Add: "plus", - Sub: "minus", - Mul: "mul", - Quo: "div", - Rem: "rem", - And: "and", - Or: "or", - Unify: "eq", - Equal: "equal", - Assign: "assign", - In: "in", - Neq: "neq", - Gt: "gt", - Lt: "lt", - Gte: "gte", - Lte: "lte", - Dot: ".", - Semicolon: ";", - Every: "every", - Contains: "contains", - If: "if", + Illegal: "illegal", + EOF: "eof", + Whitespace: "whitespace", + Comment: "comment", + Ident: "identifier", + Package: "package", + Import: "import", + As: "as", + Default: "default", + Else: "else", + Not: "not", + Some: "some", + With: "with", + Null: "null", + True: "true", + False: "false", + Number: "number", + String: "string", + TemplateStringPart: "template-string-part", + TemplateStringEnd: "template-string-end", + RawTemplateStringPart: "raw-template-string-part", + RawTemplateStringEnd: "raw-template-string-end", + LBrack: "[", + RBrack: "]", + LBrace: "{", + RBrace: "}", + LParen: "(", + RParen: ")", + Comma: ",", + Colon: ":", + Add: "plus", + Sub: "minus", + Mul: "mul", + Quo: "div", + Rem: "rem", + And: "and", + Or: "or", + Unify: "eq", + Equal: "equal", + Assign: "assign", + In: "in", + Neq: "neq", + Gt: "gt", + Lt: "lt", + Gte: "gte", + Lte: "lte", + Dot: ".", + Semicolon: ";", + Dollar: "dollar", + Every: "every", + Contains: "contains", + If: "if", } var keywords = map[string]Token{ @@ -147,3 +157,7 @@ func IsKeyword(tok Token) bool { _, ok := keywords[strings[tok]] return ok } + +func KeywordFor(tok Token) string { + return strings[tok] +} 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 index fc5a89f69a60..4f454beb965d 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/interning.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/interning.go @@ -5,6 +5,7 @@ package ast import ( + "iter" "strconv" ) @@ -19,27 +20,46 @@ type internable interface { var ( InternedNullValue Value = Null{} - InternedNullTerm = &Term{Value: InternedNullValue} + InternedNullTerm = NewTerm(InternedNullValue) InternedBooleanTrueValue Value = Boolean(true) InternedBooleanFalseValue Value = Boolean(false) - InternedBooleanTrueTerm = &Term{Value: InternedBooleanTrueValue} - InternedBooleanFalseTerm = &Term{Value: InternedBooleanFalseValue} + InternedEmptyStringValue Value = String("") + InternedEmptyArrayValue Value = NewArray() + InternedEmptyRefValue Value = Ref{} + InternedEmptyObjectValue Value = NewObject() + InternedEmptySetValue Value = NewSet() - InternedEmptyString = StringTerm("") - InternedEmptyObject = ObjectTerm() - InternedEmptyArray = ArrayTerm() - InternedEmptySet = SetTerm() - - InternedEmptyArrayValue = NewArray() + InternedBooleanTrue = NewTerm(InternedBooleanTrueValue) + InternedBooleanFalse = NewTerm(InternedBooleanFalseValue) + InternedEmptyString = NewTerm(InternedEmptyStringValue) + InternedEmptyObject = NewTerm(InternedEmptyObjectValue) + InternedEmptyArray = NewTerm(InternedEmptyArrayValue) + InternedEmptySet = NewTerm(InternedEmptySetValue) // since this is by far the most common negative number minusOneValue Value = Number("-1") - minusOneTerm = &Term{Value: minusOneValue} + minusOneTerm = NewTerm(minusOneValue) internedStringTerms = map[string]*Term{ "": InternedEmptyString, } + + internedVarValues = map[string]Value{ + "input": Var("input"), + "data": Var("data"), + "args": Var("args"), + "schema": Var("schema"), + "key": Var("key"), + "value": Var("value"), + "future": Var("future"), + "rego": Var("rego"), + "set": Var("set"), + "internal": Var("internal"), + "else": Var("else"), + + "i": Var("i"), "j": Var("j"), "k": Var("k"), "v": Var("v"), "x": Var("x"), "y": Var("y"), "z": Var("z"), + } ) // InternStringTerm interns the given strings as terms. Note that Interning is @@ -52,7 +72,21 @@ func InternStringTerm(str ...string) { continue } - internedStringTerms[s] = StringTerm(s) + internedStringTerms[s] = &Term{Value: String(s)} + } +} + +// InternVarValue interns the given variable names as Var Values. Note that Interning is +// considered experimental and should not be relied upon by external code. +// WARNING: This must **only** be called at initialization time, as the +// interned terms are shared globally, and the underlying map is not thread-safe. +func InternVarValue(names ...string) { + for _, name := range names { + if _, ok := internedVarValues[name]; ok { + continue + } + + internedVarValues[name] = Var(name) } } @@ -94,6 +128,16 @@ func InternedValue[T internable](v T) Value { return InternedValueOr(v, internedTermValue) } +// InternedVarValue returns an interned Var Value for the given name. If the +// name is not interned, a new Var Value is returned. +func InternedVarValue(name string) Value { + if v, ok := internedVarValues[name]; ok { + return v + } + + return Var(name) +} + // InternedValueOr returns an interned Value for scalar v. Calls supplier // to produce a Value if the value is not interned. func InternedValueOr[T internable](v T, supplier func(T) Value) Value { @@ -157,6 +201,13 @@ func InternedTerm[T internable](v T) *Term { } } +// InternedItem works just like [Item] but returns interned terms for both +// key and value where possible. This is mostly useful for making tests less +// verbose. +func InternedItem[K, V internable](key K, value V) [2]*Term { + return [2]*Term{InternedTerm(key), InternedTerm(value)} +} + // 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. @@ -168,6 +219,19 @@ func InternedIntNumberTermFromString(s string) *Term { return nil } +// InternedIntRange returns a sequence of interned integer number terms +// from start (inclusive) to end (exclusive). For values outside of the +// interned range, non-interned IntNumberTerms are returned. +func InternedIntRange(start, end int) iter.Seq[*Term] { + return func(yield func(*Term) bool) { + for i := start; i < end; i++ { + if !yield(internedIntNumberTerm(i)) { + return + } + } + } +} + // HasInternedIntNumberTerm returns true if the given integer value maps to an interned // term, otherwise false. func HasInternedIntNumberTerm(i int) bool { @@ -206,10 +270,10 @@ func internedBooleanValue(b bool) Value { // InternedBooleanTerm returns an interned term with the given boolean value. func internedBooleanTerm(b bool) *Term { if b { - return InternedBooleanTrueTerm + return InternedBooleanTrue } - return InternedBooleanFalseTerm + return InternedBooleanFalse } func internedIntNumberValue(i int) Value { @@ -276,7 +340,7 @@ func init() { // Various "data", "input", "result", "keywords", "path", "v1", "error", "partial", // HTTP - "code", "message", "status_code", "method", "url", "uri", + "code", "message", "status_code", "method", "url", "uri", "body", "raw_body", "headers", "query_params", // JWT "enc", "cty", "iss", "exp", "nbf", "aud", "secret", "cert", // Decisions diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/location/location.go b/vendor/github.com/open-policy-agent/opa/v1/ast/location/location.go index 6d1b16cdfcb0..6431b02ce999 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/location/location.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/location/location.go @@ -8,6 +8,7 @@ import ( "fmt" astJSON "github.com/open-policy-agent/opa/v1/ast/json" + "github.com/open-policy-agent/opa/v1/util" ) // Location records a position in source code @@ -28,10 +29,10 @@ func NewLocation(text []byte, file string, row int, col int) *Location { // Equal checks if two locations are equal to each other. func (loc *Location) Equal(other *Location) bool { - return bytes.Equal(loc.Text, other.Text) && - loc.File == other.File && + return loc.File == other.File && loc.Row == other.Row && - loc.Col == other.Col + loc.Col == other.Col && + bytes.Equal(loc.Text, other.Text) } // Errorf returns a new error value with a message formatted to include the location @@ -57,13 +58,35 @@ func (loc *Location) Format(f string, a ...any) string { } func (loc *Location) String() string { - if len(loc.File) > 0 { - return fmt.Sprintf("%v:%v", loc.File, loc.Row) + buf, _ := loc.AppendText(make([]byte, 0, loc.StringLength())) + return util.ByteSliceToString(buf) +} + +func (loc *Location) AppendText(buf []byte) ([]byte, error) { + if loc != nil { + switch { + case len(loc.File) > 0: + buf = util.AppendInt(append(append(buf, loc.File...), ':'), loc.Row) + case len(loc.Text) > 0: + buf = append(buf, loc.Text...) + default: + buf = util.AppendInt(append(util.AppendInt(buf, loc.Row), ':'), loc.Col) + } } - if len(loc.Text) > 0 { - return string(loc.Text) + return buf, nil +} + +func (loc *Location) StringLength() (n int) { + if loc != nil { + if l := len(loc.File); l > 0 { + n = l + 1 + util.NumDigitsInt(loc.Row) + } else if l := len(loc.Text); l > 0 { + n = l + } else { + n = util.NumDigitsInt(loc.Row) + 1 + util.NumDigitsInt(loc.Col) + } } - return fmt.Sprintf("%v:%v", loc.Row, loc.Col) + return n } // Compare returns -1, 0, or 1 to indicate if this loc is less than, equal to, @@ -71,7 +94,7 @@ func (loc *Location) String() string { // column of the Location (but not on the text.) Nil locations are greater than // non-nil locations. func (loc *Location) Compare(other *Location) int { - if loc == nil && other == nil { + if loc == other { return 0 } else if loc == nil { return 1 diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/parser.go b/vendor/github.com/open-policy-agent/opa/v1/ast/parser.go index 8355186cb9ea..9e52b89a675c 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/parser.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/parser.go @@ -20,12 +20,13 @@ import ( "strings" "unicode/utf8" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v3" "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" + "github.com/open-policy-agent/opa/v1/util" ) // DefaultMaxParsingRecursionDepth is the default maximum recursion @@ -57,6 +58,25 @@ const ( RegoV1 ) +var ( + // this is the name to use for instantiating an empty set, e.g., `set()`. + setConstructor = RefTerm(VarTerm("set")) + + preAllocWildcards = [...]Value{ + Var("$0"), Var("$1"), Var("$2"), Var("$3"), Var("$4"), Var("$5"), + Var("$6"), Var("$7"), Var("$8"), Var("$9"), Var("$10"), + } + + // use static references to avoid allocations, and + // copy them to the call term only when needed + memberWithKeyRef = MemberWithKey.Ref() + memberRef = Member.Ref() + + newlineBytes = []byte{'\n'} + metadataBytes = []byte("METADATA") + metadataParserPool = util.NewSyncPool[metadataParser]() +) + func (v RegoVersion) Int() int { if v == RegoV1 { return 1 @@ -88,17 +108,17 @@ func RegoVersionFromInt(i int) RegoVersion { // can do efficient shallow copies of these values when doing a // save() and restore(). type state struct { + errors Errors + comments []*Comment + hints []string s *scanner.Scanner + loc Location + lit string lastEnd int - skippedNL bool - tok tokens.Token tokEnd int - lit string - loc Location - errors Errors - hints []string - comments []*Comment wildcard int + tok tokens.Token + skippedNL bool } func (s *state) String() string { @@ -451,7 +471,6 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { // next type of statement. If a statement can be parsed, continue from that // point trying to parse packages, imports, etc. in the same order. for p.s.tok != tokens.EOF { - s := p.save() if pkg := p.parsePackage(); pkg != nil { @@ -512,12 +531,12 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) { } func (p *Parser) parseAnnotations(stmts []Statement) []Statement { - annotStmts, errs := parseAnnotations(p.s.comments) for _, err := range errs { p.error(err.Location, err.Message) } + stmts = slices.Grow(stmts, len(annotStmts)) for _, annotStmt := range annotStmts { stmts = append(stmts, annotStmt) } @@ -525,53 +544,54 @@ func (p *Parser) parseAnnotations(stmts []Statement) []Statement { return stmts } -func parseAnnotations(comments []*Comment) ([]*Annotations, Errors) { +func parseAnnotations(comments []*Comment) (stmts []*Annotations, errs Errors) { + numBlocks := CountFunc(comments, isMetadataComment) + if numBlocks == 0 { + return nil, nil + } - var hint = []byte("METADATA") - var curr *metadataParser - var blocks []*metadataParser + stmts = make([]*Annotations, 0, numBlocks) + mdp := metadataParserPool.Get() + if mdp.buf == nil { + mdp.buf = &bytes.Buffer{} + } 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]) - continue + if isMetadataComment(comments[i]) { // scan until end of block + mdp.Reset(comments[i].Location) + for i++; i < len(comments) && !blockBuster(comments[i], comments[i-1]); i++ { + mdp.Append(comments[i]) } - curr = nil - } - if bytes.HasPrefix(bytes.TrimSpace(comments[i].Text), hint) { - curr = newMetadataParser(comments[i].Location) - blocks = append(blocks, curr) - } - } - var stmts []*Annotations - var errs Errors - for _, b := range blocks { - a, err := b.Parse() - if err != nil { - errs = append(errs, &Error{ - Code: ParseErr, - Message: err.Error(), - Location: b.loc, - }) - } else { - stmts = append(stmts, a) + if a, err := mdp.Parse(); err != nil { + errs = append(errs, &Error{Code: ParseErr, Message: err.Error(), Location: mdp.loc}) + } else { + stmts = append(stmts, a) + } } } + metadataParserPool.Put(mdp) + return stmts, errs } -func (p *Parser) parsePackage() *Package { +func isMetadataComment(c *Comment) bool { + return c.Location.Col == 1 && bytes.HasPrefix(bytes.TrimSpace(c.Text), metadataBytes) +} - var pkg Package - pkg.SetLoc(p.s.Loc()) +func blockBuster(curr, prev *Comment) bool { // or endOfBlock, but the name was too good to pass up + return curr.Location.Col != 1 || curr.Location.Row-1 != prev.Location.Row +} +func (p *Parser) parsePackage() *Package { if p.s.tok != tokens.Package { return nil } + var pkg Package + pkg.SetLoc(p.s.Loc()) + p.scanWS() // Make sure we allow the first term of refs to be the 'package' keyword. @@ -633,14 +653,13 @@ func (p *Parser) parsePackage() *Package { } func (p *Parser) parseImport() *Import { - - var imp Import - imp.SetLoc(p.s.Loc()) - if p.s.tok != tokens.Import { return nil } + var imp Import + imp.SetLoc(p.s.Loc()) + p.scanWS() // Make sure we allow the first term of refs to be the 'import' keyword. @@ -952,7 +971,7 @@ func (p *Parser) parseRules() []*Rule { next.Head.keywords = rule.Head.keywords for i := range next.Head.Args { if v, ok := next.Head.Args[i].Value.(Var); ok && v.IsWildcard() { - next.Head.Args[i].Value = Var(p.genwildcard()) + next.Head.Args[i].Value = p.genwildcard() } } setLocRecursive(next.Head, loc) @@ -972,7 +991,7 @@ func (p *Parser) parseElse(head *Head) *Rule { rule.Head.generatedValue = false for i := range rule.Head.Args { if v, ok := rule.Head.Args[i].Value.(Var); ok && v.IsWildcard() { - rule.Head.Args[i].Value = Var(p.genwildcard()) + rule.Head.Args[i].Value = p.genwildcard() } } rule.Head.SetLoc(p.s.Loc()) @@ -1281,14 +1300,11 @@ func (p *Parser) parseLiteralExpr(negated bool) *Expr { } func (p *Parser) parseWith() []*With { - withs := []*With{} for { + with := With{Location: p.s.Loc()} - with := With{ - Location: p.s.Loc(), - } p.scan() if p.s.tok != tokens.Ident { @@ -1525,11 +1541,6 @@ 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 { if !p.enter() { return nil @@ -1731,6 +1742,10 @@ func (p *Parser) parseTerm() *Term { term = p.parseNumber() case tokens.String: term = p.parseString() + case tokens.TemplateStringPart, tokens.TemplateStringEnd: + term = p.parseTemplateString(false) + case tokens.RawTemplateStringPart, tokens.RawTemplateStringEnd: + term = p.parseTemplateString(true) case tokens.Ident, tokens.Contains: // NOTE(sr): contains anywhere BUT in rule heads gets no special treatment term = p.parseVar() case tokens.LBrack: @@ -1762,7 +1777,7 @@ func (p *Parser) parseTermFinish(head *Term, skipws bool) *Term { return nil } offset := p.s.loc.Offset - p.doScan(skipws) + p.doScan(skipws, noScanOptions...) switch p.s.tok { case tokens.LParen, tokens.Dot, tokens.LBrack: @@ -1783,7 +1798,7 @@ func (p *Parser) parseHeadFinish(head *Term, skipws bool) *Term { return nil } offset := p.s.loc.Offset - p.doScan(false) + p.scanWS() switch p.s.tok { case tokens.Add, tokens.Sub, tokens.Mul, tokens.Quo, tokens.Rem, @@ -1791,7 +1806,7 @@ func (p *Parser) parseHeadFinish(head *Term, skipws bool) *Term { tokens.Equal, tokens.Neq, tokens.Gt, tokens.Gte, tokens.Lt, tokens.Lte: p.illegalToken() case tokens.Whitespace: - p.doScan(skipws) + p.doScan(skipws, noScanOptions...) } switch p.s.tok { @@ -1878,7 +1893,12 @@ func (p *Parser) parseNumber() *Term { func (p *Parser) parseString() *Term { if p.s.lit[0] == '"' { if p.s.lit == "\"\"" { - return NewTerm(InternedEmptyString.Value).SetLocation(p.s.Loc()) + return NewTerm(InternedEmptyStringValue).SetLocation(p.s.Loc()) + } + + inner := p.s.lit[1 : len(p.s.lit)-1] + if !strings.ContainsRune(inner, '\\') { // nothing to un-escape + return StringTerm(inner).SetLocation(p.s.Loc()) } var s string @@ -1898,8 +1918,119 @@ func (p *Parser) parseRawString() *Term { return StringTerm(p.s.lit[1 : len(p.s.lit)-1]).SetLocation(p.s.Loc()) } -// this is the name to use for instantiating an empty set, e.g., `set()`. -var setConstructor = RefTerm(VarTerm("set")) +func templateStringPartToStringLiteral(tok tokens.Token, lit string) (string, error) { + switch tok { + case tokens.TemplateStringPart, tokens.TemplateStringEnd: + inner := lit[1 : len(lit)-1] + if !strings.ContainsRune(inner, '\\') { // nothing to un-escape + return inner, nil + } + + buf := make([]byte, 0, len(inner)+2) + buf = append(buf, '"') + buf = append(buf, inner...) + buf = append(buf, '"') + var s string + if err := json.Unmarshal(buf, &s); err != nil { + return "", fmt.Errorf("illegal template-string part: %s", lit) + } + return s, nil + case tokens.RawTemplateStringPart, tokens.RawTemplateStringEnd: + return lit[1 : len(lit)-1], nil + default: + return "", errors.New("expected template-string part") + } +} + +func (p *Parser) parseTemplateString(multiLine bool) *Term { + loc := p.s.Loc() + + if !p.po.Capabilities.ContainsFeature(FeatureTemplateStrings) { + p.errorf(loc, "template strings are not supported by current capabilities") + return nil + } + + var parts []Node + + for { + s, err := templateStringPartToStringLiteral(p.s.tok, p.s.lit) + if err != nil { + p.error(p.s.Loc(), err.Error()) + return nil + } + + // Don't add empty strings + if len(s) > 0 { + parts = append(parts, StringTerm(s).SetLocation(p.s.Loc())) + } + + if p.s.tok == tokens.TemplateStringEnd || p.s.tok == tokens.RawTemplateStringEnd { + break + } + + numCommentsBefore := len(p.s.comments) + p.scan() + numCommentsAfter := len(p.s.comments) + + expr := p.parseLiteral() + if expr == nil { + p.error(p.s.Loc(), "invalid template-string expression") + return nil + } + + if expr.Negated { + p.errorf(expr.Loc(), "unexpected negation ('%s') in template-string expression", tokens.KeywordFor(tokens.Not)) + return nil + } + + // Note: Actually unification + if expr.IsEquality() { + p.errorf(expr.Loc(), "unexpected unification ('=') in template-string expression") + return nil + } + + if expr.IsAssignment() { + p.errorf(expr.Loc(), "unexpected assignment (':=') in template-string expression") + return nil + } + + if expr.IsEvery() { + p.errorf(expr.Loc(), "unexpected '%s' in template-string expression", tokens.KeywordFor(tokens.Every)) + return nil + } + + if expr.IsSome() { + p.errorf(expr.Loc(), "unexpected '%s' in template-string expression", tokens.KeywordFor(tokens.Some)) + return nil + } + + // FIXME: Can we optimize for collections and comprehensions too? To qualify, they must not contain refs or calls. + var nonOptional bool + if term, ok := expr.Terms.(*Term); ok && numCommentsAfter == numCommentsBefore { + switch term.Value.(type) { + case String, Number, Boolean, Null: + nonOptional = true + parts = append(parts, term) + } + } + + if !nonOptional { + parts = append(parts, expr) + } + + if p.s.tok != tokens.RBrace { + p.errorf(p.s.Loc(), "expected %s to end template string expression", tokens.RBrace) + return nil + } + + p.doScan(false, scanner.ContinueTemplateString(multiLine)) + } + + // When there are template-expressions, the initial location will only contain the text up to the first expression + loc.Text = p.s.Text(loc.Offset, p.s.tokEnd) + + return TemplateStringTerm(multiLine, parts...).SetLocation(loc) +} func (p *Parser) parseCall(operator *Term, offset int) (term *Term) { if !p.enter() { @@ -1978,7 +2109,7 @@ func (p *Parser) parseRef(head *Term, offset int) (term *Term) { term = p.parseRef(term, offset) } } - end = p.s.tokEnd + end = p.s.lastEnd return term case tokens.LBrack: p.scan() @@ -2042,7 +2173,6 @@ func (p *Parser) parseArray() (term *Term) { // Does this represent a set comprehension or a set containing binary OR // call? We resolve the ambiguity by prioritizing comprehensions. head := p.parseTerm() - if head == nil { return nil } @@ -2286,7 +2416,7 @@ func (p *Parser) parseTermList(end tokens.Token, r []*Term) []*Term { } continue default: - p.illegal(fmt.Sprintf("expected %q or %q", tokens.Comma, end)) + p.illegal("expected %q or %q", tokens.Comma, end) return nil } } @@ -2316,12 +2446,12 @@ func (p *Parser) parseTermPairList(end tokens.Token, r [][2]*Term) [][2]*Term { } continue default: - p.illegal(fmt.Sprintf("expected %q or %q", tokens.Comma, end)) + p.illegal("expected %q or %q", tokens.Comma, end) return nil } } default: - p.illegal(fmt.Sprintf("expected %q", tokens.Colon)) + p.illegal("expected %q", tokens.Colon) return nil } } @@ -2331,7 +2461,8 @@ func (p *Parser) parseTermPairList(end tokens.Token, r [][2]*Term) [][2]*Term { func (p *Parser) parseTermOp(values ...tokens.Token) *Term { if slices.Contains(values, p.s.tok) { - r := RefTerm(VarTerm(p.s.tok.String()).SetLocation(p.s.Loc())).SetLocation(p.s.Loc()) + loc := p.s.Loc() + r := RefTerm(VarTerm(p.s.tok.String()).SetLocation(loc)).SetLocation(loc) p.scan() return r } @@ -2341,11 +2472,12 @@ func (p *Parser) parseTermOp(values ...tokens.Token) *Term { func (p *Parser) parseTermOpName(ref Ref, values ...tokens.Token) *Term { if slices.Contains(values, p.s.tok) { cp := ref.Copy() + loc := p.s.Loc() for _, r := range cp { - r.SetLocation(p.s.Loc()) + r.SetLocation(loc) } t := RefTerm(cp...) - t.SetLocation(p.s.Loc()) + t.SetLocation(loc) p.scan() return t } @@ -2353,48 +2485,69 @@ func (p *Parser) parseTermOpName(ref Ref, values ...tokens.Token) *Term { } func (p *Parser) parseVar() *Term { - - s := p.s.lit - - term := VarTerm(s).SetLocation(p.s.Loc()) - - // Update wildcard values with unique identifiers - if term.Equal(Wildcard) { - term.Value = Var(p.genwildcard()) + if p.s.lit == WildcardString { + // Update wildcard values with unique identifiers + return NewTerm(p.genwildcard()).SetLocation(p.s.Loc()) } - return term + return VarTerm(p.s.lit).SetLocation(p.s.Loc()) } -func (p *Parser) genwildcard() string { - c := p.s.wildcard +func (p *Parser) genwildcard() Value { + var v Value + if p.s.wildcard < len(preAllocWildcards) { + v = preAllocWildcards[p.s.wildcard] + } else { + v = Var(WildcardPrefix + strconv.Itoa(p.s.wildcard)) + } p.s.wildcard++ - return fmt.Sprintf("%v%d", WildcardPrefix, c) -} -func (p *Parser) error(loc *location.Location, reason string) { - p.errorf(loc, "%s", reason) + return v } -func (p *Parser) errorf(loc *location.Location, f string, a ...any) { - msg := strings.Builder{} - msg.WriteString(fmt.Sprintf(f, a...)) - - switch len(p.s.hints) { +func writeHints(msg *strings.Builder, hints []string) { + switch len(hints) { case 0: // nothing to do case 1: msg.WriteString(" (hint: ") - msg.WriteString(p.s.hints[0]) - msg.WriteRune(')') + msg.WriteString(hints[0]) + msg.WriteByte(')') default: msg.WriteString(" (hints: ") - for i, h := range p.s.hints { + for i, h := range hints { if i > 0 { msg.WriteString(", ") } msg.WriteString(h) } - msg.WriteRune(')') + msg.WriteByte(')') + } +} + +func (p *Parser) error(loc *location.Location, reason string) { + msg := reason + if len(p.s.hints) > 0 { + sb := &strings.Builder{} + sb.WriteString(reason) + writeHints(sb, p.s.hints) + msg = sb.String() + } + + p.s.errors = append(p.s.errors, &Error{ + Code: ParseErr, + Message: msg, + Location: loc, + Details: newParserErrorDetail(p.s.s.Bytes(), loc.Offset), + }) + p.s.hints = nil +} + +func (p *Parser) errorf(loc *location.Location, f string, a ...any) { + msg := &strings.Builder{} + fmt.Fprintf(msg, f, a...) + + if len(p.s.hints) > 0 { + writeHints(msg, p.s.hints) } p.s.errors = append(p.s.errors, &Error{ @@ -2406,28 +2559,25 @@ func (p *Parser) errorf(loc *location.Location, f string, a ...any) { p.s.hints = nil } -func (p *Parser) hint(f string, a ...any) { - p.s.hints = append(p.s.hints, fmt.Sprintf(f, a...)) +func (p *Parser) hint(s string) { + p.s.hints = append(p.s.hints, s) } func (p *Parser) illegal(note string, a ...any) { - tok := p.s.tok.String() - if p.s.tok == tokens.Illegal { p.errorf(p.s.Loc(), "illegal token") return } + tok := p.s.tok.String() + tokType := "token" - if tokens.IsKeyword(p.s.tok) { - tokType = "keyword" - } else if _, ok := allFutureKeywords[p.s.tok.String()]; ok { + if _, ok := allFutureKeywords[tok]; ok || tokens.IsKeyword(p.s.tok) { tokType = "keyword" } - note = fmt.Sprintf(note, a...) if len(note) > 0 { - p.errorf(p.s.Loc(), "unexpected %s %s: %s", tok, tokType, note) + p.errorf(p.s.Loc(), "unexpected %s %s: %s", tok, tokType, fmt.Sprintf(note, a...)) } else { p.errorf(p.s.Loc(), "unexpected %s %s", tok, tokType) } @@ -2437,15 +2587,17 @@ func (p *Parser) illegalToken() { p.illegal("") } +var noScanOptions []scanner.ScanOption + func (p *Parser) scan() { - p.doScan(true) + p.doScan(true, noScanOptions...) } func (p *Parser) scanWS() { - p.doScan(false) + p.doScan(false, noScanOptions...) } -func (p *Parser) doScan(skipws bool) { +func (p *Parser) doScan(skipws bool, scanOpts ...scanner.ScanOption) { // NOTE(tsandall): the last position is used to compute the "text" field for // complex AST nodes. Whitespace never affects the last position of an AST @@ -2458,7 +2610,7 @@ func (p *Parser) doScan(skipws bool) { var errs []scanner.Error for { var pos scanner.Position - p.s.tok, pos, p.s.lit, errs = p.s.s.Scan() + p.s.tok, pos, p.s.lit, errs = p.s.s.Scan(scanOpts...) p.s.tokEnd = pos.End p.s.loc.Row = pos.Row @@ -2513,12 +2665,10 @@ func (p *Parser) restore(s *state) { } func setLocRecursive(x any, loc *location.Location) { - NewGenericVisitor(func(x any) bool { - if node, ok := x.(Node); ok { - node.SetLoc(loc) - } + WalkNodes(x, func(n Node) bool { + n.SetLoc(loc) return false - }).Walk(x) + }) } func (p *Parser) setLoc(term *Term, loc *location.Location, offset, end int) *Term { @@ -2601,13 +2751,17 @@ type rawAnnotation struct { } type metadataParser struct { - buf *bytes.Buffer comments []*Comment + buf *bytes.Buffer loc *location.Location } -func newMetadataParser(loc *Location) *metadataParser { - return &metadataParser{loc: loc, buf: bytes.NewBuffer(nil)} +func (b *metadataParser) Reset(loc *location.Location) { + b.comments = b.comments[:0] + b.loc = loc + if b.buf != nil { + b.buf.Reset() + } } func (b *metadataParser) Append(c *Comment) { @@ -2618,14 +2772,12 @@ func (b *metadataParser) Append(c *Comment) { var yamlLineErrRegex = regexp.MustCompile(`^yaml:(?: unmarshal errors:[\n\s]*)? line ([[:digit:]]+):`) -func (b *metadataParser) Parse() (*Annotations, error) { - - var raw rawAnnotation - +func (b *metadataParser) Parse() (result *Annotations, err error) { if len(bytes.TrimSpace(b.buf.Bytes())) == 0 { return nil, errors.New("expected METADATA block, found whitespace") } + var raw rawAnnotation if err := yaml.Unmarshal(b.buf.Bytes(), &raw); err != nil { var comment *Comment match := yamlLineErrRegex.FindStringSubmatch(err.Error()) @@ -2648,13 +2800,14 @@ func (b *metadataParser) Parse() (*Annotations, error) { return nil, augmentYamlError(err, b.comments) } - var result Annotations - result.comments = b.comments - result.Scope = raw.Scope - result.Entrypoint = raw.Entrypoint - result.Title = raw.Title - result.Description = raw.Description - result.Organizations = raw.Organizations + result = &Annotations{ + comments: b.comments, + Scope: raw.Scope, + Entrypoint: raw.Entrypoint, + Title: raw.Title, + Description: raw.Description, + Organizations: raw.Organizations, + } for _, v := range raw.RelatedResources { rr, err := parseRelatedResource(v) @@ -2736,32 +2889,30 @@ func (b *metadataParser) Parse() (*Annotations, error) { result.Authors = append(result.Authors, author) } - result.Custom = make(map[string]any) - for k, v := range raw.Custom { - val, err := convertYAMLMapKeyTypes(v, nil) - if err != nil { - return nil, err + if raw.Custom != nil { + result.Custom = make(map[string]any, len(raw.Custom)) + for k, v := range raw.Custom { + if result.Custom[k], err = convertYAMLMapKeyTypes(v, nil); err != nil { + return nil, err + } } - result.Custom[k] = val } result.Location = b.loc // recreate original text of entire metadata block for location text attribute - sb := strings.Builder{} - sb.WriteString("# METADATA\n") + original := bytes.TrimSuffix(b.buf.Bytes(), newlineBytes) + numLines := bytes.Count(original, newlineBytes) + 1 + preAlloc := len("# METADATA\n") + len(original) + numLines*2 // '# ' prefix added per line - lines := bytes.Split(b.buf.Bytes(), []byte{'\n'}) + result.Location.Text = append(make([]byte, 0, preAlloc), "# METADATA\n"...) - for _, line := range lines[:len(lines)-1] { - sb.WriteString("# ") - sb.Write(line) - sb.WriteByte('\n') + for line := range bytes.SplitAfterSeq(original, newlineBytes) { + result.Location.Text = append(result.Location.Text, "# "...) + result.Location.Text = append(result.Location.Text, line...) } - result.Location.Text = []byte(strings.TrimSuffix(sb.String(), "\n")) - - return &result, nil + return result, err } // augmentYamlError augments a YAML error with hints intended to help the user figure out the cause of an otherwise @@ -2770,30 +2921,29 @@ func (b *metadataParser) Parse() (*Annotations, error) { func augmentYamlError(err error, comments []*Comment) error { // Adding hints for when key/value ':' separator isn't suffixed with a legal YAML space symbol for _, comment := range comments { - txt := string(comment.Text) - parts := strings.Split(txt, ":") - if len(parts) > 1 { - parts = parts[1:] - var invalidSpaces []string - for partIndex, part := range parts { - if len(part) == 0 && partIndex == len(parts)-1 { - invalidSpaces = []string{} - break - } - - r, _ := utf8.DecodeRuneInString(part) - if r == ' ' || r == '\t' { - invalidSpaces = []string{} - break - } + if bytes.IndexByte(comment.Text, ':') == -1 { + continue + } + parts := bytes.Split(comment.Text, []byte{':'})[1:] - invalidSpaces = append(invalidSpaces, fmt.Sprintf("%+q", r)) + var invalidSpaces []string + for partIndex, part := range parts { + if len(part) == 0 && partIndex == len(parts)-1 { + break } - if len(invalidSpaces) > 0 { - err = fmt.Errorf( - "%s\n Hint: on line %d, symbol(s) %v immediately following a key/value separator ':' is not a legal yaml space character", - err.Error(), comment.Location.Row, invalidSpaces) + + r, _ := utf8.DecodeRune(part) + if r == ' ' || r == '\t' { + break } + + invalidSpaces = append(invalidSpaces, fmt.Sprintf("%+q", r)) + } + if len(invalidSpaces) > 0 { + err = fmt.Errorf( + "%s\n Hint: on line %d, symbol(s) %v immediately following a"+ + " key/value separator ':' is not a legal yaml space character", + err.Error(), comment.Location.Row, invalidSpaces) } } return err @@ -2911,7 +3061,7 @@ func parseAuthorString(s string) (*AuthorAnnotation, error) { if len(trailing) >= len(emailPrefix)+len(emailSuffix) && strings.HasPrefix(trailing, emailPrefix) && strings.HasSuffix(trailing, emailSuffix) { email = trailing[len(emailPrefix):] - email = email[0 : len(email)-len(emailSuffix)] + email = email[:len(email)-len(emailSuffix)] namePartCount -= 1 } @@ -2999,10 +3149,7 @@ func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]toke return } - kwds := make([]string, 0, len(allowedFutureKeywords)) - for k := range allowedFutureKeywords { - kwds = append(kwds, k) - } + kwds := util.Keys(allowedFutureKeywords) switch len(path) { case 2: // all keywords imported, nothing to do @@ -3052,10 +3199,7 @@ func (p *Parser) regoV1Import(imp *Import) { } // import all future keywords with the rego.v1 import - kwds := make([]string, 0, len(futureKeywordsV0)) - for k := range futureKeywordsV0 { - kwds = append(kwds, k) - } + kwds := util.Keys(futureKeywordsV0) p.s.s.SetRegoV1Compatible() for _, kw := range kwds { diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/parser_ext.go b/vendor/github.com/open-policy-agent/opa/v1/ast/parser_ext.go index f3d4e0d188f9..ab3de33a1f82 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/parser_ext.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/parser_ext.go @@ -11,7 +11,6 @@ package ast import ( - "bytes" "errors" "fmt" "slices" @@ -625,10 +624,9 @@ func ParseStatements(filename, input string) ([]Statement, []*Comment, error) { // ParseStatementsWithOpts returns a slice of parsed statements. This is the // default return value from the parser. func ParseStatementsWithOpts(filename, input string, popts ParserOptions) ([]Statement, []*Comment, error) { - parser := NewParser(). WithFilename(filename). - WithReader(bytes.NewBufferString(input)). + WithReader(strings.NewReader(input)). WithProcessAnnotation(popts.ProcessAnnotation). WithFutureKeywords(popts.FutureKeywords...). WithAllFutureKeywords(popts.AllFutureKeywords). @@ -638,7 +636,6 @@ func ParseStatementsWithOpts(filename, input string, popts ParserOptions) ([]Sta withUnreleasedKeywords(popts.unreleasedKeywords) stmts, comments, errs := parser.Parse() - if len(errs) > 0 { return nil, nil, errs } @@ -647,7 +644,6 @@ func ParseStatementsWithOpts(filename, input string, popts ParserOptions) ([]Sta } func parseModule(filename string, stmts []Statement, comments []*Comment, regoCompatibilityMode RegoVersion) (*Module, error) { - if len(stmts) == 0 { return nil, NewError(ParseErr, &Location{File: filename}, "empty module") } @@ -662,23 +658,21 @@ func parseModule(filename string, stmts []Statement, comments []*Comment, regoCo mod := &Module{ Package: pkg, - stmts: stmts, + // The comments slice only holds comments that were not their own statements. + Comments: comments, + stmts: stmts, } - // 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) { case *Import: mod.Imports = append(mod.Imports, stmt) - if mod.regoVersion == RegoV0 && Compare(stmt.Path.Value, RegoV1CompatibleRef) == 0 { + if mod.regoVersion == RegoV0 && RegoV1CompatibleRef.Equal(stmt.Path.Value) { mod.regoVersion = RegoV0CompatV1 } case *Rule: diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/performance.go b/vendor/github.com/open-policy-agent/opa/v1/ast/performance.go index 3e285f963df9..564ee255d108 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/performance.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/performance.go @@ -4,6 +4,7 @@ package ast import ( + "encoding" "strings" "sync" ) @@ -83,3 +84,16 @@ func BuiltinNameFromRef(ref Ref) (string, bool) { return "", false } + +func AppendDelimeted[T encoding.TextAppender](buf []byte, appenders []T, delim string) ([]byte, error) { + for i, item := range appenders { + if i > 0 { + buf = append(buf, delim...) + } + var err error + if buf, err = item.AppendText(buf); err != nil { + return nil, err + } + } + return buf, nil +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/policy.go b/vendor/github.com/open-policy-agent/opa/v1/ast/policy.go index 62c82f51ec0c..632b5aa6d5e7 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/policy.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/policy.go @@ -86,7 +86,11 @@ var ReservedVars = NewVarSet( ) // Wildcard represents the wildcard variable as defined in the language. -var Wildcard = &Term{Value: Var("_")} +var ( + WildcardString = "_" + WildcardValue Value = Var(WildcardString) + Wildcard = &Term{Value: WildcardValue} +) // WildcardPrefix is the special character that all wildcard variables are // prefixed with when the statement they are contained in is parsed. @@ -367,40 +371,8 @@ func (mod *Module) Equal(other *Module) bool { } func (mod *Module) String() string { - byNode := map[Node][]*Annotations{} - for _, a := range mod.Annotations { - byNode[a.node] = append(byNode[a.node], a) - } - - appendAnnotationStrings := func(buf []string, node Node) []string { - if as, ok := byNode[node]; ok { - for i := range as { - buf = append(buf, "# METADATA") - buf = append(buf, "# "+as[i].String()) - } - } - return buf - } - - buf := []string{} - buf = appendAnnotationStrings(buf, mod.Package) - buf = append(buf, mod.Package.String()) - - if len(mod.Imports) > 0 { - buf = append(buf, "") - for _, imp := range mod.Imports { - buf = appendAnnotationStrings(buf, imp) - buf = append(buf, imp.String()) - } - } - if len(mod.Rules) > 0 { - buf = append(buf, "") - for _, rule := range mod.Rules { - buf = appendAnnotationStrings(buf, rule) - buf = append(buf, rule.stringWithOpts(toStringOpts{regoVersion: mod.regoVersion})) - } - } - return strings.Join(buf, "\n") + buf, _ := mod.AppendText(make([]byte, 0, mod.StringLength())) + return util.ByteSliceToString(buf) } // RuleSet returns a RuleSet containing named rules in the mod. @@ -469,7 +441,8 @@ func (c *Comment) SetLoc(loc *Location) { } func (c *Comment) String() string { - return "#" + string(c.Text) + buf, _ := c.AppendText(make([]byte, 0, c.StringLength())) + return util.ByteSliceToString(buf) } // Copy returns a deep copy of c. @@ -519,16 +492,8 @@ func (pkg *Package) SetLoc(loc *Location) { } func (pkg *Package) String() string { - if pkg == nil { - return "" - } else if len(pkg.Path) <= 1 { - return fmt.Sprintf("package ", pkg.Path) - } - // Omit head as all packages have the DefaultRootDocument prepended at parse time. - path := make(Ref, len(pkg.Path)-1) - path[0] = VarTerm(string(pkg.Path[1].Value.(String))) - copy(path[1:], pkg.Path[2:]) - return fmt.Sprintf("package %v", path) + buf, _ := pkg.AppendText(make([]byte, 0, pkg.StringLength())) + return util.ByteSliceToString(buf) } func (pkg *Package) MarshalJSON() ([]byte, error) { @@ -615,7 +580,7 @@ func (imp *Import) SetLoc(loc *Location) { // document. This is the alias if defined otherwise the last element in the // path. func (imp *Import) Name() Var { - if len(imp.Alias) != 0 { + if imp.Alias != "" { return imp.Alias } switch v := imp.Path.Value.(type) { @@ -631,11 +596,8 @@ 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()) - } - return strings.Join(buf, " ") + buf, _ := imp.AppendText(make([]byte, 0, imp.StringLength())) + return util.ByteSliceToString(buf) } func (imp *Import) MarshalJSON() ([]byte, error) { @@ -726,6 +688,7 @@ func (rule *Rule) SetLoc(loc *Location) { // Path returns a ref referring to the document produced by this rule. If rule // is not contained in a module, this function panics. +// // Deprecated: Poor handling of ref rules. Use `(*Rule).Ref()` instead. func (rule *Rule) Path() Ref { if rule.Module == nil { @@ -745,11 +708,12 @@ func (rule *Rule) Ref() Ref { } func (rule *Rule) String() string { - regoVersion := DefaultRegoVersion + opts := toStringOpts{} if rule.Module != nil { - regoVersion = rule.Module.RegoVersion() + opts.regoVersion = rule.Module.RegoVersion() } - return rule.stringWithOpts(toStringOpts{regoVersion: regoVersion}) + buf, _ := rule.appendWithOpts(opts, make([]byte, 0, rule.stringLengthWithOpts(opts))) + return util.ByteSliceToString(buf) } type toStringOpts struct { @@ -763,80 +727,46 @@ func (o toStringOpts) RegoVersion() RegoVersion { return o.regoVersion } -func (rule *Rule) stringWithOpts(opts toStringOpts) string { - buf := []string{} - if rule.Default { - buf = append(buf, "default") - } - buf = append(buf, rule.Head.stringWithOpts(opts)) - if !rule.Default { - switch opts.RegoVersion() { - case RegoV1, RegoV0CompatV1: - buf = append(buf, "if") - } - buf = append(buf, "{", rule.Body.String(), "}") - } - if rule.Else != nil { - buf = append(buf, rule.Else.elseString(opts)) - } - return strings.Join(buf, " ") -} - func (rule *Rule) isFunction() bool { return len(rule.Head.Args) > 0 } +// ruleJSON is used for JSON serialization of Rule to avoid map allocation overhead. +// Field order is alphabetical to match previous map-based output. +type ruleJSON struct { + Annotations []*Annotations `json:"annotations,omitempty"` + Body Body `json:"body"` + Default bool `json:"default,omitempty"` + Else *Rule `json:"else,omitempty"` + Head *Head `json:"head"` + Location *Location `json:"location,omitempty"` +} + func (rule *Rule) MarshalJSON() ([]byte, error) { - data := map[string]any{ - "head": rule.Head, - "body": rule.Body, + data := ruleJSON{ + Head: rule.Head, + Body: rule.Body, } if rule.Default { - data["default"] = true + data.Default = true } if rule.Else != nil { - data["else"] = rule.Else + data.Else = rule.Else } if astJSON.GetOptions().MarshalOptions.IncludeLocation.Rule { - if rule.Location != nil { - data["location"] = rule.Location - } + data.Location = rule.Location } if len(rule.Annotations) != 0 { - data["annotations"] = rule.Annotations + data.Annotations = rule.Annotations } return json.Marshal(data) } -func (rule *Rule) elseString(opts toStringOpts) string { - var buf []string - - buf = append(buf, "else") - - value := rule.Head.Value - if value != nil { - buf = append(buf, "=", value.String()) - } - - switch opts.RegoVersion() { - case RegoV1, RegoV0CompatV1: - buf = append(buf, "if") - } - - buf = append(buf, "{", rule.Body.String(), "}") - - if rule.Else != nil { - buf = append(buf, rule.Else.elseString(opts)) - } - - return strings.Join(buf, " ") -} - // NewHead returns a new Head object. If args are provided, the first will be // used for the key and the second will be used for the value. func NewHead(name Var, args ...*Term) *Head { @@ -981,6 +911,7 @@ func (head *Head) Copy() *Head { cpy.Key = head.Key.Copy() cpy.Value = head.Value.Copy() cpy.keywords = nil + cpy.Assign = head.Assign return &cpy } @@ -994,37 +925,8 @@ func (head *Head) String() string { } func (head *Head) stringWithOpts(opts toStringOpts) string { - buf := strings.Builder{} - buf.WriteString(head.Ref().String()) - containsAdded := false - - switch { - case len(head.Args) != 0: - buf.WriteString(head.Args.String()) - case len(head.Reference) == 1 && head.Key != nil: - switch opts.RegoVersion() { - case RegoV0: - buf.WriteRune('[') - buf.WriteString(head.Key.String()) - buf.WriteRune(']') - default: - containsAdded = true - buf.WriteString(" contains ") - buf.WriteString(head.Key.String()) - } - } - if head.Value != nil { - if head.Assign { - buf.WriteString(" := ") - } else { - buf.WriteString(" = ") - } - buf.WriteString(head.Value.String()) - } else if !containsAdded && head.Name == "" && head.Key != nil { - buf.WriteString(" contains ") - buf.WriteString(head.Key.String()) - } - return buf.String() + buf, _ := head.appendWithOpts(opts, make([]byte, 0, head.stringLengthWithOpts(opts))) + return util.ByteSliceToString(buf) } func (head *Head) MarshalJSON() ([]byte, error) { @@ -1087,7 +989,7 @@ func (head *Head) HasDynamicRef() bool { // Copy returns a deep copy of a. func (a Args) Copy() Args { - cpy := Args{} + cpy := make(Args, 0, len(a)) for _, t := range a { cpy = append(cpy, t.Copy()) } @@ -1095,11 +997,8 @@ func (a Args) Copy() Args { } func (a Args) String() string { - buf := make([]string, 0, len(a)) - for _, t := range a { - buf = append(buf, t.String()) - } - return "(" + strings.Join(buf, ", ") + ")" + buf, _ := a.AppendText(make([]byte, 0, a.StringLength())) + return util.ByteSliceToString(buf) } // Loc returns the Location of a. @@ -1232,11 +1131,12 @@ func (body Body) SetLoc(loc *Location) { } func (body Body) String() string { - buf := make([]string, 0, len(body)) - for _, v := range body { - buf = append(buf, v.String()) - } - return strings.Join(buf, "; ") + buf, _ := body.AppendText(make([]byte, 0, body.StringLength())) + return util.ByteSliceToString(buf) +} + +func (body Body) AppendText(buf []byte) ([]byte, error) { + return AppendDelimeted(buf, body, "; ") } // Vars returns a VarSet containing variables in body. The params can be set to @@ -1547,50 +1447,41 @@ func (expr *Expr) SetLoc(loc *Location) { } func (expr *Expr) String() string { - buf := make([]string, 0, 2+len(expr.With)) - if expr.Negated { - buf = append(buf, "not") - } - switch t := expr.Terms.(type) { - case []*Term: - if expr.IsEquality() && validEqAssignArgCount(expr) { - buf = append(buf, fmt.Sprintf("%v %v %v", t[1], Equality.Infix, t[2])) - } else { - buf = append(buf, Call(t).String()) - } - case fmt.Stringer: - buf = append(buf, t.String()) - } - - for i := range expr.With { - buf = append(buf, expr.With[i].String()) - } + buf, _ := expr.AppendText(make([]byte, 0, expr.StringLength())) + return util.ByteSliceToString(buf) +} - return strings.Join(buf, " ") +// exprJSON is used for JSON serialization of Expr to avoid map allocation overhead. +// Field order is alphabetical to match previous map-based output. +type exprJSON struct { + Generated bool `json:"generated,omitempty"` + Index int `json:"index"` + Location *Location `json:"location,omitempty"` + Negated bool `json:"negated,omitempty"` + Terms any `json:"terms"` + With []*With `json:"with,omitempty"` } func (expr *Expr) MarshalJSON() ([]byte, error) { - data := map[string]any{ - "terms": expr.Terms, - "index": expr.Index, + data := exprJSON{ + Index: expr.Index, + Terms: expr.Terms, } if len(expr.With) > 0 { - data["with"] = expr.With + data.With = expr.With } if expr.Generated { - data["generated"] = true + data.Generated = true } if expr.Negated { - data["negated"] = true + data.Negated = true } if astJSON.GetOptions().MarshalOptions.IncludeLocation.Expr { - if expr.Location != nil { - data["location"] = expr.Location - } + data.Location = expr.Location } return json.Marshal(data) @@ -1660,17 +1551,8 @@ func visitCogeneratedExprs(expr *Expr, f func(*Expr) bool) { } func (d *SomeDecl) String() string { - if call, ok := d.Symbols[0].Value.(Call); ok { - if len(call) == 4 { - return "some " + call[1].String() + ", " + call[2].String() + " in " + call[3].String() - } - return "some " + call[1].String() + " in " + call[2].String() - } - buf := make([]string, len(d.Symbols)) - for i := range buf { - buf[i] = d.Symbols[i].String() - } - return "some " + strings.Join(buf, ", ") + buf, _ := d.AppendText(make([]byte, 0, d.StringLength())) + return util.ByteSliceToString(buf) } // SetLoc sets the Location on d. @@ -1789,7 +1671,8 @@ func (q *Every) MarshalJSON() ([]byte, error) { } func (w *With) String() string { - return "with " + w.Target.String() + " as " + w.Value.String() + buf, _ := w.AppendText(make([]byte, 0, w.StringLength())) + return util.ByteSliceToString(buf) } // Equal returns true if this With is equals the other With. @@ -1846,16 +1729,22 @@ func (w *With) SetLoc(loc *Location) { w.Location = loc } +// withJSON is used for JSON serialization of With to avoid map allocation overhead. +// Field order is alphabetical to match previous map-based output. +type withJSON struct { + Location *Location `json:"location,omitempty"` + Target *Term `json:"target"` + Value *Term `json:"value"` +} + func (w *With) MarshalJSON() ([]byte, error) { - data := map[string]any{ - "target": w.Target, - "value": w.Value, + data := withJSON{ + Target: w.Target, + Value: w.Value, } if astJSON.GetOptions().MarshalOptions.IncludeLocation.With { - if w.Location != nil { - data["location"] = w.Location - } + data.Location = w.Location } return json.Marshal(data) diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/policy_appenders.go b/vendor/github.com/open-policy-agent/opa/v1/ast/policy_appenders.go new file mode 100644 index 000000000000..c7e50cf3c3a1 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/policy_appenders.go @@ -0,0 +1,324 @@ +package ast + +import ( + "encoding" + "fmt" +) + +func (m *Module) AppendText(buf []byte) ([]byte, error) { + if m == nil { + return append(buf, ""...), nil + } + + var err error + + // NOTE(anderseknert): this DOES allocate still, and while that's unfortunate, + // we'll be better off dealing with that when we have v2 JSON in the stdlib than + // doing manual JSON marshalling (and string length calculations) here. + for _, annotations := range m.Annotations { + // rule annotations are attached to rules, so only check for package scoped ones here + if annotations.Scope == "package" || annotations.Scope == "subpackages" { + buf = append(buf, "# METADATA\n# "...) + buf = append(buf, annotations.String()...) + buf = append(buf, '\n') + } + } + + if buf, err = m.Package.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, '\n') + + if len(m.Imports) > 0 { + for _, imp := range m.Imports { + buf = append(buf, '\n') + if buf, err = imp.AppendText(buf); err != nil { + return nil, err + } + } + buf = append(buf, '\n') + } + + if len(m.Rules) > 0 { + for _, rule := range m.Rules { + buf = append(buf, '\n') + if buf, err = rule.appendWithOpts(toStringOpts{regoVersion: m.regoVersion}, buf); err != nil { + return nil, err + } + } + } + + return buf, nil +} + +func (pkg *Package) AppendText(buf []byte) ([]byte, error) { + var err error + if pkg == nil { + return append(buf, ""...), nil + } + if len(pkg.Path) <= 1 { + buf = append(buf, "package "...), nil + } + + buf = append(buf, "package "...) + + path := pkg.Path[1:] // omit "data" + + return path.AppendText(buf) +} + +func (imp *Import) AppendText(buf []byte) ([]byte, error) { + buf = append(buf, "import "...) + var err error + if buf, err = imp.Path.AppendText(buf); err != nil { + return nil, err + } + if imp.Alias != "" { + buf = append(buf, ' ', 'a', 's', ' ') + buf = append(buf, imp.Alias...) + } + return buf, nil +} + +func (r *Rule) AppendText(buf []byte) ([]byte, error) { + regoVersion := DefaultRegoVersion + if r.Module != nil { + regoVersion = r.Module.RegoVersion() + } + return r.appendWithOpts(toStringOpts{regoVersion: regoVersion}, buf) +} + +func (r *Rule) appendWithOpts(opts toStringOpts, buf []byte) ([]byte, error) { + // See note in [Module.AppendText] regarding annotations. + for _, annotations := range r.Annotations { + buf = append(buf, "# METADATA\n# "...) + buf = append(buf, annotations.String()...) + buf = append(buf, '\n') + } + + if r.Default { + buf = append(buf, "default "...) + } + + var err error + if buf, err = r.Head.appendWithOpts(opts, buf); err != nil { + return nil, err + } + + if !r.Default { + switch opts.RegoVersion() { + case RegoV1, RegoV0CompatV1: + buf = append(buf, " if { "...) + default: + buf = append(buf, " { "...) + } + if buf, err = r.Body.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, " }"...) + } + if r.Else != nil { + if buf, err = r.Else.appendElse(opts, buf); err != nil { + return nil, err + } + } + + return buf, nil +} + +func (r *Rule) appendElse(opts toStringOpts, buf []byte) ([]byte, error) { + buf = append(buf, " else "...) + + var err error + if r.Head.Value != nil { + buf = append(buf, "= "...) + if buf, err = r.Head.Value.AppendText(buf); err != nil { + return nil, err + } + } + + if v := opts.RegoVersion(); v == RegoV1 || v == RegoV0CompatV1 { + buf = append(buf, " if { "...) + } else { + buf = append(buf, " { "...) + } + if buf, err = r.Body.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, " }"...) + + if r.Else != nil { + if buf, err = r.Else.appendElse(opts, buf); err != nil { + return nil, err + } + } + + return buf, nil +} + +func (h *Head) AppendText(buf []byte) ([]byte, error) { + return h.appendWithOpts(toStringOpts{}, buf) +} + +func (h *Head) appendWithOpts(opts toStringOpts, buf []byte) ([]byte, error) { + var err error + if h.Reference == nil { + buf = append(buf, h.Name...) + } else { + if buf, err = h.Reference.AppendText(buf); err != nil { + return nil, err + } + } + + containsAdded := false + switch { + case len(h.Args) != 0: + if buf, err = h.Args.AppendText(buf); err != nil { + return nil, err + } + case len(h.Reference) == 1 && h.Key != nil: + switch opts.RegoVersion() { + case RegoV0: + buf = append(buf, '[') + if buf, err = h.Key.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, ']') + default: + if buf, err = h.Key.AppendText(append(buf, " contains "...)); err != nil { + return nil, err + } + containsAdded = true + } + } + if h.Value != nil { + if h.Assign { + buf = append(buf, " := "...) + } else { + buf = append(buf, " = "...) + } + if buf, err = h.Value.AppendText(buf); err != nil { + return nil, err + } + } else if !containsAdded && h.Name == "" && h.Key != nil { + if buf, err = h.Key.AppendText(append(buf, " contains "...)); err != nil { + return nil, err + } + } + return buf, nil +} + +func (a Args) AppendText(buf []byte) ([]byte, error) { + var err error + buf = append(buf, '(') + if buf, err = AppendDelimeted(buf, a, ", "); err != nil { + return nil, err + } + return append(buf, ')'), nil +} + +func (expr *Expr) AppendText(buf []byte) ([]byte, error) { + if expr.Negated { + buf = append(buf, "not "...) + } + + var err error + + switch t := expr.Terms.(type) { + case []*Term: + if expr.IsEquality() && validEqAssignArgCount(expr) { + if buf, err = t[1].AppendText(buf); err != nil { + return nil, err + } + buf = append(append(append(buf, ' '), Equality.Infix...), ' ') + if buf, err = t[2].AppendText(buf); err != nil { + return nil, err + } + } else if buf, err = Call(t).AppendText(buf); err != nil { + return nil, err + } + case encoding.TextAppender: + if buf, err = t.AppendText(buf); err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unsupported expr terms type: %T", expr.Terms) + } + + if len(expr.With) > 0 { + buf = append(buf, ' ') + } + + return AppendDelimeted(buf, expr.With, " ") +} + +func (w *With) AppendText(buf []byte) ([]byte, error) { + buf = append(buf, "with "...) + var err error + if buf, err = w.Target.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, " as "...) + if buf, err = w.Value.AppendText(buf); err != nil { + return nil, err + } + return buf, nil +} + +func (w *Every) AppendText(buf []byte) ([]byte, error) { + buf = append(buf, "every "...) + var err error + if w.Key != nil { + if buf, err = w.Key.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, ", "...) + } + if buf, err = w.Value.AppendText(buf); err == nil { + buf = append(buf, " in "...) + if buf, err = w.Domain.AppendText(buf); err == nil { + buf = append(buf, " { "...) + if buf, err = w.Body.AppendText(buf); err == nil { + buf = append(buf, " }"...) + } + } + } + return buf, err +} + +func (d *SomeDecl) AppendText(buf []byte) ([]byte, error) { + var err error + buf = append(buf, "some "...) + if call, ok := d.Symbols[0].Value.(Call); ok { + if buf, err = call[1].AppendText(buf); err != nil { + return nil, err + } + if len(call) == 3 { + buf = append(buf, " in "...) + } else { + buf = append(buf, ", "...) + } + if buf, err = call[2].AppendText(buf); err != nil { + return nil, err + } + if len(call) == 4 { + buf = append(buf, " in "...) + if buf, err = call[3].AppendText(buf); err != nil { + return nil, err + } + } + return buf, nil + } + + buf, err = AppendDelimeted(buf, d.Symbols, ", ") + + return buf, err +} + +func (c *Comment) AppendText(buf []byte) ([]byte, error) { + return append(append(buf, '#'), c.Text...), nil +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/rego_v1.go b/vendor/github.com/open-policy-agent/opa/v1/ast/rego_v1.go index a702d9294c27..db9e0f722c27 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/rego_v1.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/rego_v1.go @@ -27,13 +27,12 @@ func checkRootDocumentOverrides(node any) Errors { errors := Errors{} WalkRules(node, func(rule *Rule) bool { - var name string + name := rule.Head.Name if len(rule.Head.Reference) > 0 { - name = rule.Head.Reference[0].Value.(Var).String() - } else { - name = rule.Head.Name.String() + name = rule.Head.Reference[0].Value.(Var) } - if RootDocumentRefs.Contains(RefTerm(VarTerm(name))) { + + if ReservedVars.Contains(name) { errors = append(errors, NewError(CompileErr, rule.Location, "rules must not shadow %v (use a different rule name)", name)) } @@ -52,8 +51,8 @@ func checkRootDocumentOverrides(node any) Errors { if expr.IsAssignment() { // assign() can be called directly, so we need to assert its given first operand exists before checking its name. if nameOp := expr.Operand(0); nameOp != nil { - name := nameOp.String() - if RootDocumentRefs.Contains(RefTerm(VarTerm(name))) { + name := Var(nameOp.String()) + if ReservedVars.Contains(name) { errors = append(errors, NewError(CompileErr, expr.Location, "variables must not shadow %v (use a different variable name)", name)) } } @@ -65,26 +64,24 @@ func checkRootDocumentOverrides(node any) Errors { } func walkCalls(node any, f func(any) bool) { - vis := &GenericVisitor{func(x any) bool { - switch x := x.(type) { + vis := NewGenericVisitor(func(x any) bool { + switch y := x.(type) { case Call: return f(x) case *Expr: - if x.IsCall() { + if y.IsCall() { return f(x) } case *Head: // GenericVisitor doesn't walk the rule head ref - walkCalls(x.Reference, f) + walkCalls(y.Reference, f) } return false - }} + }) vis.Walk(node) } -func checkDeprecatedBuiltins(deprecatedBuiltinsMap map[string]struct{}, node any) Errors { - errs := make(Errors, 0) - +func checkDeprecatedBuiltins(deprecatedBuiltinsMap map[string]struct{}, node any) (errs Errors) { walkCalls(node, func(x any) bool { var operator string var loc *Location diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/slices.go b/vendor/github.com/open-policy-agent/opa/v1/ast/slices.go new file mode 100644 index 000000000000..5921ec0ca168 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/slices.go @@ -0,0 +1,15 @@ +// Copyright 2026 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 + +// CountFunc counts the number of items in a slice S that satisfy predicate function f. +func CountFunc[T any, S ~[]T](items S, f func(T) bool) (n int) { + for i := range items { + if f(items[i]) { + n++ + } + } + return n +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/string_length.go b/vendor/github.com/open-policy-agent/opa/v1/ast/string_length.go new file mode 100644 index 000000000000..fe53227d2403 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/string_length.go @@ -0,0 +1,351 @@ +package ast + +import ( + "fmt" + "unicode/utf8" + + "github.com/open-policy-agent/opa/v1/util" +) + +// StringLengther is an interface for types that can report their string length without +// actually constructing the string. This is useful for pre-allocating buffers, like those +// used in AppendText, strings.Builder, bytes.Buffer, etc. +type StringLengther interface { + StringLength() int +} + +// TermSliceStringLength returns the total string length of the given terms, as reported +// by the [StringLengther.StringLength] method implementation of each term's [Value]. The +// delimLen value will be added between each term's length to account for a delimiter, or +// no delimiter if delimLen is 0. +// Implementation note: this function is optimized for inlining, and just meets the threshold +// for that. Don't change without making sure that's still the case. +func TermSliceStringLength(terms []*Term, delimLen int) (n int) { + for i := range terms { + n += terms[i].StringLength() + delimLen + } + return max(n-delimLen, 0) +} + +func (t *Term) StringLength() int { + if sl, ok := t.Value.(StringLengther); ok { + return sl.StringLength() + } + + panic("expected all ast.Value types to implement StringLenghter interface, got: " + ValueName(t.Value)) +} + +func (s String) StringLength() int { + n := 2 // surrounding quotes + bs := util.StringToByteSlice(s) + for i := 0; i < len(bs); { + r, size := utf8.DecodeRune(bs[i:]) + switch r { + case '\\', '"': + n += 2 // escaped backslash or quote + case '\b', '\f', '\n', '\r', '\t': + n += 2 // escaped control characters + default: + if r < 0x20 { + n += 6 // unicode escape for other control characters + } else { + n += size // normal rune + } + } + i += size + } + return n +} + +func (n Number) StringLength() int { + return len(n) +} + +func (b Boolean) StringLength() int { + if b { + return 4 + } + return 5 +} + +func (Null) StringLength() int { + return 4 +} + +func (s *set) StringLength() int { + if s.Len() == 0 { + return 5 // set() + } + // surrounding {} + ", " for every element - 1 + return TermSliceStringLength(s.Slice(), 2) + 2 +} + +func (a *Array) StringLength() int { + if a.Len() == 0 { + return 2 // [] + } + // surrounding brackets + ", " for every element - 1 + return TermSliceStringLength(a.elems, 2) + 2 +} + +func (o *object) StringLength() (n int) { + if o.Len() == 0 { + return 2 // {} + } + // ": " for every item + ", " for every item - 1 + o.Foreach(func(key, value *Term) { + n += key.StringLength() + 4 + value.StringLength() // ": " and ", " + }) + return n // surrounding {} but also minus last ", " +} + +func (l *lazyObj) StringLength() int { + return l.force().(*object).StringLength() +} + +func (ts *TemplateString) StringLength() (n int) { + for _, p := range ts.Parts { + switch x := p.(type) { + case *Expr: + n += 2 + x.StringLength() // for {} + case *Term: + if s, ok := x.Value.(String); ok { + n += len(s) + countUnescapedLeftCurly(string(s)) + } else { + n += x.StringLength() + } + default: + n += 9 // + } + } + return n + 3 // $"" or $`` +} + +func (c Call) StringLength() int { + return c[0].StringLength() + 2 + TermSliceStringLength(c[1:], 2) +} + +func (r Ref) StringLength() (n int) { + rlen := len(r) + if rlen == 0 { + return 0 + } + + if s, ok := r[0].Value.(String); ok { + n = len(s) // first term should never be quoted + } else { + n = r[0].StringLength() + } + + if rlen == 1 { + return n + } + + for _, p := range r[1:] { + switch v := p.Value.(type) { + case String: + str := string(v) + if IsVarCompatibleString(str) && !IsKeyword(str) { + n += 1 + len(str) // dot + name + } else { + n += 2 + p.StringLength() // brackets + } + default: + n += 2 + p.StringLength() // brackets + } + } + return n +} + +func (v Var) StringLength() int { + if v.IsWildcard() { + return 1 + } + return len(v) +} + +func (s *SetComprehension) StringLength() int { + return s.Term.StringLength() + s.Body.StringLength() + 5 // {} and " | " +} + +func (a *ArrayComprehension) StringLength() int { + return a.Term.StringLength() + a.Body.StringLength() + 5 // [] and " | " +} + +func (o *ObjectComprehension) StringLength() (n int) { + n += o.Key.StringLength() + n += o.Value.StringLength() + n += o.Body.StringLength() + return n + 7 // "{}"", " | ", and ": " +} + +func (m *Module) StringLength() (n int) { + if m.Package != nil { + n += m.Package.StringLength() + 2 // newlines + } + + if len(m.Imports) > 0 { + for _, imp := range m.Imports { + n += imp.StringLength() + 1 // newline + } + } + + if len(m.Rules) > 0 { + for _, rule := range m.Rules { + n += rule.stringLengthWithOpts(toStringOpts{regoVersion: m.regoVersion}) + 1 // newline + } + } + + return n +} + +func (p *Package) StringLength() int { + if p == nil { + return 21 // + } + if len(p.Path) <= 1 { + return 25 + p.Path.StringLength() // // package + } + + return 8 + p.Path[1:].StringLength() // "package ..." +} + +func (i *Import) StringLength() (n int) { + n = 7 + i.Path.StringLength() // "import " and path + if i.Alias != "" { + n += 4 + i.Alias.StringLength() // " as " and alias + } + return n +} + +func (r *Rule) StringLength() int { + return r.stringLengthWithOpts(toStringOpts{}) +} + +func (r *Rule) stringLengthWithOpts(opts toStringOpts) int { + n := 0 + if r.Default { + n += 8 // "default " + } + n += r.Head.stringLengthWithOpts(opts) + if !r.Default { + switch opts.RegoVersion() { + case RegoV1, RegoV0CompatV1: + n += 6 // " if { " + default: + n += 3 // " { " + } + n += r.Body.StringLength() + 2 // body and closing " }" + } + if r.Else != nil { + n += r.Else.stringLengthWithOpts(opts) + } + return n +} + +func (h *Head) StringLength() int { + return h.stringLengthWithOpts(toStringOpts{}) +} + +func (h *Head) stringLengthWithOpts(opts toStringOpts) int { + n := h.Reference.StringLength() + containsAdded := false + switch { + case len(h.Args) != 0: + n += h.Args.StringLength() + case len(h.Reference) == 1 && h.Key != nil: + switch opts.RegoVersion() { + case RegoV0: + n += 2 + h.Key.StringLength() // for [] + default: + n += 10 + h.Key.StringLength() // " contains " + containsAdded = true + } + } + if h.Value != nil { + if h.Assign { + n += 4 // " := " + } else { + n += 3 // " = " + } + n += h.Value.StringLength() + } else if !containsAdded && h.Name == "" && h.Key != nil { + n += 10 + h.Key.StringLength() // " contains " + } + return n +} + +func (a Args) StringLength() (n int) { + n = 2 // () + for _, t := range a { + n += t.StringLength() + 2 // ", " + } + return n - 2 // minus last ", " +} + +func (b Body) StringLength() (n int) { + for _, expr := range b { + n += expr.StringLength() + 2 // "; " + } + return max(n-2, 0) // minus last "; " (if `n` isn't 0) +} + +func (e *Expr) StringLength() (n int) { + if e.Negated { + n += 4 // "not " + } + switch terms := e.Terms.(type) { + case []*Term: + if e.IsEquality() && validEqAssignArgCount(e) { + n += terms[1].StringLength() + len(Equality.Infix) + terms[2].StringLength() + 2 // spaces around = + } else { + n += Call(terms).StringLength() + } + case StringLengther: + n += terms.StringLength() + default: + panic(fmt.Sprintf("string length estimation not implemented for type: %T", e.Terms)) + } + + for _, w := range e.With { + n += w.StringLength() + 1 // space before with + } + + return n +} + +func (w *With) StringLength() int { + return w.Target.StringLength() + w.Value.StringLength() + 9 // "with " and " as " +} + +func (e *Every) StringLength() int { + n := 6 // "every " + if e.Key != nil { + n += e.Key.StringLength() + 2 // ", " + } + n += e.Value.StringLength() + 4 // " in " + n += e.Domain.StringLength() + 3 // " { " + n += e.Body.StringLength() + 2 // " }" + return n +} + +func (s *SomeDecl) StringLength() int { + n := 5 // "some " + if call, ok := s.Symbols[0].Value.(Call); ok { + n += 4 // " in " + n += call[1].StringLength() + if len(call) == 4 { + n += 2 // ", " + } + n += call[2].StringLength() + if len(call) == 4 { + n += call[3].StringLength() + } + return n + } + return n + TermSliceStringLength(s.Symbols, 2) +} + +func (c *Comment) StringLength() int { + return 1 + len(c.Text) // '#' + text +} 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 index 84475224126d..72ec03f8cc2e 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/strings.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/strings.go @@ -48,6 +48,8 @@ func ValueName(x Value) string { return "objectcomprehension" case *SetComprehension: return "setcomprehension" + case *TemplateString: + return "templatestring" } 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 index 82977c836bf7..500bb073cf5d 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/syncpools.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/syncpools.go @@ -1,53 +1,31 @@ package ast import ( - "strings" + "bytes" "sync" -) -type termPtrPool struct { - pool sync.Pool -} - -type stringBuilderPool struct { - pool sync.Pool -} + "github.com/open-policy-agent/opa/v1/util" +) -type indexResultPool struct { - pool sync.Pool -} +var ( + TermPtrPool = util.NewSyncPool[Term]() + BytesReaderPool = util.NewSyncPool[bytes.Reader]() + IndexResultPool = util.NewSyncPool[IndexResult]() + + // Needs custom pool because of custom Put logic. + varVisitorPool = &vvPool{ + pool: sync.Pool{ + New: func() any { + return NewVarVisitor() + }, + }, + } +) type vvPool 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) - } -} - func (p *vvPool) Get() *VarVisitor { return p.pool.Get().(*VarVisitor) } @@ -58,35 +36,3 @@ func (p *vvPool) Put(vv *VarVisitor) { p.pool.Put(vv) } } - -var TermPtrPool = &termPtrPool{ - pool: sync.Pool{ - New: func() any { - return &Term{} - }, - }, -} - -var sbPool = &stringBuilderPool{ - pool: sync.Pool{ - New: func() any { - return &strings.Builder{} - }, - }, -} - -var varVisitorPool = &vvPool{ - pool: sync.Pool{ - New: func() any { - return NewVarVisitor() - }, - }, -} - -var IndexResultPool = &indexResultPool{ - pool: sync.Pool{ - New: func() any { - return &IndexResult{} - }, - }, -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/term.go b/vendor/github.com/open-policy-agent/opa/v1/ast/term.go index 18f8a423d9e2..436b22eb2acd 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/term.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/term.go @@ -2,7 +2,6 @@ // Use of this source code is governed by an Apache2 // license that can be found in the LICENSE file. -// nolint: deadcode // Public API. package ast import ( @@ -13,7 +12,6 @@ import ( "io" "math" "net/url" - "regexp" "slices" "strconv" "strings" @@ -26,7 +24,22 @@ import ( "github.com/open-policy-agent/opa/v1/util" ) -var errFindNotFound = errors.New("find: not found") +// maxBindingsEstimate is the cap for binding count estimates in comprehensions. +// This value aligns with maxLinearScan in topdown/bindings.go. +const maxBindingsEstimate = 16 + +// EstimateBodyBindingCount returns an estimate of the number of bindings needed +// for evaluating a comprehension body. It uses the body length as a heuristic, +// capped at maxBindingsEstimate. +func EstimateBodyBindingCount(body Body) (estimate int) { + return min(len(body), maxBindingsEstimate) +} + +var ( + NullValue Value = Null{} + + errFindNotFound = errors.New("find: not found") +) // Location records a position in source code. type Location = location.Location @@ -44,12 +57,15 @@ func NewLocation(text []byte, file string, row int, col int) *Location { // - Variables, References // - Array, Set, and Object Comprehensions // - Calls +// - Template Strings type Value interface { Compare(other Value) int // Compare returns <0, 0, or >0 if this Value is less than, equal to, or greater than other, respectively. Find(path Ref) (Value, error) // Find returns value referred to by path or an error if path is not found. Hash() int // Returns hash code of the value. IsGround() bool // IsGround returns true if this value is not a variable or contains no variables. String() string // String returns a human readable string representation of the value. + + StringLengther // All Values must be able to report their string length during optimization. } // InterfaceToValue converts a native Go value x to a Value. @@ -352,6 +368,8 @@ func (term *Term) Copy() *Term { cpy.Value = v.Copy() case *SetComprehension: cpy.Value = v.Copy() + case *TemplateString: + cpy.Value = v.Copy() case Call: cpy.Value = v.Copy() } @@ -405,19 +423,24 @@ func (term *Term) IsGround() bool { return term.Value.IsGround() } +// termJSON is used to serialize Term to JSON without map allocation. +type termJSON struct { + Location *Location `json:"location,omitempty"` + Type string `json:"type"` + Value Value `json:"value"` +} + // 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]any{ - "type": ValueName(term.Value), - "value": term.Value, + d := termJSON{ + Type: ValueName(term.Value), + Value: term.Value, } jsonOptions := astJSON.GetOptions().MarshalOptions if jsonOptions.IncludeLocation.Term { - if term.Location != nil { - d["location"] = term.Location - } + d.Location = term.Location } return json.Marshal(d) } @@ -457,7 +480,17 @@ func (term *Term) Vars() VarSet { } // IsConstant returns true if the AST value is constant. +// Note that this is only a shallow check as we currently don't have a real +// notion of constant "vars" in the AST implementation. Meaning that while we could +// derive that a reference to a constant value is also constant, we currently don't. func IsConstant(v Value) bool { + switch v.(type) { + case Null, Boolean, Number, String: + return true + case Var, Ref, *ArrayComprehension, *ObjectComprehension, *SetComprehension, Call: + return false + } + found := false vis := GenericVisitor{ func(x any) bool { @@ -532,8 +565,6 @@ 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: NullValue} @@ -651,8 +682,9 @@ func NumberTerm(n json.Number) *Term { } // IntNumberTerm creates a new Term with an integer Number value. +// For values between -1 and 512, returns a cached Term to reduce allocations. func IntNumberTerm(i int) *Term { - return &Term{Value: newIntNumberValue(i)} + return internedIntNumberTerm(i) } // UIntNumberTerm creates a new Term with an unsigned integer Number value. @@ -819,12 +851,159 @@ func (str String) Hash() int { return int(xxhash.Sum64String(string(str))) } +type TemplateString struct { + Parts []Node `json:"parts"` + MultiLine bool `json:"multi_line"` +} + +func (ts *TemplateString) Copy() *TemplateString { + cpy := &TemplateString{MultiLine: ts.MultiLine, Parts: make([]Node, len(ts.Parts))} + for i, p := range ts.Parts { + switch v := p.(type) { + case *Expr: + cpy.Parts[i] = v.Copy() + case *Term: + cpy.Parts[i] = v.Copy() + } + } + return cpy +} + +func (ts *TemplateString) Equal(other Value) bool { + if o, ok := other.(*TemplateString); ok && ts.MultiLine == o.MultiLine && len(ts.Parts) == len(o.Parts) { + for i, p := range ts.Parts { + switch v := p.(type) { + case *Expr: + if ope, ok := o.Parts[i].(*Expr); !ok || !v.Equal(ope) { + return false + } + case *Term: + if opt, ok := o.Parts[i].(*Term); !ok || !v.Equal(opt) { + return false + } + default: + return false + } + } + return true + } + return false +} + +func (ts *TemplateString) Compare(other Value) int { + if ots, ok := other.(*TemplateString); ok { + if ts.MultiLine != ots.MultiLine { + if !ts.MultiLine { + return -1 + } + return 1 + } + + if len(ts.Parts) != len(ots.Parts) { + return len(ts.Parts) - len(ots.Parts) + } + + for i := range ts.Parts { + if cmp := Compare(ts.Parts[i], ots.Parts[i]); cmp != 0 { + return cmp + } + } + + return 0 + } + return Compare(ts, other) +} + +func (ts *TemplateString) Find(path Ref) (Value, error) { + if len(path) == 0 { + return ts, nil + } + return nil, errFindNotFound +} + +func (ts *TemplateString) Hash() int { + hash := 0 + for _, p := range ts.Parts { + switch x := p.(type) { + case *Expr: + hash += x.Hash() + case *Term: + hash += x.Value.Hash() + default: + panic(fmt.Sprintf("invalid template part type %T", p)) + } + } + return hash +} + +func (*TemplateString) IsGround() bool { + return false +} + +func (ts *TemplateString) String() string { + buf, _ := ts.AppendText(make([]byte, 0, ts.StringLength())) + return util.ByteSliceToString(buf) +} + +func TemplateStringTerm(multiLine bool, parts ...Node) *Term { + return &Term{Value: &TemplateString{MultiLine: multiLine, Parts: parts}} +} + +// EscapeTemplateStringStringPart escapes unescaped left curly braces in s - i.e "{" becomes "\{". +// The internal representation of string terms within a template string does **NOT** +// treat '{' as special, but expects code dealing with template strings to escape them when +// required, such as when serializing the complete template string. Code that programmatically +// constructs template strings should not pre-escape left curly braces in string term parts. +// +// // TODO(anders): a future optimization would be to combine this with the other escaping done +// // for strings (e.g. escaping quotes, backslashes, and JSON control characters) in a single operation +// // to avoid multiple passes and allocations over the same string. That's currently done by +// // strconv.Quote, so we would need to re-implement that logic in code of our own. +// // NOTE(anders): I would love to come up with a better name for this component than +// // "TemplateStringStringPart".. +func EscapeTemplateStringStringPart(s string) string { + numUnescaped := countUnescapedLeftCurly(s) + if numUnescaped == 0 { + return s + } + + return util.ByteSliceToString(AppendEscapedTemplateStringStringPart(make([]byte, 0, len(s)+numUnescaped), s)) +} + +func AppendEscapedTemplateStringStringPart(buf []byte, s string) []byte { + if s[0] == '{' { + buf = append(buf, '\\', s[0]) + } else { + buf = append(buf, s[0]) + } + + for i := 1; i < len(s); i++ { + if s[i] == '{' && s[i-1] != '\\' { + buf = append(buf, '\\', s[i]) + } else { + buf = append(buf, s[i]) + } + } + + return buf +} + +func countUnescapedLeftCurly(s string) (n int) { + // Note(anders): while not the functions I'd intuitively reach for to solve this, + // they are hands down the fastest option here, as they're done in assembly, which + // performs about an order of magnitude better than a manual loop in Go. + if n = strings.Count(s, "{"); n > 0 { + n -= strings.Count(s, `\{`) + } + return n +} + // Var represents a variable as defined by the language. type Var string // VarTerm creates a new Term with a Variable value. func VarTerm(v string) *Term { - return &Term{Value: Var(v)} + return &Term{Value: InternedVarValue(v)} } // Equal returns true if the other Value is a Variable and has the same value @@ -881,7 +1060,7 @@ func (v Var) String() string { // illegal variable name character (WildcardPrefix) to avoid conflicts. When // we serialize the variable here, we need to make sure it's parseable. if v.IsWildcard() { - return Wildcard.String() + return WildcardString } return string(v) } @@ -952,14 +1131,14 @@ func (ref Ref) Insert(x *Term, pos int) Ref { // Extend returns a copy of ref with the terms from other appended. The head of // other will be converted to a string. func (ref Ref) Extend(other Ref) Ref { - dst := make(Ref, len(ref)+len(other)) + offset := len(ref) + dst := make(Ref, offset+len(other)) copy(dst, ref) head := other[0].Copy() head.Value = String(head.Value.(Var)) - offset := len(ref) - dst[offset] = head + dst[offset] = head copy(dst[offset+1:], other[1:]) return dst } @@ -1071,42 +1250,38 @@ func (ref Ref) HasPrefix(other Ref) bool { func (ref Ref) ConstantPrefix() Ref { i := ref.Dynamic() if i < 0 { - return ref.Copy() + return ref } - return ref[:i].Copy() + return ref[:i] } +// StringPrefix returns the string portion of the ref starting from the head. func (ref Ref) StringPrefix() Ref { for i := 1; i < len(ref); i++ { switch ref[i].Value.(type) { case String: // pass default: // cut off - return ref[:i].Copy() + return ref[:i] } } - return ref.Copy() + return ref } // 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 { - if i > 0 && !x.IsGround() { - break + for i := range ref { + if i > 0 && !ref[i].IsGround() { + return ref[:i] } - prefix = append(prefix, x) } - return prefix + return ref } +// DynamicSuffix returns the dynamic portion of the ref. +// If the ref is not dynamic, nil is returned. func (ref Ref) DynamicSuffix() Ref { i := ref.Dynamic() if i < 0 { @@ -1117,7 +1292,7 @@ func (ref Ref) DynamicSuffix() Ref { // IsGround returns true if all of the parts of the Ref are ground. func (ref Ref) IsGround() bool { - if len(ref) == 0 { + if len(ref) < 2 { return true } return termSliceIsGround(ref[1:]) @@ -1137,85 +1312,84 @@ func (ref Ref) IsNested() bool { // contains non-string terms this function returns an error. Path // components are escaped. func (ref Ref) Ptr() (string, error) { - parts := make([]string, 0, len(ref)-1) - for _, term := range ref[1:] { - if str, ok := term.Value.(String); ok { - parts = append(parts, url.PathEscape(string(str))) - } else { + buf := &strings.Builder{} + tail := ref[1:] + + l := max(len(tail)-1, 0) // number of '/' to add + for i := range tail { + str, ok := tail[i].Value.(String) + if !ok { return "", errors.New("invalid path value type") } + l += len(str) } - return strings.Join(parts, "/"), nil -} + buf.Grow(l) -var varRegexp = regexp.MustCompile("^[[:alpha:]_][[:alpha:][:digit:]_]*$") + for i := range tail { + if i > 0 { + buf.WriteByte('/') + } + str := string(tail[i].Value.(String)) + // Sadly, the url package does not expose an appender for this. + buf.WriteString(url.PathEscape(str)) + } + return buf.String(), nil +} +// IsVarCompatibleString returns true if s is a valid variable name. String s is a valid variable +// name if it starts with a letter (a-z or A-Z) or underscore (_) and is followed by +// letters (a-z or A-Z), digits (0-9), and underscores. func IsVarCompatibleString(s string) bool { - return varRegexp.MatchString(s) -} + l := len(s) + if l == 0 { + return false + } + // not exactly easy on the eyes, but often orders of magnitude faster + // than using a compiled regex (see benchmarks in term_bench_test.go) + is_letter := func(c byte) bool { + return (c > 96 && c < 123) || (c > 64 && c < 91) + } + is_digit := func(c byte) bool { + return c > 47 && c < 58 + } + + // first character must be a letter or underscore + c := s[0] + if !(is_letter(c) || c == 95) { + return false + } -var bbPool = &sync.Pool{ - New: func() any { - return new(bytes.Buffer) - }, + // remaining characters must be letters, digits, or underscores + for i := 1; i < l; i++ { + if c = s[i]; !(is_letter(c) || is_digit(c) || c == 95) { + return false + } + } + + return true } func (ref Ref) String() string { - // Note(anderseknert): - // Options tried in the order of cheapness, where after some effort, - // only the last option now requires a (single) allocation: - // 1. empty ref - // 2. single var ref - // 3. built-in function ref - // 4. concatenated parts - reflen := len(ref) - if reflen == 0 { + l := len(ref) + // First check for zero-alloc options, as making the buffer for AppendText + // always costs an allocation. + if l == 0 { return "" } - if reflen == 1 { + if l == 1 { + if s, ok := ref[0].Value.(String); ok { + // Ref head should normally be a Var, but if for some reason + // it's a string, don't quote it. + return string(s) + } return ref[0].Value.String() } if name, ok := BuiltinNameFromRef(ref); ok { return name } - _var := ref[0].Value.String() - - bb := bbPool.Get().(*bytes.Buffer) - bb.Reset() - - defer bbPool.Put(bb) - - bb.Grow(len(_var) + len(ref[1:])*7) // rough estimate - bb.WriteString(_var) - - for _, p := range ref[1:] { - switch p := p.Value.(type) { - case String: - str := string(p) - if IsVarCompatibleString(str) && !IsKeyword(str) { - bb.WriteByte('.') - bb.WriteString(str) - } else { - bb.WriteByte('[') - // Determine whether we need the full JSON-escaped form - if strings.ContainsFunc(str, isControlOrBackslash) { - bb.Write(strconv.AppendQuote(bb.AvailableBuffer(), str)) - } else { - bb.WriteByte('"') - bb.WriteString(str) - bb.WriteByte('"') - } - bb.WriteByte(']') - } - default: - bb.WriteByte('[') - bb.WriteString(p.String()) - bb.WriteByte(']') - } - } - - return bb.String() + buf, _ := ref.AppendText(make([]byte, 0, ref.StringLength())) + return util.ByteSliceToString(buf) } // OutputVars returns a VarSet containing variables that would be bound by evaluating @@ -1258,6 +1432,15 @@ func NewArray(a ...*Term) *Array { return arr } +// NewArrayWithCapacity returns a new empty Array with the given capacity pre-allocated. +func NewArrayWithCapacity(capacity int) *Array { + return &Array{ + elems: make([]*Term, 0, capacity), + hashs: make([]int, 0, capacity), + ground: true, + } +} + // Array represents an array as defined by the language. Arrays are similar to the // same types as defined by JSON with the exception that they can contain Vars // and References. @@ -1270,13 +1453,12 @@ type Array struct { // Copy returns a deep copy of arr. func (arr *Array) Copy() *Array { - cpy := make([]int, len(arr.elems)) - copy(cpy, arr.hashs) return &Array{ elems: termSliceCopy(arr.elems), - hashs: cpy, + hashs: slices.Clone(arr.hashs), hash: arr.hash, - ground: arr.IsGround()} + ground: arr.ground, + } } // Equal returns true if arr is equal to other. @@ -1387,21 +1569,8 @@ func (arr *Array) MarshalJSON() ([]byte, error) { } func (arr *Array) String() string { - sb := sbPool.Get() - sb.Grow(len(arr.elems) * 16) - - defer sbPool.Put(sb) - - sb.WriteByte('[') - for i, e := range arr.elems { - if i > 0 { - sb.WriteString(", ") - } - sb.WriteString(e.String()) - } - sb.WriteByte(']') - - return sb.String() + buf, _ := arr.AppendText(make([]byte, 0, arr.StringLength())) + return util.ByteSliceToString(buf) } // Len returns the number of elements in the array. @@ -1519,6 +1688,11 @@ func NewSet(t ...*Term) Set { return s } +// NewSetWithCapacity returns a new empty Set with the given capacity pre-allocated. +func NewSetWithCapacity(capacity int) Set { + return newset(capacity) +} + func newset(n int) *set { var keys []*Term if n > 0 { @@ -1555,13 +1729,19 @@ type set struct { // Copy returns a deep copy of s. func (s *set) Copy() Set { - terms := make([]*Term, len(s.keys)) - for i := range s.keys { - terms[i] = s.keys[i].Copy() + cpy := &set{ + hash: s.hash, + ground: s.ground, + sortGuard: sync.Once{}, + elems: make(map[int]*Term, len(s.elems)), + keys: make([]*Term, 0, len(s.keys)), } - cpy := NewSet(terms...).(*set) - cpy.hash = s.hash - cpy.ground = s.ground + + for hash := range s.elems { + cpy.elems[hash] = s.elems[hash].Copy() + cpy.keys = append(cpy.keys, cpy.elems[hash]) + } + return cpy } @@ -1576,25 +1756,8 @@ func (s *set) Hash() int { } func (s *set) String() string { - if s.Len() == 0 { - return "set()" - } - - sb := sbPool.Get() - sb.Grow(s.Len() * 16) - - defer sbPool.Put(sb) - - sb.WriteByte('{') - for i := range s.sortedKeys() { - if i > 0 { - sb.WriteString(", ") - } - sb.WriteString(s.keys[i].Value.String()) - } - sb.WriteByte('}') - - return sb.String() + buf, _ := s.AppendText(make([]byte, 0, s.StringLength())) + return util.ByteSliceToString(buf) } func (s *set) sortedKeys() []*Term { @@ -1635,14 +1798,14 @@ func (s *set) Diff(other Set) Set { return NewSet() } - terms := make([]*Term, 0, len(s.keys)) - for _, term := range s.sortedKeys() { + result := newset(len(s.keys)) + for _, term := range s.keys { if !other.Contains(term) { - terms = append(terms, term) + result.insert(term, false) } } - return NewSet(terms...) + return result } // Intersect returns the set containing elements in both s and other. @@ -1657,21 +1820,28 @@ func (s *set) Intersect(other Set) Set { n = m } - terms := make([]*Term, 0, n) - for _, term := range ss.sortedKeys() { + result := newset(n) + for _, term := range ss.keys { if so.Contains(term) { - terms = append(terms, term) + result.insert(term, false) } } - return NewSet(terms...) + return result } // Union returns the set containing all elements of s and other. func (s *set) Union(other Set) Set { - r := NewSet() - s.Foreach(r.Add) - other.Foreach(r.Add) + o := other.(*set) + // Pre-allocate with max size - avoids over-allocation for overlapping sets + // while only requiring one potential grow for disjoint sets. + r := newset(max(len(s.keys), len(o.keys))) + for _, term := range s.keys { + r.insert(term, false) + } + for _, term := range o.keys { + r.insert(term, false) + } return r } @@ -1845,6 +2015,11 @@ func NewObject(t ...[2]*Term) Object { return obj } +// NewObjectWithCapacity returns a new empty Object with the given capacity pre-allocated. +func NewObjectWithCapacity(capacity int) Object { + return newobject(capacity) +} + // ObjectTerm creates a new Term with an Object value. func ObjectTerm(o ...[2]*Term) *Term { return &Term{Value: NewObject(o...)} @@ -2316,19 +2491,21 @@ func (obj *object) Merge(other Object) (Object, bool) { // 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) { - result := NewObject() + // Might overallocate assuming no conflicts is the common case, + // but that's typically faster than iterating over each object twice. + result := newobject(obj.Len() + other.Len()) stop := obj.Until(func(k, v *Term) bool { v2 := other.Get(k) // The key didn't exist in other, keep the original value if v2 == nil { - result.Insert(k, v) + result.insert(k, v, false) return false } // The key exists in both, resolve the conflict if possible merged, stop := conflictResolver(v, v2) if !stop { - result.Insert(k, merged) + result.insert(k, merged, false) } return stop }) @@ -2340,7 +2517,7 @@ func (obj *object) MergeWith(other Object, conflictResolver func(v1, v2 *Term) ( // Copy in any values from other for keys that don't exist in obj other.Foreach(func(k, v *Term) { if v2 := obj.Get(k); v2 == nil { - result.Insert(k, v) + result.insert(k, v, false) } }) return result, true @@ -2363,24 +2540,8 @@ func (obj *object) Len() int { } 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 { - sb.WriteString(", ") - } - sb.WriteString(elem.key.String()) - sb.WriteString(": ") - sb.WriteString(elem.value.String()) - } - sb.WriteByte('}') - - return sb.String() + buf, _ := obj.AppendText(make([]byte, 0, obj.StringLength())) + return util.ByteSliceToString(buf) } func (*object) get(*Term) *objectElem { @@ -2451,7 +2612,7 @@ func filterObject(o Value, filter Value) (Value, error) { case String, Number, Boolean, Null: return o, nil case *Array: - values := NewArray() + values := make([]*Term, 0, v.Len()) for i := range v.Len() { subFilter := filteredObj.Get(InternedIntegerString(i)) if subFilter != nil { @@ -2459,10 +2620,10 @@ func filterObject(o Value, filter Value) (Value, error) { if err != nil { return nil, err } - values = values.Append(NewTerm(filteredValue)) + values = append(values, NewTerm(filteredValue)) } } - return values, nil + return NewArray(values...), nil case Set: terms := make([]*Term, 0, v.Len()) for _, t := range v.Slice() { @@ -2585,7 +2746,8 @@ func (ac *ArrayComprehension) IsGround() bool { } func (ac *ArrayComprehension) String() string { - return "[" + ac.Term.String() + " | " + ac.Body.String() + "]" + buf, _ := ac.AppendText(make([]byte, 0, ac.StringLength())) + return util.ByteSliceToString(buf) } // ObjectComprehension represents an object comprehension as defined in the language. @@ -2645,7 +2807,8 @@ func (oc *ObjectComprehension) IsGround() bool { } func (oc *ObjectComprehension) String() string { - return "{" + oc.Key.String() + ": " + oc.Value.String() + " | " + oc.Body.String() + "}" + buf, _ := oc.AppendText(make([]byte, 0, oc.StringLength())) + return util.ByteSliceToString(buf) } // SetComprehension represents a set comprehension as defined in the language. @@ -2702,7 +2865,8 @@ func (sc *SetComprehension) IsGround() bool { } func (sc *SetComprehension) String() string { - return "{" + sc.Term.String() + " | " + sc.Body.String() + "}" + buf, _ := sc.AppendText(make([]byte, 0, sc.StringLength())) + return util.ByteSliceToString(buf) } // Call represents as function call in the language. @@ -2740,18 +2904,31 @@ func (c Call) IsGround() bool { return termSliceIsGround(c) } -// MakeExpr returns an ew Expr from this call. +// MakeExpr returns a new Expr from this call. func (c Call) MakeExpr(output *Term) *Expr { terms := []*Term(c) return NewExpr(append(terms, output)) } -func (c Call) String() string { - args := make([]string, len(c)-1) - for i := 1; i < len(c); i++ { - args[i-1] = c[i].String() +func (c Call) Operator() Ref { + if len(c) == 0 { + return nil + } + + return c[0].Value.(Ref) +} + +func (c Call) Operands() []*Term { + if len(c) < 1 { + return nil } - return fmt.Sprintf("%v(%v)", c[0], strings.Join(args, ", ")) + + return c[1:] +} + +func (c Call) String() string { + buf, _ := c.AppendText(make([]byte, 0, c.StringLength())) + return util.ByteSliceToString(buf) } func termSliceCopy(a []*Term) []*Term { diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/term_appenders.go b/vendor/github.com/open-policy-agent/opa/v1/ast/term_appenders.go new file mode 100644 index 000000000000..93c080391069 --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/term_appenders.go @@ -0,0 +1,266 @@ +package ast + +import ( + "encoding" + "strconv" + "strings" + + "github.com/open-policy-agent/opa/v1/util" +) + +// AppendText appends the text representation of term (i.e. as printed in policy) to +// buf and returns the extended buffer. +func (term *Term) AppendText(buf []byte) ([]byte, error) { + if app, ok := term.Value.(encoding.TextAppender); ok { + return app.AppendText(buf) + } + + return append(buf, term.Value.String()...), nil +} + +func (v Var) AppendText(buf []byte) ([]byte, error) { + if v.IsWildcard() { + return append(buf, WildcardString...), nil + } + return append(buf, v...), nil +} + +func (b Boolean) AppendText(buf []byte) ([]byte, error) { + if b { + return append(buf, "true"...), nil + } + return append(buf, "false"...), nil +} + +func (Null) AppendText(buf []byte) ([]byte, error) { + return append(buf, "null"...), nil +} + +func (str String) AppendText(buf []byte) ([]byte, error) { + return strconv.AppendQuote(buf, string(str)), nil +} + +func (str String) appendNoQuote(buf []byte) []byte { + // Append using strconv.AppendQuote for proper escaping, but trim off + // the leading and trailing quotes afterwards. + oldLen := len(buf) + buf = strconv.AppendQuote(buf, string(str)) + newLen := len(buf) + quoted := buf[oldLen:newLen] + + return append(buf[:oldLen], quoted[1:len(quoted)-1]...) +} + +func (num Number) AppendText(buf []byte) ([]byte, error) { + return append(buf, num...), nil +} + +func (arr *Array) AppendText(buf []byte) ([]byte, error) { + buf, err := AppendDelimeted(append(buf, '['), arr.elems, ", ") + if err != nil { + return nil, err + } + return append(buf, ']'), nil +} + +func (obj *object) AppendText(buf []byte) ([]byte, error) { + olen := obj.Len() + if olen == 0 { + return append(buf, "{}"...), nil + } + + buf = append(buf, '{') + + var err error + + // first key-value pair + keys := obj.sortedKeys() + for i := range keys { + if buf, err = keys[i].key.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, ": "...) + if buf, err = keys[i].value.AppendText(buf); err != nil { + return nil, err + } + if i < olen-1 { + buf = append(buf, ", "...) + } + } + + return append(buf, '}'), nil +} + +func (obj *lazyObj) AppendText(buf []byte) ([]byte, error) { + return append(buf, obj.force().String()...), nil +} + +func (s *set) AppendText(buf []byte) ([]byte, error) { + slen := s.Len() + if slen == 0 { + return append(buf, "set()"...), nil + } + + var err error + + buf = append(buf, '{') + if buf, err = AppendDelimeted(buf, s.sortedKeys(), ", "); err != nil { + return nil, err + } + + return append(buf, '}'), nil +} + +func (c Call) AppendText(buf []byte) ([]byte, error) { + if len(c) == 0 { + return buf, nil + } + + var err error + + if buf, err = c[0].AppendText(buf); err != nil { + return nil, err + } + + if buf, err = AppendDelimeted(append(buf, '('), c[1:], ", "); err != nil { + return nil, err + } + return append(buf, ')'), nil +} + +func (ts *TemplateString) AppendText(buf []byte) ([]byte, error) { + buf = append(buf, "$\""...) + for _, p := range ts.Parts { + switch x := p.(type) { + case *Expr: + buf = append(buf, '{') + var err error + if buf, err = x.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, '}') + case *Term: + if str, ok := x.Value.(String); ok { + // TODO(anders): this is a bit of a mess, but as explained by the comment on + // [EscapeTemplateStringStringPart], required as long as we rely on strconv for escaping, which adds + // quotes around the string that we don't want here, and trying to "unappend" them is not nice at all.. + s := string(str) + ulc := countUnescapedLeftCurly(s) + sl := str.StringLength() + ulc - 2 // no surrounding quotes + + if sl == len(s) { // no escaping needed + buf = append(buf, s...) + } else { // some escaping needed + if sl == len(s)+ulc { // only unescaped { + buf = AppendEscapedTemplateStringStringPart(buf, string(str)) + } else { // full escaping needed. this is expensive but luckily rare + tmp := str.appendNoQuote(make([]byte, 0, sl)) + ets := EscapeTemplateStringStringPart(util.ByteSliceToString(tmp)) + buf = append(buf, ets...) + } + } + } else { + var err error + if buf, err = x.AppendText(buf); err != nil { + return nil, err + } + } + default: + buf = append(buf, ""...) + } + } + return append(buf, '"'), nil +} + +func (r Ref) AppendText(buf []byte) ([]byte, error) { + reflen := len(r) + if reflen == 0 { + return buf, nil + } + if reflen == 1 { + if s, ok := r[0].Value.(String); ok { + // While a ref head is typically a Var, a lone String term should not be quoted + return append(buf, s...), nil + } + return r[0].AppendText(buf) + } + if name, ok := BuiltinNameFromRef(r); ok { + return append(buf, name...), nil + } + + var err error + if s, ok := r[0].Value.(String); ok { + buf = append(buf, s...) + } else if buf, err = r[0].AppendText(buf); err != nil { + return nil, err + } + + for _, p := range r[1:] { + switch v := p.Value.(type) { + case String: + str := string(v) + if IsVarCompatibleString(str) && !IsKeyword(str) { + buf = append(append(buf, '.'), str...) + } else { + buf = append(buf, '[') + // Determine whether we need the full JSON-escaped form + if strings.ContainsFunc(str, isControlOrBackslash) { + if buf, err = v.AppendText(buf); err != nil { + return nil, err + } + } else { + buf = append(append(append(buf, '"'), str...), '"') + } + buf = append(buf, ']') + } + default: + buf = append(buf, '[') + if buf, err = p.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, ']') + } + } + + return buf, nil +} + +func (sc *SetComprehension) AppendText(buf []byte) ([]byte, error) { + buf = append(buf, '{') + var err error + if buf, err = sc.Term.AppendText(buf); err != nil { + return nil, err + } + if buf, err = sc.Body.AppendText(append(buf, " | "...)); err != nil { + return nil, err + } + return append(buf, '}'), nil +} + +func (ac *ArrayComprehension) AppendText(buf []byte) ([]byte, error) { + buf = append(buf, '[') + var err error + if buf, err = ac.Term.AppendText(buf); err != nil { + return nil, err + } + if buf, err = ac.Body.AppendText(append(buf, " | "...)); err != nil { + return nil, err + } + return append(buf, ']'), nil +} + +func (oc *ObjectComprehension) AppendText(buf []byte) ([]byte, error) { + buf = append(buf, '{') + var err error + if buf, err = oc.Key.AppendText(buf); err != nil { + return nil, err + } + buf = append(buf, ": "...) + if buf, err = oc.Value.AppendText(buf); err != nil { + return nil, err + } + if buf, err = oc.Body.AppendText(append(buf, " | "...)); err != nil { + return nil, err + } + return append(buf, '}'), nil +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/transform.go b/vendor/github.com/open-policy-agent/opa/v1/ast/transform.go index 197ab6457dc2..a71bc0a77c04 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/transform.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/transform.go @@ -19,7 +19,6 @@ type Transformer interface { // Transform iterates the AST and calls the Transform function on the // Transformer t for x before recursing. func Transform(t Transformer, x any) (any, error) { - if term, ok := x.(*Term); ok { return Transform(t, term.Value) } @@ -284,6 +283,19 @@ func Transform(t Transformer, x any) (any, error) { } } return y, nil + case *TemplateString: + for i := range y.Parts { + if expr, ok := y.Parts[i].(*Expr); ok { + transformed, err := Transform(t, expr) + if err != nil { + return nil, err + } + if y.Parts[i], ok = transformed.(*Expr); !ok { + return nil, fmt.Errorf("illegal transform: %T != %T", expr, transformed) + } + } + } + return y, nil default: return y, nil } @@ -291,29 +303,29 @@ func Transform(t Transformer, x any) (any, error) { // TransformRefs calls the function f on all references under x. func TransformRefs(x any, f func(Ref) (Value, error)) (any, error) { - t := &GenericTransformer{func(x any) (any, error) { + t := NewGenericTransformer(func(x any) (any, error) { if r, ok := x.(Ref); ok { return f(r) } return x, nil - }} + }) return Transform(t, x) } // TransformVars calls the function f on all vars under x. func TransformVars(x any, f func(Var) (Value, error)) (any, error) { - t := &GenericTransformer{func(x any) (any, error) { + t := NewGenericTransformer(func(x any) (any, error) { if v, ok := x.(Var); ok { return f(v) } return x, nil - }} + }) return Transform(t, x) } -// TransformComprehensions calls the functio nf on all comprehensions under x. +// TransformComprehensions calls the function f on all comprehensions under x. func TransformComprehensions(x any, f func(any) (Value, error)) (any, error) { - t := &GenericTransformer{func(x any) (any, error) { + t := NewGenericTransformer(func(x any) (any, error) { switch x := x.(type) { case *ArrayComprehension: return f(x) @@ -323,7 +335,7 @@ func TransformComprehensions(x any, f func(any) (Value, error)) (any, error) { return f(x) } return x, nil - }} + }) return Transform(t, x) } @@ -387,11 +399,7 @@ func transformTerm(t Transformer, term *Term) (*Term, error) { if err != nil { return nil, err } - r := &Term{ - Value: v, - Location: term.Location, - } - return r, nil + return &Term{Value: v, Location: term.Location}, nil } func transformValue(t Transformer, v Value) (Value, error) { @@ -407,13 +415,18 @@ func transformValue(t Transformer, v Value) (Value, error) { } func transformVar(t Transformer, v Var) (Var, error) { - v1, err := Transform(t, v) + tv, err := t.Transform(v) if err != nil { return "", err } - r, ok := v1.(Var) + + if tv == nil { + return "", nil + } + + r, ok := tv.(Var) if !ok { - return "", fmt.Errorf("illegal transform: %T != %T", v, v1) + return "", fmt.Errorf("illegal transform: %T != %T", v, tv) } return r, nil } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/unify.go b/vendor/github.com/open-policy-agent/opa/v1/ast/unify.go index acbe275c0fcc..67b89a2a936f 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/unify.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/unify.go @@ -11,12 +11,11 @@ func isRefSafe(ref Ref, safe VarSet) bool { case Call: return isCallSafe(head, safe) default: - for v := range ref[0].Vars() { - if !safe.Contains(v) { - return false - } - } - return true + vis := varVisitorPool.Get().WithParams(SafetyCheckVisitorParams) + vis.Walk(ref[0]) + isSafe := vis.Vars().DiffCount(safe) == 0 + varVisitorPool.Put(vis) + return isSafe } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/varset.go b/vendor/github.com/open-policy-agent/opa/v1/ast/varset.go index e5bd52ae8c86..55bbea80d045 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/varset.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/varset.go @@ -12,7 +12,7 @@ import ( ) // VarSet represents a set of variables. -type VarSet map[Var]struct{} +type VarSet map[Var]struct{ *Location } // NewVarSet returns a new VarSet containing the specified variables. func NewVarSet(vs ...Var) VarSet { @@ -30,7 +30,16 @@ func NewVarSetOfSize(size int) VarSet { // Add updates the set to include the variable "v". func (s VarSet) Add(v Var) { - s[v] = struct{}{} + if _, ok := s[v]; !ok { + s[v] = struct{ *Location }{} + } +} + +func (s VarSet) AddLocation(v Var, l *Location) { + if entry, ok := s[v]; ok { + entry.Location = l + s[v] = entry + } } // Contains returns true if the set contains the variable "v". @@ -54,6 +63,7 @@ func (s VarSet) Diff(vs VarSet) VarSet { for v := range s { if !vs.Contains(v) { r.Add(v) + r.AddLocation(v, s[v].Location) } } return r diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/version_index.json b/vendor/github.com/open-policy-agent/opa/v1/ast/version_index.json index b02f785299c7..bd0df82ad65d 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/version_index.json +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/version_index.json @@ -3,1476 +3,1077 @@ "abs": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "all": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "and": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "any": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "array.concat": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 + }, + "array.flatten": { + "Major": 1, + "Minor": 13, + "Patch": 0 }, "array.reverse": { "Major": 0, "Minor": 36, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "array.slice": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "assign": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "base64.decode": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "base64.encode": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "base64.is_valid": { "Major": 0, "Minor": 24, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "base64url.decode": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "base64url.encode": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "base64url.encode_no_pad": { "Major": 0, "Minor": 25, "Patch": 0, - "PreRelease": "rc2", - "Metadata": "" + "PreRelease": "rc2" }, "bits.and": { "Major": 0, "Minor": 18, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "bits.lsh": { "Major": 0, "Minor": 18, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "bits.negate": { "Major": 0, "Minor": 18, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "bits.or": { "Major": 0, "Minor": 18, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "bits.rsh": { "Major": 0, "Minor": 18, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "bits.xor": { "Major": 0, "Minor": 18, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "cast_array": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "cast_boolean": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "cast_null": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "cast_object": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "cast_set": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "cast_string": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "ceil": { "Major": 0, "Minor": 26, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "concat": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "contains": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "count": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.hmac.equal": { "Major": 0, "Minor": 52, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.hmac.md5": { "Major": 0, "Minor": 36, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.hmac.sha1": { "Major": 0, "Minor": 36, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.hmac.sha256": { "Major": 0, "Minor": 36, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.hmac.sha512": { "Major": 0, "Minor": 36, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.md5": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.parse_private_keys": { "Major": 0, "Minor": 55, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.sha1": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.sha256": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.x509.parse_and_verify_certificates": { "Major": 0, "Minor": 31, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.x509.parse_and_verify_certificates_with_options": { "Major": 0, "Minor": 63, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.x509.parse_certificate_request": { "Major": 0, "Minor": 21, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.x509.parse_certificates": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.x509.parse_keypair": { "Major": 0, "Minor": 53, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "crypto.x509.parse_rsa_private_key": { "Major": 0, "Minor": 33, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "div": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "endswith": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "eq": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "equal": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "floor": { "Major": 0, "Minor": 26, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "format_int": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "glob.match": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "glob.quote_meta": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graph.reachable": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graph.reachable_paths": { "Major": 0, "Minor": 37, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graphql.is_valid": { "Major": 0, "Minor": 41, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graphql.parse": { "Major": 0, "Minor": 41, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graphql.parse_and_verify": { "Major": 0, "Minor": 41, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graphql.parse_query": { "Major": 0, "Minor": 41, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graphql.parse_schema": { "Major": 0, "Minor": 41, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "graphql.schema_is_valid": { "Major": 0, "Minor": 46, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "gt": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "gte": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "hex.decode": { "Major": 0, "Minor": 25, "Patch": 0, - "PreRelease": "rc2", - "Metadata": "" + "PreRelease": "rc2" }, "hex.encode": { "Major": 0, "Minor": 25, "Patch": 0, - "PreRelease": "rc2", - "Metadata": "" + "PreRelease": "rc2" }, "http.send": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "indexof": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "indexof_n": { "Major": 0, "Minor": 37, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "internal.member_2": { "Major": 0, "Minor": 34, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "internal.member_3": { "Major": 0, "Minor": 34, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "internal.print": { "Major": 0, "Minor": 34, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 + }, + "internal.template_string": { + "Major": 1, + "Minor": 12, + "Patch": 0 }, "internal.test_case": { "Major": 1, "Minor": 2, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "intersection": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.decode": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.decode_verify": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.encode_sign": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.encode_sign_raw": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_eddsa": { "Major": 1, "Minor": 8, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_es256": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_es384": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_es512": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_hs256": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_hs384": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_hs512": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_ps256": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_ps384": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_ps512": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_rs256": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_rs384": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "io.jwt.verify_rs512": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "is_array": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "is_boolean": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "is_null": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "is_number": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "is_object": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "is_set": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "is_string": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.filter": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.is_valid": { "Major": 0, "Minor": 25, "Patch": 0, - "PreRelease": "rc1", - "Metadata": "" + "PreRelease": "rc1" }, "json.marshal": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.marshal_with_options": { "Major": 0, "Minor": 64, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.match_schema": { "Major": 0, "Minor": 50, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.patch": { "Major": 0, "Minor": 25, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.remove": { "Major": 0, "Minor": 18, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.unmarshal": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "json.verify_schema": { "Major": 0, "Minor": 50, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "lower": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "lt": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "lte": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "max": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "min": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "minus": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "mul": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "neq": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "net.cidr_contains": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "net.cidr_contains_matches": { "Major": 0, "Minor": 19, "Patch": 0, - "PreRelease": "rc1", - "Metadata": "" + "PreRelease": "rc1" }, "net.cidr_expand": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "net.cidr_intersects": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "net.cidr_is_valid": { "Major": 0, "Minor": 46, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "net.cidr_merge": { "Major": 0, "Minor": 24, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "net.cidr_overlap": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "net.lookup_ip_addr": { "Major": 0, "Minor": 35, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "numbers.range": { "Major": 0, "Minor": 22, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "numbers.range_step": { "Major": 0, "Minor": 56, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "object.filter": { "Major": 0, "Minor": 17, - "Patch": 2, - "PreRelease": "", - "Metadata": "" + "Patch": 2 }, "object.get": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "object.keys": { "Major": 0, "Minor": 47, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "object.remove": { "Major": 0, "Minor": 17, - "Patch": 2, - "PreRelease": "", - "Metadata": "" + "Patch": 2 }, "object.subset": { "Major": 0, "Minor": 42, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "object.union": { "Major": 0, "Minor": 17, - "Patch": 2, - "PreRelease": "", - "Metadata": "" + "Patch": 2 }, "object.union_n": { "Major": 0, "Minor": 37, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "opa.runtime": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "or": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "plus": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "print": { "Major": 0, "Minor": 34, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "product": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "providers.aws.sign_req": { "Major": 0, "Minor": 47, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rand.intn": { "Major": 0, "Minor": 31, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "re_match": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.find_all_string_submatch_n": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.find_n": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.globs_match": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.is_valid": { "Major": 0, "Minor": 23, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.match": { "Major": 0, "Minor": 23, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.replace": { "Major": 0, "Minor": 45, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.split": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "regex.template_match": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rego.metadata.chain": { "Major": 0, "Minor": 40, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rego.metadata.rule": { "Major": 0, "Minor": 40, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rego.parse_module": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rem": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "replace": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "round": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "semver.compare": { "Major": 0, "Minor": 22, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "semver.is_valid": { "Major": 0, "Minor": 22, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "set_diff": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "sort": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "split": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "sprintf": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "startswith": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "strings.any_prefix_match": { "Major": 0, "Minor": 44, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "strings.any_suffix_match": { "Major": 0, "Minor": 44, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "strings.count": { "Major": 0, "Minor": 67, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "strings.render_template": { "Major": 0, "Minor": 59, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "strings.replace_n": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "strings.reverse": { "Major": 0, "Minor": 36, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "substring": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "sum": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.add_date": { "Major": 0, "Minor": 19, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.clock": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.date": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.diff": { "Major": 0, "Minor": 28, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.format": { "Major": 0, "Minor": 48, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.now_ns": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.parse_duration_ns": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.parse_ns": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.parse_rfc3339_ns": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "time.weekday": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "to_number": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "trace": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "trim": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "trim_left": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "trim_prefix": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "trim_right": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "trim_space": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "trim_suffix": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "type_name": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "union": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "units.parse": { "Major": 0, "Minor": 41, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "units.parse_bytes": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "upper": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "urlquery.decode": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "urlquery.decode_object": { "Major": 0, "Minor": 24, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "urlquery.encode": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "urlquery.encode_object": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "uuid.parse": { "Major": 0, "Minor": 57, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "uuid.rfc4122": { "Major": 0, "Minor": 20, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "walk": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "yaml.is_valid": { "Major": 0, "Minor": 25, "Patch": 0, - "PreRelease": "rc1", - "Metadata": "" + "PreRelease": "rc1" }, "yaml.marshal": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "yaml.unmarshal": { "Major": 0, "Minor": 17, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 } }, "features": { "keywords_in_refs": { "Major": 1, "Minor": 6, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rego_v1": { "Major": 1, "Minor": 0, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rego_v1_import": { "Major": 0, "Minor": 59, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rule_head_ref_string_prefixes": { "Major": 0, "Minor": 46, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "rule_head_refs": { "Major": 0, "Minor": 59, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 + }, + "template_strings": { + "Major": 1, + "Minor": 12, + "Patch": 0 } }, "keywords": { "contains": { "Major": 0, "Minor": 42, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "every": { "Major": 0, "Minor": 38, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "if": { "Major": 0, "Minor": 42, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 }, "in": { "Major": 0, "Minor": 34, - "Patch": 0, - "PreRelease": "", - "Metadata": "" + "Patch": 0 } } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/ast/visit.go b/vendor/github.com/open-policy-agent/opa/v1/ast/visit.go index 4ae6569ad768..d7725f5a513a 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/ast/visit.go +++ b/vendor/github.com/open-policy-agent/opa/v1/ast/visit.go @@ -4,40 +4,109 @@ package ast -// Visitor defines the interface for iterating AST elements. The Visit function -// can return a Visitor w which will be used to visit the children of the AST -// element v. If the Visit function returns nil, the children will not be -// visited. -// Deprecated: use GenericVisitor or another visitor implementation -type Visitor interface { - Visit(v any) (w Visitor) -} +var ( + termTypeVisitor = newTypeVisitor[*Term]() + varTypeVisitor = newTypeVisitor[Var]() + exprTypeVisitor = newTypeVisitor[*Expr]() + ruleTypeVisitor = newTypeVisitor[*Rule]() + refTypeVisitor = newTypeVisitor[Ref]() + bodyTypeVisitor = newTypeVisitor[Body]() + withTypeVisitor = newTypeVisitor[*With]() +) -// BeforeAndAfterVisitor wraps Visitor to provide hooks for being called before -// and after the AST has been visited. -// Deprecated: use GenericVisitor or another visitor implementation -type BeforeAndAfterVisitor interface { - Visitor - Before(x any) - After(x any) -} +type ( + // GenericVisitor provides a utility to walk over AST nodes using a + // closure. If the closure returns true, the visitor will not walk + // over AST nodes under x. + GenericVisitor struct { + f func(x any) bool + } + + // BeforeAfterVisitor provides a utility to walk over AST nodes using + // closures. If the before closure returns true, the visitor will not + // walk over AST nodes under x. The after closure is invoked always + // after visiting a node. + BeforeAfterVisitor struct { + before func(x any) bool + after func(x any) + } + + // VarVisitor walks AST nodes under a given node and collects all encountered + // variables. The collected variables can be controlled by specifying + // VarVisitorParams when creating the visitor. + VarVisitor struct { + params VarVisitorParams + vars VarSet + } + + // VarVisitorParams contains settings for a VarVisitor. + VarVisitorParams struct { + SkipRefHead bool + SkipRefCallHead bool + SkipObjectKeys bool + SkipClosures bool + SkipWithTarget bool + SkipSets bool + SkipTemplateStrings bool + } -// Walk iterates the AST by calling the Visit function on the Visitor + // Visitor defines the interface for iterating AST elements. The Visit function + // can return a Visitor w which will be used to visit the children of the AST + // element v. If the Visit function returns nil, the children will not be + // visited. + // + // Deprecated: use [GenericVisitor] or another visitor implementation + Visitor interface { + Visit(v any) (w Visitor) + } + + // BeforeAndAfterVisitor wraps Visitor to provide hooks for being called before + // and after the AST has been visited. + // + // Deprecated: use [GenericVisitor] or another visitor implementation + BeforeAndAfterVisitor interface { + Visitor + Before(x any) + After(x any) + } + + // typeVisitor is a generic visitor for a specific type T (the "generic" name was + // however taken). Contrary to the [GenericVisitor], the typeVisitor only invokes + // the visit function for nodes of type T, saving both CPU cycles and type assertions. + // typeVisitor implementations carry no state, and can be shared freely across + // goroutines. Access is private for the time being, as there is already inflation + // in visitor types exposed in the AST package. The various WalkXXX functions however + // now leverage typeVisitor under the hood. + // + // While a typeVisitor is generally a more performant option over a GenericVisitor, + // it is not as flexible: a type visitor can only visit nodes of a single type T, + // whereas a GenericVisitor visits all nodes. Adding to that, a typeVisitor can only + // be instantiated for **concrete types** — not interfaces (e.g., [*Expr], not [Node]), + // as reflection would be required to determine the concrete type at runtime, thus + // nullifying the performance benefits of the typeVisitor in the first place. + typeVisitor[T any] struct { + typ any + } +) + +// Walk iterates the AST by calling the Visit function on the [Visitor] // v for x before recursing. -// Deprecated: use GenericVisitor.Walk +// +// Deprecated: use [GenericVisitor.Walk] func Walk(v Visitor, x any) { if bav, ok := v.(BeforeAndAfterVisitor); !ok { walk(v, x) } else { bav.Before(x) - defer bav.After(x) walk(bav, x) + bav.After(x) } } // WalkBeforeAndAfter iterates the AST by calling the Visit function on the // Visitor v for x before recursing. -// Deprecated: use GenericVisitor.Walk +// +// Deprecated: use [GenericVisitor.Walk] func WalkBeforeAndAfter(v BeforeAndAfterVisitor, x any) { Walk(v, x) } @@ -149,132 +218,258 @@ func walk(v Visitor, x any) { for i := range x.Symbols { Walk(w, x.Symbols[i]) } + case *TemplateString: + for i := range x.Parts { + Walk(w, x.Parts[i]) + } } } // WalkVars calls the function f on all vars under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkVars(x any, f func(Var) bool) { - vis := &GenericVisitor{func(x any) bool { - if v, ok := x.(Var); ok { - return f(v) - } - return false - }} - vis.Walk(x) + varTypeVisitor.walk(x, f) } // WalkClosures calls the function f on all closures under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkClosures(x any, f func(any) bool) { - vis := &GenericVisitor{func(x any) bool { + vis := NewGenericVisitor(func(x any) bool { switch x := x.(type) { case *ArrayComprehension, *ObjectComprehension, *SetComprehension, *Every: return f(x) } return false - }} + }) vis.Walk(x) } // WalkRefs calls the function f on all references under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkRefs(x any, f func(Ref) bool) { - vis := &GenericVisitor{func(x any) bool { - if r, ok := x.(Ref); ok { - return f(r) - } - return false - }} - vis.Walk(x) + refTypeVisitor.walk(x, f) } // WalkTerms calls the function f on all terms under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkTerms(x any, f func(*Term) bool) { - vis := &GenericVisitor{func(x any) bool { - if term, ok := x.(*Term); ok { - return f(term) - } - return false - }} - vis.Walk(x) + termTypeVisitor.walk(x, f) } // WalkWiths calls the function f on all with modifiers under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkWiths(x any, f func(*With) bool) { - vis := &GenericVisitor{func(x any) bool { - if w, ok := x.(*With); ok { - return f(w) - } - return false - }} - vis.Walk(x) + withTypeVisitor.walk(x, f) } // WalkExprs calls the function f on all expressions under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkExprs(x any, f func(*Expr) bool) { - vis := &GenericVisitor{func(x any) bool { - if r, ok := x.(*Expr); ok { - return f(r) - } - return false - }} - vis.Walk(x) + exprTypeVisitor.walk(x, f) } // WalkBodies calls the function f on all bodies under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkBodies(x any, f func(Body) bool) { - vis := &GenericVisitor{func(x any) bool { - if b, ok := x.(Body); ok { - return f(b) - } - return false - }} - vis.Walk(x) + bodyTypeVisitor.walk(x, f) } // WalkRules calls the function f on all rules under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkRules(x any, f func(*Rule) bool) { - vis := &GenericVisitor{func(x any) bool { - if r, ok := x.(*Rule); ok { - stop := f(r) - // NOTE(tsandall): since rules cannot be embedded inside of queries - // we can stop early if there is no else block. - if stop || r.Else == nil { - return true + switch x := x.(type) { + case *Module: + for i := range x.Rules { + if !f(x.Rules[i]) && x.Rules[i].Else != nil { + WalkRules(x.Rules[i].Else, f) } } - return false - }} - vis.Walk(x) + case *Rule: + if !f(x) && x.Else != nil { + WalkRules(x.Else, f) + } + default: + ruleTypeVisitor.walk(x, f) + } } // WalkNodes calls the function f on all nodes under x. If the function f // returns true, AST nodes under the last node will not be visited. func WalkNodes(x any, f func(Node) bool) { - vis := &GenericVisitor{func(x any) bool { + vis := NewGenericVisitor(func(x any) bool { if n, ok := x.(Node); ok { return f(n) } return false - }} + }) vis.Walk(x) } -// GenericVisitor provides a utility to walk over AST nodes using a -// closure. If the closure returns true, the visitor will not walk -// over AST nodes under x. -type GenericVisitor struct { - f func(x any) bool +func newTypeVisitor[T any]() *typeVisitor[T] { + var t T + + return &typeVisitor[T]{typ: any(t)} +} + +func (tv *typeVisitor[T]) walkArgs(args Args, visit func(x T) bool) { + // If T is not Args, avoid allocation by inlining the walk. + if _, ok := tv.typ.(Args); !ok { + for i := range args { + tv.walk(args[i], visit) + } + } else { + tv.walk(args, visit) // allocates + } +} + +func (tv *typeVisitor[T]) walkBody(body Body, visit func(x T) bool) { + if _, ok := tv.typ.(Body); !ok { + for i := range body { + tv.walk(body[i], visit) + } + } else { + tv.walk(body, visit) // allocates + } +} + +func (tv *typeVisitor[T]) walkRef(ref Ref, visit func(x T) bool) { + if _, ok := tv.typ.(Ref); !ok { + for i := range ref { + tv.walk(ref[i], visit) + } + } else { + tv.walk(ref, visit) // allocates + } +} + +func (tv *typeVisitor[T]) walk(x any, visit func(x T) bool) { + if v, ok := x.(T); ok && visit(v) { + return + } + + switch x := x.(type) { + case *Module: + tv.walk(x.Package, visit) + for i := range x.Imports { + tv.walk(x.Imports[i], visit) + } + for i := range x.Rules { + tv.walk(x.Rules[i], visit) + } + for i := range x.Annotations { + tv.walk(x.Annotations[i], visit) + } + for i := range x.Comments { + tv.walk(x.Comments[i], visit) + } + case *Package: + tv.walkRef(x.Path, visit) + case *Import: + tv.walk(x.Path, visit) + if _, ok := tv.typ.(Var); ok { + tv.walk(x.Alias, visit) + } + case *Rule: + tv.walk(x.Head, visit) + tv.walkBody(x.Body, visit) + if x.Else != nil { + tv.walk(x.Else, visit) + } + case *Head: + if _, ok := tv.typ.(Var); ok { + tv.walk(x.Name, visit) + } + tv.walkArgs(x.Args, visit) + if x.Key != nil { + tv.walk(x.Key, visit) + } + if x.Value != nil { + tv.walk(x.Value, visit) + } + case Body: + for i := range x { + tv.walk(x[i], visit) + } + case Args: + for i := range x { + tv.walk(x[i], visit) + } + case *Expr: + switch ts := x.Terms.(type) { + case *Term, *SomeDecl, *Every: + tv.walk(ts, visit) + case []*Term: + for i := range ts { + tv.walk(ts[i], visit) + } + } + for i := range x.With { + tv.walk(x.With[i], visit) + } + case *With: + tv.walk(x.Target, visit) + tv.walk(x.Value, visit) + case *Term: + tv.walk(x.Value, visit) + case Ref: + for i := range x { + tv.walk(x[i], visit) + } + case *object: + x.Foreach(func(k, v *Term) { + tv.walk(k, visit) + tv.walk(v, visit) + }) + case Object: + for _, k := range x.Keys() { + tv.walk(k, visit) + tv.walk(x.Get(k), visit) + } + case *Array: + for i := range x.Len() { + tv.walk(x.Elem(i), visit) + } + case Set: + xSlice := x.Slice() + for i := range xSlice { + tv.walk(xSlice[i], visit) + } + case *ArrayComprehension: + tv.walk(x.Term, visit) + tv.walkBody(x.Body, visit) + case *ObjectComprehension: + tv.walk(x.Key, visit) + tv.walk(x.Value, visit) + tv.walkBody(x.Body, visit) + case *SetComprehension: + tv.walk(x.Term, visit) + tv.walkBody(x.Body, visit) + case Call: + for i := range x { + tv.walk(x[i], visit) + } + case *Every: + if x.Key != nil { + tv.walk(x.Key, visit) + } + tv.walk(x.Value, visit) + tv.walk(x.Domain, visit) + tv.walkBody(x.Body, visit) + case *SomeDecl: + for i := range x.Symbols { + tv.walk(x.Symbols[i], visit) + } + case *TemplateString: + for i := range x.Parts { + tv.walk(x.Parts[i], visit) + } + } } // NewGenericVisitor returns a new GenericVisitor that will invoke the function -// f on AST nodes. +// f on AST nodes. Note that while it returns a pointer, the creating a GenericVisitor +// doesn't commonly allocate it on the heap, as long as it doesn't escape the function +// in which it is created and used (as it's trivially inlined). func NewGenericVisitor(f func(x any) bool) *GenericVisitor { return &GenericVisitor{f} } @@ -306,7 +501,9 @@ func (vis *GenericVisitor) Walk(x any) { vis.Walk(x.Path) case *Import: vis.Walk(x.Path) - vis.Walk(x.Alias) + if x.Alias != "" { + vis.f(x.Alias) + } case *Rule: vis.Walk(x.Head) vis.Walk(x.Body) @@ -314,8 +511,12 @@ func (vis *GenericVisitor) Walk(x any) { vis.Walk(x.Else) } case *Head: - vis.Walk(x.Name) - vis.Walk(x.Args) + if x.Name != "" { + vis.f(x.Name) + } + if x.Args != nil { + vis.Walk(x.Args) + } if x.Key != nil { vis.Walk(x.Key) } @@ -395,18 +596,13 @@ func (vis *GenericVisitor) Walk(x any) { for i := range x.Symbols { vis.Walk(x.Symbols[i]) } + case *TemplateString: + for i := range x.Parts { + vis.Walk(x.Parts[i]) + } } } -// BeforeAfterVisitor provides a utility to walk over AST nodes using -// closures. If the before closure returns true, the visitor will not -// walk over AST nodes under x. The after closure is invoked always -// after visiting a node. -type BeforeAfterVisitor struct { - before func(x any) bool - after func(x any) -} - // NewBeforeAfterVisitor returns a new BeforeAndAfterVisitor that // will invoke the functions before and after AST nodes. func NewBeforeAfterVisitor(before func(x any) bool, after func(x any)) *BeforeAfterVisitor { @@ -538,31 +734,29 @@ func (vis *BeforeAfterVisitor) Walk(x any) { } } -// VarVisitor walks AST nodes under a given node and collects all encountered -// variables. The collected variables can be controlled by specifying -// VarVisitorParams when creating the visitor. -type VarVisitor struct { - params VarVisitorParams - vars VarSet -} - -// VarVisitorParams contains settings for a VarVisitor. -type VarVisitorParams struct { - SkipRefHead bool - SkipRefCallHead bool - SkipObjectKeys bool - SkipClosures bool - SkipWithTarget bool - SkipSets bool -} - -// NewVarVisitor returns a new VarVisitor object. +// NewVarVisitor returns a new [VarVisitor] object. func NewVarVisitor() *VarVisitor { return &VarVisitor{ vars: NewVarSet(), } } +// ClearOrNewVarVisitor clears a non-nil [VarVisitor] or returns a new one. +func ClearOrNewVarVisitor(vis *VarVisitor) *VarVisitor { + if vis == nil { + return NewVarVisitor() + } + + return vis.Clear() +} + +// ClearOrNew resets the visitor to its initial state, or returns a new one if nil. +// +// Deprecated: use [ClearOrNewVarVisitor] instead. +func (vis *VarVisitor) ClearOrNew() *VarVisitor { + return ClearOrNewVarVisitor(vis) +} + // Clear resets the visitor to its initial state, and returns it for chaining. func (vis *VarVisitor) Clear() *VarVisitor { vis.params = VarVisitorParams{} @@ -571,14 +765,6 @@ func (vis *VarVisitor) Clear() *VarVisitor { return vis } -// ClearOrNew returns a new VarVisitor if vis is nil, or else a cleared VarVisitor. -func (vis *VarVisitor) ClearOrNew() *VarVisitor { - if vis == nil { - return NewVarVisitor() - } - return vis.Clear() -} - // WithParams sets the parameters in params on vis. func (vis *VarVisitor) WithParams(params VarVisitorParams) *VarVisitor { vis.params = params @@ -594,7 +780,7 @@ func (vis *VarVisitor) Add(v Var) { } } -// Vars returns a VarSet that contains collected vars. +// Vars returns a [VarSet] that contains collected vars. func (vis *VarVisitor) Vars() VarSet { return vis.vars } @@ -621,7 +807,7 @@ func (vis *VarVisitor) visit(v any) bool { } if vis.params.SkipClosures { switch v := v.(type) { - case *ArrayComprehension, *ObjectComprehension, *SetComprehension: + case *ArrayComprehension, *ObjectComprehension, *SetComprehension, *TemplateString: return true case *Expr: if ev, ok := v.Terms.(*Every); ok { @@ -685,15 +871,20 @@ func (vis *VarVisitor) visit(v any) bool { return true } } + if vis.params.SkipTemplateStrings { + if _, ok := v.(*TemplateString); ok { + return true + } + } if v, ok := v.(Var); ok { vis.Add(v) + return true } return false } -// Walk iterates the AST by calling the function f on the -// GenericVisitor before recursing. Contrary to the generic Walk, this -// does not require allocating the visitor from heap. +// Walk iterates the AST by calling the function f on the [VarVisitor] before recursing. +// Contrary to the deprecated [Walk] function, this does not require allocating the visitor from heap. func (vis *VarVisitor) Walk(x any) { if vis.visit(x) { return @@ -701,16 +892,9 @@ func (vis *VarVisitor) Walk(x any) { switch x := x.(type) { case *Module: - vis.Walk(x.Package) - for i := range x.Imports { - vis.Walk(x.Imports[i]) - } for i := range x.Rules { vis.Walk(x.Rules[i]) } - for i := range x.Comments { - vis.Walk(x.Comments[i]) - } case *Package: vis.WalkRef(x.Path) case *Import: @@ -758,14 +942,17 @@ func (vis *VarVisitor) Walk(x any) { vis.Walk(x.Value.Value) case *Term: vis.Walk(x.Value) + if vVar, ok := x.Value.(Var); ok { + vis.vars.AddLocation(vVar, x.Location) + } case Ref: for i := range x { vis.Walk(x[i].Value) } case *object: - x.Foreach(func(k, _ *Term) { + x.Foreach(func(k, v *Term) { vis.Walk(k) - vis.Walk(x.Get(k)) + vis.Walk(v) }) case *Array: x.Foreach(func(t *Term) { @@ -801,6 +988,10 @@ func (vis *VarVisitor) Walk(x any) { for i := range x.Symbols { vis.Walk(x.Symbols[i]) } + case *TemplateString: + for i := range x.Parts { + vis.Walk(x.Parts[i]) + } } } @@ -820,6 +1011,9 @@ func (vis *VarVisitor) WalkRef(ref Ref) { } for _, term := range ref { vis.Walk(term.Value) + if vVar, ok := term.Value.(Var); ok { + vis.vars.AddLocation(vVar, term.Location) + } } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/bundle/bundle.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/bundle.go index 5b418c360b2a..bf00e96ca266 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/bundle/bundle.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/bundle.go @@ -6,9 +6,7 @@ package bundle import ( - "archive/tar" "bytes" - "compress/gzip" "encoding/hex" "encoding/json" "errors" @@ -24,6 +22,8 @@ import ( "sync" "github.com/gobwas/glob" + "golang.org/x/sync/errgroup" + "github.com/open-policy-agent/opa/internal/file/archive" "github.com/open-policy-agent/opa/internal/merge" "github.com/open-policy-agent/opa/v1/ast" @@ -51,6 +51,10 @@ const ( SnapshotBundleType = "snapshot" ) +var ( + empty Bundle +) + // Bundle represents a loaded bundle. The bundle can contain data and policies. type Bundle struct { Signatures SignaturesConfig @@ -96,7 +100,7 @@ type SignaturesConfig struct { // isEmpty returns if the SignaturesConfig is empty. func (s SignaturesConfig) isEmpty() bool { - return reflect.DeepEqual(s, SignaturesConfig{}) + return s.Signatures == nil && s.Plugin == "" } // DecodedSignature represents the decoded JWT payload. @@ -186,7 +190,6 @@ func (m *Manifest) SetRegoVersion(v ast.RegoVersion) { // Equal returns true if m is semantically equivalent to other. func (m Manifest) Equal(other Manifest) bool { - // This is safe since both are passed by value. m.Init() other.Init() @@ -323,7 +326,6 @@ func (ss stringSet) Equal(other stringSet) bool { } func (m *Manifest) validateAndInjectDefaults(b Bundle) error { - m.Init() // Validate roots in bundle. @@ -337,7 +339,7 @@ func (m *Manifest) validateAndInjectDefaults(b Bundle) error { 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]) + return fmt.Errorf("manifest has overlapped roots: '%s' and '%s'", roots[i], roots[j]) } } } @@ -349,7 +351,7 @@ func (m *Manifest) validateAndInjectDefaults(b Bundle) error { found = RootPathsContain(roots, path) } if !found { - return fmt.Errorf("manifest roots %v do not permit '%v' in module '%v'", roots, module.Parsed.Package, module.Path) + return fmt.Errorf("manifest roots %v do not permit '%v' in module '%s'", roots, module.Parsed.Package, module.Path) } } @@ -368,7 +370,7 @@ func (m *Manifest) validateAndInjectDefaults(b Bundle) error { // Ensure wasm module entrypoint in within bundle roots if !RootPathsContain(roots, wmConfig.Entrypoint) { - return fmt.Errorf("manifest roots %v do not permit '%v' entrypoint for wasm module '%v'", roots, wmConfig.Entrypoint, wmConfig.Module) + return fmt.Errorf("manifest roots %v do not permit '%s' entrypoint for wasm module '%s'", roots, wmConfig.Entrypoint, wmConfig.Module) } if _, ok := seenEps[wmConfig.Entrypoint]; ok { @@ -504,14 +506,13 @@ func NewReader(r io.Reader) *Reader { // NewCustomReader returns a new Reader configured to use the // specified DirectoryLoader. func NewCustomReader(loader DirectoryLoader) *Reader { - nr := Reader{ + return &Reader{ loader: loader, - metrics: metrics.New(), + metrics: metrics.NoOp(), files: make(map[string]FileInfo), sizeLimitBytes: DefaultSizeLimitBytes + 1, lazyLoadingMode: HasExtension(), } - return &nr } // IncludeManifestInData sets whether the manifest metadata should be @@ -620,24 +621,17 @@ func (r *Reader) ParserOptions() ast.ParserOptions { // Read returns a new Bundle loaded from the reader. func (r *Reader) Read() (Bundle, error) { - - var bundle Bundle - var descriptors []*Descriptor - var err error - var raw []Raw - - bundle.Signatures, bundle.Patch, descriptors, err = preProcessBundle(r.loader, r.skipVerify, r.sizeLimitBytes) + bundle, descriptors, err := preProcessBundle(r.loader, r.skipVerify, r.sizeLimitBytes) if err != nil { - return bundle, err + return empty, err } bundle.lazyLoadingMode = r.lazyLoadingMode bundle.sizeLimitBytes = r.sizeLimitBytes if bundle.Type() == SnapshotBundleType { - err = r.checkSignaturesAndDescriptors(bundle.Signatures) - if err != nil { - return bundle, err + if err := r.checkSignaturesAndDescriptors(bundle.Signatures); err != nil { + return empty, err } bundle.Data = map[string]any{} @@ -647,7 +641,7 @@ func (r *Reader) Read() (Bundle, error) { for _, f := range descriptors { buf, err := readFile(f, r.sizeLimitBytes) if err != nil { - return bundle, err + return empty, err } // verify the file content @@ -663,7 +657,7 @@ func (r *Reader) Read() (Bundle, error) { delete(r.files, path) } else { if err = r.verifyBundleFile(path, buf); err != nil { - return bundle, err + return empty, err } } } @@ -690,7 +684,7 @@ func (r *Reader) Read() (Bundle, error) { p = modulePathWithPrefix(r.name, fullPath) } - raw = append(raw, Raw{Path: p, Value: bs, module: &mf}) + bundle.Raw = append(bundle.Raw, Raw{Path: p, Value: bs, module: &mf}) } } else if filepath.Base(path) == WasmFile { bundle.WasmModules = append(bundle.WasmModules, WasmModuleFile{ @@ -706,7 +700,7 @@ func (r *Reader) Read() (Bundle, error) { }) } else if filepath.Base(path) == dataFile { if r.lazyLoadingMode { - raw = append(raw, Raw{Path: path, Value: buf.Bytes()}) + bundle.Raw = append(bundle.Raw, Raw{Path: path, Value: buf.Bytes()}) continue } @@ -717,16 +711,16 @@ func (r *Reader) Read() (Bundle, error) { r.metrics.Timer(metrics.RegoDataParse).Stop() if err != nil { - return bundle, fmt.Errorf("bundle load failed on %v: %w", r.fullPath(path), err) + return empty, fmt.Errorf("bundle load failed on %v: %w", r.fullPath(path), err) } - if err := insertValue(&bundle, path, value); err != nil { - return bundle, err + if err := insertValue(bundle, path, value); err != nil { + return empty, err } } else if filepath.Base(path) == yamlDataFile || filepath.Base(path) == ymlDataFile { if r.lazyLoadingMode { - raw = append(raw, Raw{Path: path, Value: buf.Bytes()}) + bundle.Raw = append(bundle.Raw, Raw{Path: path, Value: buf.Bytes()}) continue } @@ -737,16 +731,16 @@ func (r *Reader) Read() (Bundle, error) { r.metrics.Timer(metrics.RegoDataParse).Stop() if err != nil { - return bundle, fmt.Errorf("bundle load failed on %v: %w", r.fullPath(path), err) + return empty, fmt.Errorf("bundle load failed on %v: %w", r.fullPath(path), err) } - if err := insertValue(&bundle, path, value); err != nil { - return bundle, err + if err := insertValue(bundle, path, value); err != nil { + return empty, err } } else if strings.HasSuffix(path, ManifestExt) { if err := util.NewJSONDecoder(&buf).Decode(&bundle.Manifest); err != nil { - return bundle, fmt.Errorf("bundle load failed on manifest decode: %w", err) + return empty, fmt.Errorf("bundle load failed on manifest decode: %w", err) } } } @@ -754,52 +748,63 @@ func (r *Reader) Read() (Bundle, error) { // Parse modules popts := r.ParserOptions() popts.RegoVersion = bundle.RegoVersion(popts.EffectiveRegoVersion()) - for _, mf := range modules { - modulePopts := popts + + g := &errgroup.Group{} + r.metrics.Timer(metrics.RegoModuleParse).Start() + + for i, mf := range modules { + mpopts := popts if regoVersion, err := bundle.RegoVersionForFile(mf.RelativePath, popts.EffectiveRegoVersion()); err != nil { - return bundle, err + 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 + // We don't expect ast.RegoUndefined here, but don't override + // configured rego-version if we do just to be extra protective + mpopts.RegoVersion = regoVersion } - r.metrics.Timer(metrics.RegoModuleParse).Start() - mf.Parsed, err = ast.ParseModuleWithOpts(mf.Path, util.ByteSliceToString(mf.Raw), modulePopts) - r.metrics.Timer(metrics.RegoModuleParse).Stop() - if err != nil { - return bundle, err - } - bundle.Modules = append(bundle.Modules, mf) + + g.Go(func() (err error) { + if mf.Parsed, err = ast.ParseModuleWithOpts(mf.Path, util.ByteSliceToString(mf.Raw), mpopts); err == nil { + modules[i] = mf + } + return err + }) + } + + err = g.Wait() + r.metrics.Timer(metrics.RegoModuleParse).Stop() + if err != nil { + return empty, err } + bundle.Modules = modules + if bundle.Type() == DeltaBundleType { if len(bundle.Data) != 0 { - return bundle, errors.New("delta bundle expected to contain only patch file but data files found") + return empty, errors.New("delta bundle expected to contain only patch file but data files found") } if len(bundle.Modules) != 0 { - return bundle, errors.New("delta bundle expected to contain only patch file but policy files found") + return empty, errors.New("delta bundle expected to contain only patch file but policy files found") } if len(bundle.WasmModules) != 0 { - return bundle, errors.New("delta bundle expected to contain only patch file but wasm files found") + return empty, errors.New("delta bundle expected to contain only patch file but wasm files found") } if r.persist { - return bundle, errors.New("'persist' property is true in config. persisting delta bundle to disk is not supported") + return empty, errors.New( + "'persist' property is true in config. persisting delta bundle to disk is not supported") } } // check if the bundle signatures specify any files that weren't found in the bundle if bundle.Type() == SnapshotBundleType && len(r.files) != 0 { - extra := []string{} - for k := range r.files { - extra = append(extra, k) - } - return bundle, fmt.Errorf("file(s) %v specified in bundle signatures but not found in the target bundle", extra) + return empty, fmt.Errorf( + "file(s) %v specified in bundle signatures but not found in the target bundle", util.Keys(r.files)) } - if err := bundle.Manifest.validateAndInjectDefaults(bundle); err != nil { - return bundle, err + if err := bundle.Manifest.validateAndInjectDefaults(*bundle); err != nil { + return empty, err } // Inject the wasm module entrypoint refs into the WasmModuleFile structs @@ -812,36 +817,33 @@ func (r *Reader) Read() (Bundle, error) { for _, entrypoint := range entrypoints { ref, err := ast.PtrRef(ast.DefaultRootDocument, entrypoint) if err != nil { - return bundle, fmt.Errorf("failed to parse wasm module entrypoint '%s': %s", entrypoint, err) + return empty, fmt.Errorf("failed to parse wasm module entrypoint '%s': %s", entrypoint, err) } bundle.WasmModules[i].Entrypoints = append(bundle.WasmModules[i].Entrypoints, ref) } } if r.includeManifestInData { - var metadata map[string]any - b, err := json.Marshal(&bundle.Manifest) if err != nil { - return bundle, fmt.Errorf("bundle load failed on manifest marshal: %w", err) + return empty, fmt.Errorf("bundle load failed on manifest marshal: %w", err) } - err = util.UnmarshalJSON(b, &metadata) - if err != nil { - return bundle, fmt.Errorf("bundle load failed on manifest unmarshal: %w", err) + var metadata map[string]any + if err := util.UnmarshalJSON(b, &metadata); err != nil { + return empty, fmt.Errorf("bundle load failed on manifest unmarshal: %w", err) } // For backwards compatibility always write to the old unnamed manifest path // This will *not* be correct if >1 bundle is in use... if err := bundle.insertData(legacyManifestStoragePath, metadata); err != nil { - return bundle, fmt.Errorf("bundle load failed on %v: %w", legacyRevisionStoragePath, err) + return empty, fmt.Errorf("bundle load failed on %v: %w", legacyRevisionStoragePath, err) } } bundle.Etag = r.etag - bundle.Raw = raw - return bundle, nil + return *bundle, nil } func (r *Reader) isFileExcluded(path string) bool { @@ -869,10 +871,9 @@ func (r *Reader) checkSignaturesAndDescriptors(signatures SignaturesConfig) erro } // verify the JWT signatures included in the `.signatures.json` file - if err := r.verifyBundleSignature(signatures); err != nil { - return err - } + return r.verifyBundleSignature(signatures) } + return nil } @@ -931,19 +932,10 @@ func (w *Writer) DisableFormat(yes bool) *Writer { // Write writes the bundle to the writer's output stream. func (w *Writer) Write(bundle Bundle) error { - gw := gzip.NewWriter(w.w) - tw := tar.NewWriter(gw) - - bundleType := bundle.Type() + tw := archive.NewTarGzWriter(w.w) - if bundleType == SnapshotBundleType { - var buf bytes.Buffer - - if err := json.NewEncoder(&buf).Encode(bundle.Data); err != nil { - return err - } - - if err := archive.WriteFile(tw, "data.json", buf.Bytes()); err != nil { + if bundle.Type() == SnapshotBundleType { + if err := tw.WriteJSONFile("/data.json", bundle.Data); err != nil { return err } @@ -953,7 +945,7 @@ func (w *Writer) Write(bundle Bundle) error { path = module.Path } - if err := archive.WriteFile(tw, path, module.Raw); err != nil { + if err := tw.WriteFile(util.WithPrefix(path, "/"), module.Raw); err != nil { return err } } @@ -969,55 +961,48 @@ func (w *Writer) Write(bundle Bundle) error { if err := w.writePlan(tw, bundle); err != nil { return err } - } else if bundleType == DeltaBundleType { - if err := writePatch(tw, bundle); err != nil { + } else if bundle.Type() == DeltaBundleType { + if err := tw.WriteJSONFile("/patch.json", bundle.Patch); err != nil { return err } } - if err := writeManifest(tw, bundle); err != nil { - return err - } - - if err := tw.Close(); err != nil { - return err + if !bundle.Manifest.Empty() { + if err := tw.WriteJSONFile("/.manifest", bundle.Manifest); err != nil { + return err + } } - return gw.Close() + return tw.Close() } -func (w *Writer) writeWasm(tw *tar.Writer, bundle Bundle) error { +func (w *Writer) writeWasm(tw *archive.TarGzWriter, bundle Bundle) error { for _, wm := range bundle.WasmModules { path := wm.URL if w.usePath { path = wm.Path } - err := archive.WriteFile(tw, path, wm.Raw) - if err != nil { + if err := tw.WriteFile(util.WithPrefix(path, "/"), wm.Raw); err != nil { return err } } - if len(bundle.Wasm) > 0 { - err := archive.WriteFile(tw, "/"+WasmFile, bundle.Wasm) - if err != nil { - return err - } + if len(bundle.Wasm) == 0 { + return nil } - return nil + return tw.WriteFile(util.WithPrefix(WasmFile, "/"), bundle.Wasm) } -func (w *Writer) writePlan(tw *tar.Writer, bundle Bundle) error { +func (w *Writer) writePlan(tw *archive.TarGzWriter, bundle Bundle) error { for _, wm := range bundle.PlanModules { path := wm.URL if w.usePath { path = wm.Path } - err := archive.WriteFile(tw, path, wm.Raw) - if err != nil { + if err := tw.WriteFile(util.WithPrefix(path, "/"), wm.Raw); err != nil { return err } } @@ -1025,34 +1010,7 @@ func (w *Writer) writePlan(tw *tar.Writer, bundle Bundle) error { return nil } -func writeManifest(tw *tar.Writer, bundle Bundle) error { - - if bundle.Manifest.Empty() { - return nil - } - - var buf bytes.Buffer - - if err := json.NewEncoder(&buf).Encode(bundle.Manifest); err != nil { - return err - } - - return archive.WriteFile(tw, ManifestExt, buf.Bytes()) -} - -func writePatch(tw *tar.Writer, bundle Bundle) error { - - var buf bytes.Buffer - - if err := json.NewEncoder(&buf).Encode(bundle.Patch); err != nil { - return err - } - - return archive.WriteFile(tw, patchFile, buf.Bytes()) -} - -func writeSignatures(tw *tar.Writer, bundle Bundle) error { - +func writeSignatures(tw *archive.TarGzWriter, bundle Bundle) error { if bundle.Signatures.isEmpty() { return nil } @@ -1062,7 +1020,7 @@ func writeSignatures(tw *tar.Writer, bundle Bundle) error { return err } - return archive.WriteFile(tw, fmt.Sprintf(".%v", SignaturesFile), bs) + return tw.WriteFile(util.WithPrefix(SignaturesFile, "/."), bs) } func hashBundleFiles(hash SignatureHasher, b *Bundle) ([]FileInfo, error) { @@ -1115,8 +1073,7 @@ func hashBundleFiles(hash SignatureHasher, b *Bundle) ([]FileInfo, error) { return files, err } - bs, err = hash.HashFile(result) - if err != nil { + if bs, err = hash.HashFile(result); err != nil { return files, err } @@ -1227,10 +1184,6 @@ func (b *Bundle) GenerateSignature(signingConfig *SigningConfig, keyID string, u return err } - if b.Signatures.isEmpty() { - b.Signatures = SignaturesConfig{} - } - if signingConfig.Plugin != "" { b.Signatures.Plugin = signingConfig.Plugin } @@ -1243,7 +1196,6 @@ func (b *Bundle) GenerateSignature(signingConfig *SigningConfig, keyID string, u // ParsedModules returns a map of parsed modules with names that are // unique and human readable for the given a bundle name. func (b *Bundle) ParsedModules(bundleName string) map[string]*ast.Module { - mods := make(map[string]*ast.Module, len(b.Modules)) for _, mf := range b.Modules { @@ -1255,9 +1207,10 @@ func (b *Bundle) ParsedModules(bundleName string) map[string]*ast.Module { func (b *Bundle) RegoVersion(def ast.RegoVersion) ast.RegoVersion { if v := b.Manifest.RegoVersion; v != nil { - if *v == 0 { + switch *v { + case 0: return ast.RegoV0 - } else if *v == 1 { + case 1: return ast.RegoV1 } } @@ -1328,10 +1281,6 @@ func (m *Manifest) numericRegoVersionForFile(path string) (*int, error) { // Equal returns true if this bundle's contents equal the other bundle's // contents. func (b Bundle) Equal(other Bundle) bool { - if !reflect.DeepEqual(b.Data, other.Data) { - return false - } - if len(b.Modules) != len(other.Modules) { return false } @@ -1357,6 +1306,10 @@ func (b Bundle) Equal(other Bundle) bool { return false } + if !reflect.DeepEqual(b.Data, other.Data) { + return false + } + return bytes.Equal(b.Wasm, other.Wasm) } @@ -1487,7 +1440,6 @@ func Merge(bundles []*Bundle) (*Bundle, error) { // If usePath is true, per-file rego-versions will be calculated using the file's ModuleFile.Path; otherwise, the file's // ModuleFile.URL will be used. func MergeWithRegoVersion(bundles []*Bundle, regoVersion ast.RegoVersion, usePath bool) (*Bundle, error) { - if len(bundles) == 0 { return nil, errors.New("expected at least one bundle") } @@ -1512,7 +1464,6 @@ func MergeWithRegoVersion(bundles []*Bundle, regoVersion ast.RegoVersion, usePat var result Bundle for _, b := range bundles { - if b.Manifest.Roots == nil { return nil, errors.New("bundle manifest not initialized") } @@ -1607,16 +1558,11 @@ func bundleRelativePath(m ModuleFile, usePath bool) string { } func bundleAbsolutePath(m ModuleFile, usePath bool) string { - var p string + p := m.URL if usePath { p = m.Path - } else { - p = m.URL - } - if !path.IsAbs(p) { - p = "/" + p } - return path.Clean(p) + return path.Clean(util.WithPrefix(p, "/")) } // RootPathsOverlap takes in two bundle root paths and returns true if they overlap. @@ -1642,7 +1588,6 @@ func rootPathSegments(path string) []string { } func rootContains(root []string, other []string) bool { - // A single segment, empty string root always contains the other. if len(root) == 1 && root[0] == "" { return true @@ -1674,7 +1619,7 @@ func getNormalizedPath(path string) []string { // other hand, if the path is empty, filepath.Dir will return '.'. // Note: filepath.Dir can return paths with '\' separators, always use // filepath.ToSlash to keep them normalized. - dirpath := strings.TrimLeft(normalizePath(filepath.Dir(path)), "/.") + dirpath := strings.TrimLeft(filepath.ToSlash(filepath.Dir(path)), "/.") var key []string if dirpath != "" { key = strings.Split(dirpath, "/") @@ -1701,56 +1646,52 @@ func dfs(value any, path string, fn func(string, any) (bool, error)) error { } func modulePathWithPrefix(bundleName string, modulePath string) string { - // Default prefix is just the bundle name - prefix := bundleName - // Bundle names are sometimes just file paths, some of which // are full urls (file:///foo/). Parse these and only use the path. parsed, err := url.Parse(bundleName) if err == nil { - prefix = filepath.Join(parsed.Host, parsed.Path) + return path.Join(parsed.Host, parsed.Path, modulePath) } - // Note: filepath.Join can return paths with '\' separators, always use - // filepath.ToSlash to keep them normalized. - return normalizePath(filepath.Join(prefix, modulePath)) + return path.Join(bundleName, modulePath) } // IsStructuredDoc checks if the file name equals a structured file extension ex. ".json" func IsStructuredDoc(name string) bool { - return filepath.Base(name) == dataFile || filepath.Base(name) == yamlDataFile || - filepath.Base(name) == SignaturesFile || filepath.Base(name) == ManifestExt + base := filepath.Base(name) + return base == dataFile || base == yamlDataFile || base == SignaturesFile || base == ManifestExt } -func preProcessBundle(loader DirectoryLoader, skipVerify bool, sizeLimitBytes int64) (SignaturesConfig, Patch, []*Descriptor, error) { +func preProcessBundle(loader DirectoryLoader, skipVerify bool, sizeLimitBytes int64) (*Bundle, []*Descriptor, error) { + bundle := &Bundle{} descriptors := []*Descriptor{} - var signatures SignaturesConfig - var patch Patch for { f, err := loader.NextFile() - if err == io.EOF { - break - } - if err != nil { - return signatures, patch, nil, fmt.Errorf("bundle read failed: %w", err) + if err == io.EOF { + break + } + return bundle, nil, fmt.Errorf("bundle read failed: %w", err) } - // check for the signatures file - if !skipVerify && strings.HasSuffix(f.Path(), SignaturesFile) { + isSignaturesFile := strings.HasSuffix(f.Path(), SignaturesFile) + + if !skipVerify && isSignaturesFile { buf, err := readFile(f, sizeLimitBytes) if err != nil { - return signatures, patch, nil, err + return bundle, nil, err } - if err := util.NewJSONDecoder(&buf).Decode(&signatures); err != nil { - return signatures, patch, nil, fmt.Errorf("bundle load failed on signatures decode: %w", err) + if err := util.NewJSONDecoder(&buf).Decode(&bundle.Signatures); err != nil { + return bundle, nil, fmt.Errorf("bundle load failed on signatures decode: %w", err) } - } else if !strings.HasSuffix(f.Path(), SignaturesFile) { + } else if !isSignaturesFile { descriptors = append(descriptors, f) - if filepath.Base(f.Path()) == patchFile { + base := filepath.Base(f.Path()) + + if base == patchFile { var b bytes.Buffer tee := io.TeeReader(f.reader, &b) @@ -1758,18 +1699,19 @@ func preProcessBundle(loader DirectoryLoader, skipVerify bool, sizeLimitBytes in buf, err := readFile(f, sizeLimitBytes) if err != nil { - return signatures, patch, nil, err + return bundle, nil, err } - if err := util.NewJSONDecoder(&buf).Decode(&patch); err != nil { - return signatures, patch, nil, fmt.Errorf("bundle load failed on patch decode: %w", err) + if err := util.NewJSONDecoder(&buf).Decode(&bundle.Patch); err != nil { + return bundle, nil, fmt.Errorf("bundle load failed on patch decode: %w", err) } f.reader = &b } } } - return signatures, patch, descriptors, nil + + return bundle, descriptors, nil } func readFile(f *Descriptor, sizeLimitBytes int64) (bytes.Buffer, error) { @@ -1839,7 +1781,3 @@ func fstatFileSize(f *os.File) (int64, error) { } return fileInfo.Size(), nil } - -func normalizePath(p string) string { - return filepath.ToSlash(p) -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/bundle/file.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/file.go index d008c3d44c6d..4897ee7b91c0 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/bundle/file.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/file.go @@ -352,12 +352,10 @@ func (t *tarballLoader) NextFile() (*Descriptor, error) { for { header, err := t.tr.Next() - - if err == io.EOF { - break - } - if err != nil { + if err == io.EOF { + break + } return nil, err } @@ -365,7 +363,6 @@ func (t *tarballLoader) NextFile() (*Descriptor, error) { if header.Typeflag == tar.TypeReg { if t.filter != nil { - if t.filter(filepath.ToSlash(header.Name), header.FileInfo(), getdepth(header.Name, false)) { continue } @@ -504,9 +501,9 @@ func getdepth(path string, isDir bool) int { } func getFileStoragePath(path string) (storage.Path, error) { - fpath := strings.TrimLeft(normalizePath(filepath.Dir(path)), "/.") + fpath := strings.TrimLeft(filepath.ToSlash(filepath.Dir(path)), "/.") if strings.HasSuffix(path, RegoExt) { - fpath = strings.Trim(normalizePath(path), "/") + fpath = strings.Trim(filepath.ToSlash(path), "/") } p, ok := storage.ParsePathEscaped("/" + fpath) diff --git a/vendor/github.com/open-policy-agent/opa/v1/bundle/filefs.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/filefs.go index 7ab3de989c1d..fc6fc1896f7d 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/bundle/filefs.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/filefs.go @@ -1,6 +1,3 @@ -//go:build go1.16 -// +build go1.16 - package bundle import ( diff --git a/vendor/github.com/open-policy-agent/opa/v1/bundle/hash.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/hash.go index 5a62d2dc004f..dd9dfe5149ca 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/bundle/hash.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/hash.go @@ -14,7 +14,6 @@ import ( "fmt" "hash" "io" - "strings" "github.com/open-policy-agent/opa/v1/util" ) @@ -132,5 +131,5 @@ func encodePrimitive(v any) []byte { encoder := json.NewEncoder(&buf) encoder.SetEscapeHTML(false) _ = encoder.Encode(v) - return []byte(strings.Trim(buf.String(), "\n")) + return bytes.Trim(buf.Bytes(), "\n") } diff --git a/vendor/github.com/open-policy-agent/opa/v1/bundle/store.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/store.go index 992bf78f6328..f6c13c75fc1a 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/bundle/store.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/store.go @@ -571,12 +571,11 @@ func doDFS(obj map[string]json.RawMessage, path string, roots []string) error { } for key := range obj { - newPath := filepath.Join(strings.Trim(path, "/"), key) // Note: filepath.Join can return paths with '\' separators, always use // filepath.ToSlash to keep them normalized. - newPath = strings.TrimLeft(normalizePath(newPath), "/.") + newPath = strings.TrimLeft(filepath.ToSlash(newPath), "/.") contains := false prefix := false @@ -971,7 +970,7 @@ func compileModules(compiler *ast.Compiler, m metrics.Metrics, bundles map[strin m.Timer(metrics.RegoModuleCompile).Start() defer m.Timer(metrics.RegoModuleCompile).Stop() - modules := map[string]*ast.Module{} + modules := make(map[string]*ast.Module, len(compiler.Modules)+len(extraModules)+len(bundles)) // preserve any modules already on the compiler maps.Copy(modules, compiler.Modules) @@ -1191,17 +1190,20 @@ func applyPatches(ctx context.Context, store storage.Store, txn storage.Transact // Helpers for the older single (unnamed) bundle style manifest storage. // LegacyManifestStoragePath is the older unnamed bundle path for manifests to be stored. +// // Deprecated: Use ManifestStoragePath and named bundles instead. var legacyManifestStoragePath = storage.MustParsePath("/system/bundle/manifest") var legacyRevisionStoragePath = append(legacyManifestStoragePath, "revision") // LegacyWriteManifestToStore will write the bundle manifest to the older single (unnamed) bundle manifest location. +// // Deprecated: Use WriteManifestToStore and named bundles instead. func LegacyWriteManifestToStore(ctx context.Context, store storage.Store, txn storage.Transaction, manifest Manifest) error { return write(ctx, store, txn, legacyManifestStoragePath, manifest) } // LegacyEraseManifestFromStore will erase the bundle manifest from the older single (unnamed) bundle manifest location. +// // Deprecated: Use WriteManifestToStore and named bundles instead. func LegacyEraseManifestFromStore(ctx context.Context, store storage.Store, txn storage.Transaction) error { err := store.Write(ctx, txn, storage.RemoveOp, legacyManifestStoragePath, nil) @@ -1212,12 +1214,14 @@ func LegacyEraseManifestFromStore(ctx context.Context, store storage.Store, txn } // LegacyReadRevisionFromStore will read the bundle manifest revision from the older single (unnamed) bundle manifest location. +// // Deprecated: Use ReadBundleRevisionFromStore and named bundles instead. func LegacyReadRevisionFromStore(ctx context.Context, store storage.Store, txn storage.Transaction) (string, error) { return readRevisionFromStore(ctx, store, txn, legacyRevisionStoragePath) } // ActivateLegacy calls Activate for the bundles but will also write their manifest to the older unnamed store location. +// // Deprecated: Use Activate with named bundles instead. func ActivateLegacy(opts *ActivateOpts) error { opts.legacy = true diff --git a/vendor/github.com/open-policy-agent/opa/v1/bundle/verify.go b/vendor/github.com/open-policy-agent/opa/v1/bundle/verify.go index 82e308b49e24..42c8908f73a0 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/bundle/verify.go +++ b/vendor/github.com/open-policy-agent/opa/v1/bundle/verify.go @@ -144,10 +144,6 @@ func verifyJWTSignature(token string, bvc *VerificationConfig) (*DecodedSignatur // Because we want to fallback to ds.KeyID when we can't find the // keyID, we need to parse the payload here already. - // - // (lestrrat) Whoa, you're going to trust the payload before you - // verify the signature? Even if it's for backwrds compatibility, - // Is this OK? decoder := base64.RawURLEncoding payload := make([]byte, decoder.DecodedLen(len(payloadb64))) if _, err := decoder.Decode(payload, payloadb64); err != 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 index 5b0bb1ea523d..ff2c9aa2c7d8 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/capabilities/capabilities.go +++ b/vendor/github.com/open-policy-agent/opa/v1/capabilities/capabilities.go @@ -2,9 +2,6 @@ // 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 ( diff --git a/vendor/github.com/open-policy-agent/opa/v1/config/config.go b/vendor/github.com/open-policy-agent/opa/v1/config/config.go deleted file mode 100644 index 1912d1f38ca5..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/config/config.go +++ /dev/null @@ -1,393 +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 config implements OPA configuration file parsing and validation. -package config - -import ( - "encoding/json" - "errors" - "fmt" - "maps" - "os" - "path/filepath" - "reflect" - "sort" - "strings" - - "github.com/open-policy-agent/opa/internal/ref" - "github.com/open-policy-agent/opa/v1/ast" - "github.com/open-policy-agent/opa/v1/util" - "github.com/open-policy-agent/opa/v1/version" -) - -// ServerConfig represents the different server configuration options. -type ServerConfig struct { - Metrics json.RawMessage `json:"metrics,omitempty"` - - Encoding json.RawMessage `json:"encoding,omitempty"` - Decoding json.RawMessage `json:"decoding,omitempty"` -} - -// Clone creates a deep copy of ServerConfig. -func (s *ServerConfig) Clone() *ServerConfig { - if s == nil { - return nil - } - - clone := &ServerConfig{} - - if s.Encoding != nil { - clone.Encoding = make(json.RawMessage, len(s.Encoding)) - copy(clone.Encoding, s.Encoding) - } - if s.Decoding != nil { - clone.Decoding = make(json.RawMessage, len(s.Decoding)) - copy(clone.Decoding, s.Decoding) - } - if s.Metrics != nil { - clone.Metrics = make(json.RawMessage, len(s.Metrics)) - copy(clone.Metrics, s.Metrics) - } - - return clone -} - -// StorageConfig represents Config's storage options. -type StorageConfig struct { - Disk json.RawMessage `json:"disk,omitempty"` -} - -// Clone creates a deep copy of StorageConfig. -func (s *StorageConfig) Clone() *StorageConfig { - if s == nil { - return nil - } - - clone := &StorageConfig{} - - if s.Disk != nil { - clone.Disk = make(json.RawMessage, len(s.Disk)) - copy(clone.Disk, s.Disk) - } - - return clone -} - -// Config represents the configuration file that OPA can be started with. -type Config struct { - Services json.RawMessage `json:"services,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Discovery json.RawMessage `json:"discovery,omitempty"` - Bundle json.RawMessage `json:"bundle,omitempty"` // Deprecated: Use `bundles` instead - Bundles json.RawMessage `json:"bundles,omitempty"` - DecisionLogs json.RawMessage `json:"decision_logs,omitempty"` - Status json.RawMessage `json:"status,omitempty"` - Plugins map[string]json.RawMessage `json:"plugins,omitempty"` - Keys json.RawMessage `json:"keys,omitempty"` - DefaultDecision *string `json:"default_decision,omitempty"` - DefaultAuthorizationDecision *string `json:"default_authorization_decision,omitempty"` - Caching json.RawMessage `json:"caching,omitempty"` - NDBuiltinCache bool `json:"nd_builtin_cache,omitempty"` - PersistenceDirectory *string `json:"persistence_directory,omitempty"` - DistributedTracing json.RawMessage `json:"distributed_tracing,omitempty"` - Server *ServerConfig `json:"server,omitempty"` - Storage *StorageConfig `json:"storage,omitempty"` - Extra map[string]json.RawMessage `json:"-"` -} - -// ParseConfig returns a valid Config object with defaults injected. The id -// and version parameters will be set in the labels map. -func ParseConfig(raw []byte, id string) (*Config, error) { - // NOTE(sr): based on https://stackoverflow.com/a/33499066/993018 - var result Config - objValue := reflect.ValueOf(&result).Elem() - knownFields := map[string]reflect.Value{} - for i := 0; i != objValue.NumField(); i++ { - jsonName := strings.Split(objValue.Type().Field(i).Tag.Get("json"), ",")[0] - knownFields[jsonName] = objValue.Field(i) - } - - if err := util.Unmarshal(raw, &result.Extra); err != nil { - return nil, err - } - - for key, chunk := range result.Extra { - if field, found := knownFields[key]; found { - if err := util.Unmarshal(chunk, field.Addr().Interface()); err != nil { - return nil, err - } - delete(result.Extra, key) - } - } - if len(result.Extra) == 0 { - result.Extra = nil - } - return &result, result.validateAndInjectDefaults(id) -} - -// PluginNames returns a sorted list of names of enabled plugins. -func (c Config) PluginNames() (result []string) { - if c.Bundle != nil || c.Bundles != nil { - result = append(result, "bundles") - } - if c.Status != nil { - result = append(result, "status") - } - if c.DecisionLogs != nil { - result = append(result, "decision_logs") - } - for name := range c.Plugins { - result = append(result, name) - } - sort.Strings(result) - return result -} - -// PluginsEnabled returns true if one or more plugin features are enabled. -// -// 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 -} - -// DefaultDecisionRef returns the default decision as a reference. -func (c Config) DefaultDecisionRef() ast.Ref { - r, _ := ref.ParseDataPath(*c.DefaultDecision) - return r -} - -// DefaultAuthorizationDecisionRef returns the default authorization decision -// as a reference. -func (c Config) DefaultAuthorizationDecisionRef() ast.Ref { - r, _ := ref.ParseDataPath(*c.DefaultAuthorizationDecision) - return r -} - -// NDBuiltinCacheEnabled returns if the ND builtins cache should be used. -func (c Config) NDBuiltinCacheEnabled() bool { - return c.NDBuiltinCache -} - -// GetPersistenceDirectory returns the configured persistence directory, or $PWD/.opa if none is configured -func (c Config) GetPersistenceDirectory() (string, error) { - if c.PersistenceDirectory == nil { - pwd, err := os.Getwd() - if err != nil { - return "", err - } - return filepath.Join(pwd, ".opa"), nil - } - return *c.PersistenceDirectory, nil -} - -// ActiveConfig returns OPA's active configuration -// with the credentials and crypto keys removed -func (c *Config) ActiveConfig() (any, error) { - bs, err := json.Marshal(c) - if err != nil { - return nil, err - } - - var result map[string]any - if err := util.UnmarshalJSON(bs, &result); err != nil { - return nil, err - } - for k, e := range c.Extra { - var v any - if err := util.UnmarshalJSON(e, &v); err != nil { - return nil, err - } - result[k] = v - } - - if err := removeServiceCredentials(result["services"]); err != nil { - return nil, err - } - - if err := removeCryptoKeys(result["keys"]); err != nil { - return nil, err - } - - return result, nil -} - -// Clone creates a deep copy of the Config struct -func (c *Config) Clone() *Config { - if c == nil { - return nil - } - - clone := &Config{ - NDBuiltinCache: c.NDBuiltinCache, - Server: c.Server.Clone(), - Storage: c.Storage.Clone(), - Labels: maps.Clone(c.Labels), - } - - if c.Services != nil { - clone.Services = make(json.RawMessage, len(c.Services)) - copy(clone.Services, c.Services) - } - if c.Discovery != nil { - clone.Discovery = make(json.RawMessage, len(c.Discovery)) - copy(clone.Discovery, c.Discovery) - } - if c.Bundle != nil { - clone.Bundle = make(json.RawMessage, len(c.Bundle)) - copy(clone.Bundle, c.Bundle) - } - if c.Bundles != nil { - clone.Bundles = make(json.RawMessage, len(c.Bundles)) - copy(clone.Bundles, c.Bundles) - } - if c.DecisionLogs != nil { - clone.DecisionLogs = make(json.RawMessage, len(c.DecisionLogs)) - copy(clone.DecisionLogs, c.DecisionLogs) - } - if c.Status != nil { - clone.Status = make(json.RawMessage, len(c.Status)) - copy(clone.Status, c.Status) - } - if c.Keys != nil { - clone.Keys = make(json.RawMessage, len(c.Keys)) - copy(clone.Keys, c.Keys) - } - if c.Caching != nil { - clone.Caching = make(json.RawMessage, len(c.Caching)) - copy(clone.Caching, c.Caching) - } - if c.DistributedTracing != nil { - clone.DistributedTracing = make(json.RawMessage, len(c.DistributedTracing)) - copy(clone.DistributedTracing, c.DistributedTracing) - } - - if c.DefaultDecision != nil { - s := *c.DefaultDecision - clone.DefaultDecision = &s - } - if c.DefaultAuthorizationDecision != nil { - s := *c.DefaultAuthorizationDecision - clone.DefaultAuthorizationDecision = &s - } - if c.PersistenceDirectory != nil { - s := *c.PersistenceDirectory - clone.PersistenceDirectory = &s - } - - if c.Plugins != nil { - clone.Plugins = make(map[string]json.RawMessage, len(c.Plugins)) - for k, v := range c.Plugins { - if v != nil { - clone.Plugins[k] = make(json.RawMessage, len(v)) - copy(clone.Plugins[k], v) - } - } - } - - if c.Extra != nil { - clone.Extra = make(map[string]json.RawMessage, len(c.Extra)) - for k, v := range c.Extra { - if v != nil { - clone.Extra[k] = make(json.RawMessage, len(v)) - copy(clone.Extra[k], v) - } - } - } - - return clone -} - -func (c *Config) validateAndInjectDefaults(id string) error { - if c.DefaultDecision == nil { - s := defaultDecisionPath - c.DefaultDecision = &s - } - - _, err := ref.ParseDataPath(*c.DefaultDecision) - if err != nil { - return err - } - - if c.DefaultAuthorizationDecision == nil { - s := defaultAuthorizationDecisionPath - c.DefaultAuthorizationDecision = &s - } - - _, err = ref.ParseDataPath(*c.DefaultAuthorizationDecision) - if err != nil { - return err - } - - if c.Labels == nil { - c.Labels = map[string]string{} - } - - c.Labels["id"] = id - c.Labels["version"] = version.Version - - return nil -} - -func removeServiceCredentials(x any) error { - switch x := x.(type) { - case nil: - return nil - case []any: - for _, v := range x { - err := removeKey(v, "credentials") - if err != nil { - return err - } - } - - case map[string]any: - for _, v := range x { - err := removeKey(v, "credentials") - if err != nil { - return err - } - } - default: - return fmt.Errorf("illegal service config type: %T", x) - } - - return nil -} - -func removeCryptoKeys(x any) error { - switch x := x.(type) { - case nil: - return nil - case map[string]any: - for _, v := range x { - err := removeKey(v, "key", "private_key") - if err != nil { - return err - } - } - default: - return fmt.Errorf("illegal keys config type: %T", x) - } - - return nil -} - -func removeKey(x any, keys ...string) error { - val, ok := x.(map[string]any) - if !ok { - return errors.New("type assertion error") - } - - for _, key := range keys { - delete(val, key) - } - - return nil -} - -const ( - defaultDecisionPath = "/system/main" - defaultAuthorizationDecisionPath = "/system/authz/allow" -) diff --git a/vendor/github.com/open-policy-agent/opa/v1/format/format.go b/vendor/github.com/open-policy-agent/opa/v1/format/format.go index 75514d39c001..c14a6ce798b0 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/format/format.go +++ b/vendor/github.com/open-policy-agent/opa/v1/format/format.go @@ -9,7 +9,6 @@ import ( "bytes" "errors" "fmt" - "regexp" "slices" "sort" "strings" @@ -27,11 +26,8 @@ import ( const defaultLocationFile = "__format_default__" var ( - elseVar ast.Value = ast.Var("else") - expandedConst = ast.NewBody(ast.NewExpr(ast.InternedTerm(true))) commentsSlicePool = util.NewSlicePool[*ast.Comment](50) - varRegexp = regexp.MustCompile("^[[:alpha:]_][[:alpha:][:digit:]_]*$") ) // Opts lets you control the code formatting via `AstWithOpts()`. @@ -732,7 +728,7 @@ func (w *writer) writeElse(rule *ast.Rule, comments []*ast.Comment) ([]*ast.Comm rule.Else.Head.Name = "else" // NOTE(sr): whaaat - elseHeadReference := ast.NewTerm(elseVar) // construct a reference for the term + elseHeadReference := ast.VarTerm("else") // 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} @@ -1284,6 +1280,11 @@ func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Co } } + case *ast.TemplateString: + comments, err = w.writeTemplateString(x, comments) + if err != nil { + return nil, err + } case ast.Var: w.write(w.formatVar(x)) case ast.Call: @@ -1301,6 +1302,91 @@ func (w *writer) writeTermParens(parens bool, term *ast.Term, comments []*ast.Co return comments, nil } +func (w *writer) writeTemplateString(ts *ast.TemplateString, comments []*ast.Comment) ([]*ast.Comment, error) { + w.write("$") + if ts.MultiLine { + w.write("`") + } else { + w.write(`"`) + } + + for i, p := range ts.Parts { + switch x := p.(type) { + case *ast.Expr: + w.write("{") + w.up() + + if w.beforeEnd != nil { + // We have a comment on the same line as the opening template-expression brace '{' + w.endLine() + w.startLine() + } else { + // We might have comments to write; the first of which should be on the same line as the opening template-expression brace '{' + before, _, _ := partitionComments(comments, x.Location) + if len(before) > 0 { + w.write(" ") + w.inline = true + if err := w.writeComments(before); err != nil { + return nil, err + } + + comments = comments[len(before):] + } + } + + var err error + comments, err = w.writeExpr(x, comments) + if err != nil { + return comments, err + } + + // write trailing comments + if i+1 < len(ts.Parts) { + before, _, _ := partitionComments(comments, ts.Parts[i+1].Loc()) + if len(before) > 0 { + w.endLine() + if err := w.writeComments(before); err != nil { + return nil, err + } + + comments = comments[len(before):] + w.startLine() + } + } + + w.write("}") + + if err := w.down(); err != nil { + return nil, err + } + case *ast.Term: + if s, ok := x.Value.(ast.String); ok { + if ts.MultiLine { + w.write(ast.EscapeTemplateStringStringPart(string(s))) + } else { + str := ast.EscapeTemplateStringStringPart(s.String()) + w.write(str[1 : len(str)-1]) + } + } else { + s := x.String() + s = strings.TrimPrefix(s, "\"") + s = strings.TrimSuffix(s, "\"") + w.write(s) + } + default: + w.write("") + } + } + + if ts.MultiLine { + w.write("`") + } else { + w.write(`"`) + } + + return comments, nil +} + func (w *writer) writeRef(x ast.Ref, comments []*ast.Comment) ([]*ast.Comment, error) { if len(x) > 0 { parens := false @@ -1353,7 +1439,7 @@ func (w *writer) writeRefStringPath(s ast.String, l *ast.Location) { } func (w *writer) shouldBracketRefTerm(s string, l *ast.Location) bool { - if !varRegexp.MatchString(s) { + if !ast.IsVarCompatibleString(s) { return true } @@ -1931,7 +2017,7 @@ func partitionComments(comments []*ast.Comment, l *ast.Location) ([]*ast.Comment var at *ast.Comment before := make([]*ast.Comment, 0, numBefore) - after := comments[0 : 0 : len(comments)-numBefore] + after := make([]*ast.Comment, 0, numAfter) for _, c := range comments { switch cmp := c.Location.Row - l.Row; { diff --git a/vendor/github.com/open-policy-agent/opa/v1/hooks/hooks.go b/vendor/github.com/open-policy-agent/opa/v1/hooks/hooks.go deleted file mode 100644 index cb756e5020f4..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/hooks/hooks.go +++ /dev/null @@ -1,97 +0,0 @@ -// 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. - -package hooks - -import ( - "context" - "fmt" - - "github.com/open-policy-agent/opa/v1/config" - topdown_cache "github.com/open-policy-agent/opa/v1/topdown/cache" -) - -// Hook is a hook to be called in some select places in OPA's operation. -// -// The base Hook interface is any, and wherever a hook can occur, the calling code -// will check if your hook implements an appropriate interface. If so, your hook -// is called. -// -// This allows you to only hook in to behavior you care about, and it allows the -// OPA to add more hooks in the future. -// -// All hook interfaces in this package have Hook in the name. Hooks must be safe -// for concurrent use. It is expected that hooks are fast; if a hook needs to take -// time, then copy what you need and ensure the hook is async. -// -// When multiple instances of a hook are provided, they are all going to be executed -// in an unspecified order (it's a map-range call underneath). If you need hooks to -// be run in order, you can wrap them into another hook, and configure that one. -type Hook any - -// Hooks is the type used for every struct in OPA that can work with hooks. -type Hooks struct { - m map[Hook]struct{} // we are NOT providing a stable invocation ordering -} - -// New creates a new instance of Hooks. -func New(hs ...Hook) Hooks { - h := Hooks{m: make(map[Hook]struct{}, len(hs))} - for i := range hs { - h.m[hs[i]] = struct{}{} - } - return h -} - -func (hs Hooks) Each(fn func(Hook)) { - for h := range hs.m { - fn(h) - } -} - -func (hs Hooks) Len() int { - return len(hs.m) -} - -// ConfigHook allows inspecting or rewriting the configuration when the plugin -// manager is processing it. -// Note that this hook is not run when the plugin manager is reconfigured. This -// usually only happens when there's a new config from a discovery bundle, and -// for processing _that_, there's `ConfigDiscoveryHook`. -type ConfigHook interface { - OnConfig(context.Context, *config.Config) (*config.Config, error) -} - -// ConfigHook allows inspecting or rewriting the discovered configuration when -// the discovery plugin is processing it. -type ConfigDiscoveryHook interface { - OnConfigDiscovery(context.Context, *config.Config) (*config.Config, error) -} - -// InterQueryCacheHook allows access to the server's inter-query cache instance. -// It's useful for out-of-tree handlers that also need to evaluate something. -// Using this hook, they can share the caches with the rest of OPA. -type InterQueryCacheHook interface { - OnInterQueryCache(context.Context, topdown_cache.InterQueryCache) error -} - -// InterQueryValueCacheHook allows access to the server's inter-query value cache -// instance. -type InterQueryValueCacheHook interface { - OnInterQueryValueCache(context.Context, topdown_cache.InterQueryValueCache) error -} - -func (hs Hooks) Validate() error { - for h := range hs.m { - switch h.(type) { - case InterQueryCacheHook, - InterQueryValueCacheHook, - ConfigHook, - ConfigDiscoveryHook: // OK - default: - return fmt.Errorf("unknown hook type %T", h) - } - } - return nil -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/loader/loader.go b/vendor/github.com/open-policy-agent/opa/v1/loader/loader.go index 42a59d031f1d..d97e3e5409b3 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/loader/loader.go +++ b/vendor/github.com/open-policy-agent/opa/v1/loader/loader.go @@ -495,6 +495,7 @@ func loadOneSchema(path string) (any, error) { } // All returns a Result object loaded (recursively) from the specified paths. +// // Deprecated: Use FileLoader.Filtered() instead. func All(paths []string) (*Result, error) { return NewFileLoader().Filtered(paths, nil) @@ -503,6 +504,7 @@ func All(paths []string) (*Result, error) { // Filtered returns a Result object loaded (recursively) from the specified // paths while applying the given filters. If any filter returns true, the // file/directory is excluded. +// // Deprecated: Use FileLoader.Filtered() instead. func Filtered(paths []string, filter Filter) (*Result, error) { return NewFileLoader().Filtered(paths, filter) @@ -511,6 +513,7 @@ func Filtered(paths []string, filter Filter) (*Result, error) { // AsBundle loads a path as a bundle. If it is a single file // it will be treated as a normal tarball bundle. If a directory // is supplied it will be loaded as an unzipped bundle tree. +// // Deprecated: Use FileLoader.AsBundle() instead. func AsBundle(path string) (*bundle.Bundle, error) { return NewFileLoader().AsBundle(path) @@ -631,11 +634,10 @@ func (l *Result) mergeDocument(path string, doc any) error { } func (l *Result) withParent(p string) *Result { - path := append(l.path, p) return &Result{ Documents: l.Documents, Modules: l.Modules, - path: path, + path: append(l.path, p), } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/plugins/plugins.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/plugins.go deleted file mode 100644 index ca8df1ee48b0..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/plugins/plugins.go +++ /dev/null @@ -1,1195 +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 plugins implements plugin management for the policy engine. -package plugins - -import ( - "context" - "errors" - "fmt" - "maps" - mr "math/rand" - "net/http" - "sync" - "time" - - "github.com/open-policy-agent/opa/internal/report" - "github.com/prometheus/client_golang/prometheus" - "go.opentelemetry.io/otel/sdk/trace" - - 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/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. -// -// When OPA processes it's configuration it looks for factories that -// have been registered by calling runtime.RegisterPlugin. Factories -// are registered to a name which is used to key into the -// configuration blob. If your plugin has not been configured, your -// factory will not be invoked. -// -// plugins: -// my_plugin1: -// some_key: foo -// # my_plugin2: -// # some_key2: bar -// -// If OPA was started with the configuration above and received two -// calls to runtime.RegisterPlugins (one with NAME "my_plugin1" and -// one with NAME "my_plugin2"), it would only invoke the factory for -// for my_plugin1. -// -// OPA instantiates and reconfigures plugins in two steps. First, OPA -// will call Validate to check the configuration. Assuming the -// configuration is valid, your factory should return a configuration -// value that can be used to construct your plugin. Second, OPA will -// call New to instantiate your plugin providing the configuration -// value returned from the Validate call. -// -// Validate receives a slice of bytes representing plugin -// configuration and returns a configuration value that can be used to -// instantiate your plugin. The manager is provided to give access to -// the OPA's compiler, storage layer, and global configuration. Your -// Validate function will typically: -// -// 1. Deserialize the raw config bytes -// 2. Validate the deserialized config for semantic errors -// 3. Inject default values -// 4. Return a deserialized/parsed config -// -// New receives a valid configuration for your plugin and returns a -// plugin object. Your New function will typically: -// -// 1. Cast the config value to it's own type -// 2. Instantiate a plugin object -// 3. Return the plugin object -// 4. Update status via `plugins.Manager#UpdatePluginStatus` -// -// After a plugin has been created subsequent status updates can be -// send anytime the plugin enters a ready or error state. -type Factory interface { - Validate(manager *Manager, config []byte) (any, error) - New(manager *Manager, config any) Plugin -} - -// Plugin defines the interface OPA uses to manage your plugin. -// -// When OPA starts it will start all of the plugins it was configured -// to instantiate. Each time a new plugin is configured (via -// discovery), OPA will start it. You can use the Start call to spawn -// additional goroutines or perform initialization tasks. -// -// Currently OPA will not call Stop on plugins. -// -// When OPA receives new configuration for your plugin via discovery -// it will first Validate the configuration using your factory and -// then call Reconfigure. -type Plugin interface { - Start(ctx context.Context) error - Stop(ctx context.Context) - Reconfigure(ctx context.Context, config any) -} - -// Triggerable defines the interface plugins use for manual plugin triggers. -type Triggerable interface { - Trigger(context.Context) error -} - -// State defines the state that a Plugin instance is currently -// in with pre-defined states. -type State string - -const ( - // StateNotReady indicates that the Plugin is not in an error state, but isn't - // ready for normal operation yet. This should only happen at - // initialization time. - StateNotReady State = "NOT_READY" - - // StateOK signifies that the Plugin is operating normally. - StateOK State = "OK" - - // StateErr indicates that the Plugin is in an error state and should not - // be considered as functional. - StateErr State = "ERROR" - - // StateWarn indicates the Plugin is operating, but in a potentially dangerous or - // degraded state. It may be used to indicate manual remediation is needed, or to - // alert admins of some other noteworthy state. - StateWarn State = "WARN" -) - -// TriggerMode defines the trigger mode utilized by a Plugin for bundle download, -// log upload etc. -type TriggerMode string - -const ( - // TriggerPeriodic represents periodic polling mechanism - TriggerPeriodic TriggerMode = "periodic" - - // TriggerManual represents manual triggering mechanism - TriggerManual TriggerMode = "manual" - - // DefaultTriggerMode represents default trigger mechanism - DefaultTriggerMode TriggerMode = "periodic" -) - -// default interval between OPA report uploads -var defaultUploadIntervalSec = int64(3600) - -// Status has a Plugin's current status plus an optional Message. -type Status struct { - State State `json:"state"` - Message string `json:"message,omitempty"` -} - -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) - -// Manager implements lifecycle management of plugins and gives plugins access -// to engine-wide components like storage. -type Manager struct { - Store storage.Store - // Config values should be accessed from the thread-safe GetConfig method. - Config *config.Config - Info *ast.Term - ID string - - compiler *ast.Compiler - compilerMux sync.RWMutex - wasmResolvers []*wasm.Resolver - wasmResolversMtx sync.RWMutex - services map[string]rest.Client - keys map[string]*keys.Config - plugins []namedplugin - registeredTriggers []func(storage.Transaction) - mtx sync.Mutex - pluginStatus map[string]*Status - pluginStatusListeners map[string]StatusListener - initBundles map[string]*bundle.Bundle - initFiles loader.Result - maxErrors int - initialized bool - interQueryBuiltinCacheConfig *cache.Config - gracefulShutdownPeriod int - registeredCacheTriggers []func(*cache.Config) - logger logging.Logger - consoleLogger logging.Logger - serverInitialized chan struct{} - serverInitializedOnce sync.Once - printHook print.Hook - enablePrintStatements bool - router *http.ServeMux - prometheusRegister prometheus.Registerer - tracerProvider *trace.TracerProvider - distributedTacingOpts tracing.Options - registeredNDCacheTriggers []func(bool) - registeredTelemetryGatherers map[string]report.Gatherer - bootstrapConfigLabels map[string]string - hooks hooks.Hooks - enableTelemetry bool - reporter report.Reporter - opaReportNotifyCh chan struct{} - stop chan chan struct{} - parserOptions ast.ParserOptions - extraRoutes map[string]ExtraRoute - extraMiddlewares []func(http.Handler) http.Handler - extraAuthorizerRoutes []func(string, []any) bool - bundleActivatorPlugin string -} - -type ( - managerContextKey string - managerWasmResolverKey string -) - -const ( - managerCompilerContextKey = managerContextKey("compiler") - managerWasmResolverContextKey = managerWasmResolverKey("wasmResolvers") -) - -// SetCompilerOnContext puts the compiler into the storage context. Calling this -// function before committing updated policies to storage allows the manager to -// skip parsing and compiling of modules. Instead, the manager will use the -// compiler that was stored on the context. -func SetCompilerOnContext(context *storage.Context, compiler *ast.Compiler) { - context.Put(managerCompilerContextKey, compiler) -} - -// GetCompilerOnContext gets the compiler cached on the storage context. -func GetCompilerOnContext(context *storage.Context) *ast.Compiler { - compiler, ok := context.Get(managerCompilerContextKey).(*ast.Compiler) - if !ok { - return nil - } - return compiler -} - -// SetWasmResolversOnContext puts a set of Wasm Resolvers into the storage -// context. Calling this function before committing updated wasm modules to -// storage allows the manager to skip initializing modules before using them. -// Instead, the manager will use the compiler that was stored on the context. -func SetWasmResolversOnContext(context *storage.Context, rs []*wasm.Resolver) { - context.Put(managerWasmResolverContextKey, rs) -} - -// getWasmResolversOnContext gets the resolvers cached on the storage context. -func getWasmResolversOnContext(context *storage.Context) []*wasm.Resolver { - resolvers, ok := context.Get(managerWasmResolverContextKey).([]*wasm.Resolver) - if !ok { - return nil - } - return resolvers -} - -func validateTriggerMode(mode TriggerMode) error { - switch mode { - case TriggerPeriodic, TriggerManual: - return nil - default: - return fmt.Errorf("invalid trigger mode %q (want %q or %q)", mode, TriggerPeriodic, TriggerManual) - } -} - -// ValidateAndInjectDefaultsForTriggerMode validates the trigger mode and injects default values -func ValidateAndInjectDefaultsForTriggerMode(a, b *TriggerMode) (*TriggerMode, error) { - if a == nil && b != nil { - err := validateTriggerMode(*b) - if err != nil { - return nil, err - } - return b, nil - } else if a != nil && b == nil { - err := validateTriggerMode(*a) - if err != nil { - return nil, err - } - return a, nil - } else if a != nil && b != nil { - if *a != *b { - return nil, fmt.Errorf("trigger mode mismatch: %s and %s (hint: check discovery configuration)", *a, *b) - } - err := validateTriggerMode(*a) - if err != nil { - return nil, err - } - return a, nil - } - - t := DefaultTriggerMode - return &t, nil -} - -type namedplugin struct { - name string - plugin Plugin -} - -// Info sets the runtime information on the manager. The runtime information is -// propagated to opa.runtime() built-in function calls. -func Info(term *ast.Term) func(*Manager) { - return func(m *Manager) { - m.Info = term - } -} - -// InitBundles provides the initial set of bundles to load. -func InitBundles(b map[string]*bundle.Bundle) func(*Manager) { - return func(m *Manager) { - m.initBundles = b - } -} - -// InitFiles provides the initial set of other data/policy files to load. -func InitFiles(f loader.Result) func(*Manager) { - return func(m *Manager) { - m.initFiles = f - } -} - -// MaxErrors sets the error limit for the manager's shared compiler. -func MaxErrors(n int) func(*Manager) { - return func(m *Manager) { - m.maxErrors = n - } -} - -// GracefulShutdownPeriod passes the configured graceful shutdown period to plugins -func GracefulShutdownPeriod(gracefulShutdownPeriod int) func(*Manager) { - return func(m *Manager) { - m.gracefulShutdownPeriod = gracefulShutdownPeriod - } -} - -// Logger configures the passed logger on the plugin manager (useful to -// configure default fields) -func Logger(logger logging.Logger) func(*Manager) { - return func(m *Manager) { - m.logger = logger - } -} - -// ConsoleLogger sets the passed logger to be used by plugins that are -// configured with console logging enabled. -func ConsoleLogger(logger logging.Logger) func(*Manager) { - return func(m *Manager) { - m.consoleLogger = logger - } -} - -func EnablePrintStatements(yes bool) func(*Manager) { - return func(m *Manager) { - m.enablePrintStatements = yes - } -} - -func PrintHook(h print.Hook) func(*Manager) { - return func(m *Manager) { - m.printHook = h - } -} - -func WithRouter(r *http.ServeMux) func(*Manager) { - return func(m *Manager) { - m.router = r - } -} - -// WithPrometheusRegister sets the passed prometheus.Registerer to be used by plugins -func WithPrometheusRegister(prometheusRegister prometheus.Registerer) func(*Manager) { - return func(m *Manager) { - m.prometheusRegister = prometheusRegister - } -} - -// WithTracerProvider sets the passed *trace.TracerProvider to be used by plugins -func WithTracerProvider(tracerProvider *trace.TracerProvider) func(*Manager) { - return func(m *Manager) { - m.tracerProvider = tracerProvider - } -} - -// WithDistributedTracingOpts sets the options to be used by distributed tracing. -func WithDistributedTracingOpts(tr tracing.Options) func(*Manager) { - return func(m *Manager) { - m.distributedTacingOpts = tr - } -} - -// WithHooks allows passing hooks to the plugin manager. -func WithHooks(hs hooks.Hooks) func(*Manager) { - return func(m *Manager) { - m.hooks = hs - } -} - -// WithParserOptions sets the parser options to be used by the plugin manager. -func WithParserOptions(opts ast.ParserOptions) func(*Manager) { - return func(m *Manager) { - m.parserOptions = opts - } -} - -// WithEnableTelemetry controls whether OPA will send telemetry reports to an external service. -func WithEnableTelemetry(enableTelemetry bool) func(*Manager) { - return func(m *Manager) { - m.enableTelemetry = enableTelemetry - } -} - -// WithTelemetryGatherers allows registration of telemetry gatherers which enable injection of additional data in the -// telemetry report -func WithTelemetryGatherers(gs map[string]report.Gatherer) func(*Manager) { - return func(m *Manager) { - m.registeredTelemetryGatherers = gs - } -} - -// WithBundleActivatorPlugin sets the name of the activator plugin to load bundles into the store -func WithBundleActivatorPlugin(bundleActivatorPlugin string) func(*Manager) { - return func(m *Manager) { - m.bundleActivatorPlugin = bundleActivatorPlugin - } -} - -// New creates a new Manager using config. -func New(raw []byte, id string, store storage.Store, opts ...func(*Manager)) (*Manager, error) { - parsedConfig, err := config.ParseConfig(raw, id) - if err != nil { - return nil, err - } - - m := &Manager{ - Store: store, - Config: parsedConfig, - ID: id, - pluginStatus: map[string]*Status{}, - pluginStatusListeners: map[string]StatusListener{}, - maxErrors: -1, - serverInitialized: make(chan struct{}), - bootstrapConfigLabels: parsedConfig.Labels, - extraRoutes: map[string]ExtraRoute{}, - } - - for _, f := range opts { - 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() - } - - if m.consoleLogger == nil { - m.consoleLogger = logging.New() - } - - m.hooks.Each(func(h hooks.Hook) { - if f, ok := h.(hooks.ConfigHook); ok { - if c, e := f.OnConfig(context.Background(), parsedConfig); e != nil { - err = errors.Join(err, e) - } else { - parsedConfig = c - } - } - }) - if err != nil { - return nil, err - } - - // do after options and overrides - m.keys, err = keys.ParseKeysConfig(parsedConfig.Keys) - if err != nil { - return nil, err - } - - m.interQueryBuiltinCacheConfig, err = cache.ParseCachingConfig(parsedConfig.Caching) - if err != nil { - return nil, err - } - - serviceOpts := m.DefaultServiceOpts(parsedConfig) - - m.services, err = cfg.ParseServicesConfig(serviceOpts) - if err != nil { - return nil, err - } - - if m.enableTelemetry { - reporter, err := report.New(report.Options{Logger: m.logger}) - if err != nil { - return nil, err - } - m.reporter = reporter - - m.reporter.RegisterGatherer("min_compatible_version", func(_ context.Context) (any, error) { - var minimumCompatibleVersion string - if c := m.GetCompiler(); c != nil && c.Required != nil { - minimumCompatibleVersion, _ = c.Required.MinimumCompatibleVersion() - } - return minimumCompatibleVersion, nil - }) - - // register any additional gatherers - for k, g := range m.registeredTelemetryGatherers { - m.reporter.RegisterGatherer(k, g) - } - } - - return m, nil -} - -// Init returns an error if the manager could not initialize itself. Init() should -// be called before Start(). Init() is idempotent. -func (m *Manager) Init(ctx context.Context) error { - if m.initialized { - return nil - } - - params := storage.TransactionParams{ - Write: true, - Context: storage.NewContext(), - } - - if m.enableTelemetry { - m.opaReportNotifyCh = make(chan struct{}) - m.stop = make(chan chan struct{}) - go m.sendOPAUpdateLoop(ctx) - } - - err := storage.Txn(ctx, m.Store, params, func(txn storage.Transaction) error { - result, err := initload.InsertAndCompile(ctx, initload.InsertAndCompileOptions{ - Store: m.Store, - Txn: txn, - Files: m.initFiles, - Bundles: m.initBundles, - MaxErrors: m.maxErrors, - EnablePrintStatements: m.enablePrintStatements, - ParserOptions: m.parserOptions, - BundleActivatorPlugin: m.bundleActivatorPlugin, - }) - if err != nil { - return err - } - - SetCompilerOnContext(params.Context, result.Compiler) - - resolvers, err := bundleUtils.LoadWasmResolversFromStore(ctx, m.Store, txn, nil) - if err != nil { - return err - } - SetWasmResolversOnContext(params.Context, resolvers) - - _, err = m.Store.Register(ctx, txn, storage.TriggerConfig{OnCommit: m.onCommit}) - return err - }) - if err != nil { - if m.stop != nil { - done := make(chan struct{}) - m.stop <- done - <-done - } - - return err - } - - m.initialized = true - return nil -} - -// Labels returns the set of labels from the configuration. -func (m *Manager) Labels() map[string]string { - m.mtx.Lock() - defer m.mtx.Unlock() - - return maps.Clone(m.Config.Labels) -} - -// InterQueryBuiltinCacheConfig returns the configuration for the inter-query caches. -func (m *Manager) InterQueryBuiltinCacheConfig() *cache.Config { - m.mtx.Lock() - defer m.mtx.Unlock() - - return m.interQueryBuiltinCacheConfig.Clone() -} - -// GetConfig returns a deep copy of the manager's configuration. -func (m *Manager) GetConfig() *config.Config { - m.mtx.Lock() - defer m.mtx.Unlock() - - return m.Config.Clone() -} - -// Register adds a plugin to the manager. When the manager is started, all of -// the plugins will be started. -func (m *Manager) Register(name string, plugin Plugin) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.plugins = append(m.plugins, namedplugin{ - name: name, - plugin: plugin, - }) - if _, ok := m.pluginStatus[name]; !ok { - m.pluginStatus[name] = &Status{State: StateNotReady} - } -} - -// Plugins returns the list of plugins registered with the manager. -func (m *Manager) Plugins() []string { - m.mtx.Lock() - defer m.mtx.Unlock() - result := make([]string, len(m.plugins)) - for i := range m.plugins { - result[i] = m.plugins[i].name - } - return result -} - -// Plugin returns the plugin registered with name or nil if name is not found. -func (m *Manager) Plugin(name string) Plugin { - m.mtx.Lock() - defer m.mtx.Unlock() - for i := range m.plugins { - if m.plugins[i].name == name { - return m.plugins[i].plugin - } - } - return nil -} - -// AuthPlugin returns the HTTPAuthPlugin registered with name or nil if name is not found. -func (m *Manager) AuthPlugin(name string) rest.HTTPAuthPlugin { - m.mtx.Lock() - defer m.mtx.Unlock() - for i := range m.plugins { - if m.plugins[i].name == name { - return m.plugins[i].plugin.(rest.HTTPAuthPlugin) - } - } - return nil -} - -// GetCompiler returns the manager's compiler. -func (m *Manager) GetCompiler() *ast.Compiler { - m.compilerMux.RLock() - defer m.compilerMux.RUnlock() - return m.compiler -} - -func (m *Manager) setCompiler(compiler *ast.Compiler) { - m.compilerMux.Lock() - defer m.compilerMux.Unlock() - m.compiler = compiler -} - -type ExtraRoute struct { - PromName string // name is for prometheus metrics - HandlerFunc http.HandlerFunc -} - -func (m *Manager) ExtraRoutes() map[string]ExtraRoute { - return m.extraRoutes -} - -func (m *Manager) ExtraMiddlewares() []func(http.Handler) http.Handler { - return m.extraMiddlewares -} - -func (m *Manager) ExtraAuthorizerRoutes() []func(string, []any) bool { - return m.extraAuthorizerRoutes -} - -// ExtraRoute registers an extra route to be served by the HTTP -// server later. Using this instead of directly registering routes -// with GetRouter() lets the server apply its handler wrapping for -// Prometheus and OpenTelemetry. -// Caution: This cannot be used to dynamically register and un- -// register HTTP handlers. It's meant as a late-stage set up helper, -// to be called from a plugin's init methods. -func (m *Manager) ExtraRoute(path, name string, hf http.HandlerFunc) { - if _, ok := m.extraRoutes[path]; ok { - panic("extra route already registered: " + path) - } - m.extraRoutes[path] = ExtraRoute{ - PromName: name, - HandlerFunc: hf, - } -} - -// ExtraMiddleware registers extra middlewares (`func(http.Handler) http.Handler`) -// to be injected into the HTTP handler chain in the server later. -// Caution: This cannot be used to dynamically register and un- -// register middlewares. It's meant as a late-stage set up helper, -// to be called from a plugin's init methods. -func (m *Manager) ExtraMiddleware(mw ...func(http.Handler) http.Handler) { - m.extraMiddlewares = append(m.extraMiddlewares, mw...) -} - -// ExtraAuthorizerRoute registers an extra URL path validator function for use -// in the server authorizer. These functions designate specific methods and URL -// prefixes or paths where the authorizer should allow request body parsing. -// Caution: This cannot be used to dynamically register and un- -// register path validator functions. It's meant as a late-stage -// set up helper, to be called from a plugin's init methods. -func (m *Manager) ExtraAuthorizerRoute(validatorFunc func(string, []any) bool) { - m.extraAuthorizerRoutes = append(m.extraAuthorizerRoutes, validatorFunc) -} - -// GetRouter returns the managers router if set -func (m *Manager) GetRouter() *http.ServeMux { - m.mtx.Lock() - defer m.mtx.Unlock() - return m.router -} - -// RegisterCompilerTrigger registers for change notifications when the compiler -// is changed. -func (m *Manager) RegisterCompilerTrigger(f func(storage.Transaction)) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.registeredTriggers = append(m.registeredTriggers, f) -} - -// GetWasmResolvers returns the manager's set of Wasm Resolvers. -func (m *Manager) GetWasmResolvers() []*wasm.Resolver { - m.wasmResolversMtx.RLock() - defer m.wasmResolversMtx.RUnlock() - return m.wasmResolvers -} - -func (m *Manager) setWasmResolvers(rs []*wasm.Resolver) { - m.wasmResolversMtx.Lock() - defer m.wasmResolversMtx.Unlock() - m.wasmResolvers = rs -} - -// Start starts the manager. Init() should be called once before Start(). -func (m *Manager) Start(ctx context.Context) error { - if m == nil { - return nil - } - - if !m.initialized { - if err := m.Init(ctx); err != nil { - return err - } - } - - var toStart []Plugin - - func() { - m.mtx.Lock() - defer m.mtx.Unlock() - toStart = make([]Plugin, len(m.plugins)) - for i := range m.plugins { - toStart[i] = m.plugins[i].plugin - } - }() - - for i := range toStart { - if err := toStart[i].Start(ctx); err != nil { - return err - } - } - - return nil -} - -// Stop stops the manager, stopping all the plugins registered with it. -// Any plugin that needs to perform cleanup should do so within the duration -// of the graceful shutdown period passed with the context as a timeout. -// Note that a graceful shutdown period configured with the Manager instance -// will override the timeout of the passed in context (if applicable). -func (m *Manager) Stop(ctx context.Context) { - var toStop []Plugin - - func() { - m.mtx.Lock() - defer m.mtx.Unlock() - toStop = make([]Plugin, len(m.plugins)) - for i := range m.plugins { - toStop[i] = m.plugins[i].plugin - } - }() - - var cancel context.CancelFunc - if m.gracefulShutdownPeriod > 0 { - ctx, cancel = context.WithTimeout(ctx, time.Duration(m.gracefulShutdownPeriod)*time.Second) - } else { - ctx, cancel = context.WithCancel(ctx) - } - defer cancel() - for i := range toStop { - toStop[i].Stop(ctx) - } - if c, ok := m.Store.(interface{ Close(context.Context) error }); ok { - if err := c.Close(ctx); err != nil { - m.logger.Error("Error closing store: %v", err) - } - } - - if m.stop != nil { - done := make(chan struct{}) - m.stop <- done - <-done - } -} - -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(newCfg *config.Config) error { - config := newCfg.Clone() - - opts := m.DefaultServiceOpts(config) - - keys, err := keys.ParseKeysConfig(config.Keys) - if err != nil { - return err - } - opts.Keys = keys - - services, err := cfg.ParseServicesConfig(opts) - if err != nil { - return err - } - - interQueryBuiltinCacheConfig, err := cache.ParseCachingConfig(config.Caching) - if err != nil { - return err - } - - m.mtx.Lock() - defer m.mtx.Unlock() - - // don't overwrite existing labels, only allow additions - always based on the boostrap config - if config.Labels == nil { - config.Labels = m.bootstrapConfigLabels - } else { - maps.Copy(config.Labels, m.bootstrapConfigLabels) - } - - // don't erase persistence directory - if config.PersistenceDirectory == nil { - // update is ok since we have the lock - config.PersistenceDirectory = m.Config.PersistenceDirectory - } - - m.Config = config - m.interQueryBuiltinCacheConfig = interQueryBuiltinCacheConfig - - maps.Copy(m.services, services) - maps.Copy(m.keys, keys) - - for _, trigger := range m.registeredCacheTriggers { - trigger(interQueryBuiltinCacheConfig) - } - - for _, trigger := range m.registeredNDCacheTriggers { - trigger(config.NDBuiltinCache) - } - - return nil -} - -// PluginStatus returns the current statuses of any plugins registered. -func (m *Manager) PluginStatus() map[string]*Status { - m.mtx.Lock() - defer m.mtx.Unlock() - - return m.copyPluginStatus() -} - -// RegisterPluginStatusListener registers a StatusListener to be -// called when plugin status updates occur. -func (m *Manager) RegisterPluginStatusListener(name string, listener StatusListener) { - m.mtx.Lock() - defer m.mtx.Unlock() - - m.pluginStatusListeners[name] = listener -} - -// UnregisterPluginStatusListener removes a StatusListener registered with the -// same name. -func (m *Manager) UnregisterPluginStatusListener(name string) { - m.mtx.Lock() - defer m.mtx.Unlock() - - delete(m.pluginStatusListeners, name) -} - -// UpdatePluginStatus updates a named plugins status. Any registered -// listeners will be called with a copy of the new state of all -// plugins. -func (m *Manager) UpdatePluginStatus(pluginName string, status *Status) { - var toNotify map[string]StatusListener - var statuses map[string]*Status - - func() { - m.mtx.Lock() - defer m.mtx.Unlock() - m.pluginStatus[pluginName] = status - toNotify = make(map[string]StatusListener, len(m.pluginStatusListeners)) - maps.Copy(toNotify, m.pluginStatusListeners) - statuses = m.copyPluginStatus() - }() - - for _, l := range toNotify { - l(statuses) - } -} - -func (m *Manager) copyPluginStatus() map[string]*Status { - statusCpy := map[string]*Status{} - for k, v := range m.pluginStatus { - var cpy *Status - if v != nil { - cpy = &Status{ - State: v.State, - Message: v.Message, - } - } - statusCpy[k] = cpy - } - return statusCpy -} - -func (m *Manager) onCommit(ctx context.Context, txn storage.Transaction, event storage.TriggerEvent) { - compiler := GetCompilerOnContext(event.Context) - - // If the context does not contain the compiler fallback to loading the - // compiler from the store. Currently the bundle plugin sets the - // compiler on the context but the server does not (nor would users - // implementing their own policy loading.) - if compiler == nil && event.PolicyChanged() { - compiler, _ = loadCompilerFromStore(ctx, m.Store, txn, m.enablePrintStatements, m.ParserOptions()) - } - - if compiler != nil { - m.setCompiler(compiler) - - if m.enableTelemetry && event.PolicyChanged() { - m.opaReportNotifyCh <- struct{}{} - } - - for _, f := range m.registeredTriggers { - f(txn) - } - } - - // Similar to the compiler, look for a set of resolvers on the transaction - // context. If they are not set we may need to reload from the store. - resolvers := getWasmResolversOnContext(event.Context) - if resolvers != nil { - m.setWasmResolvers(resolvers) - } else if event.DataChanged() { - if requiresWasmResolverReload(event) { - resolvers, err := bundleUtils.LoadWasmResolversFromStore(ctx, m.Store, txn, nil) - if err != nil { - panic(err) - } - m.setWasmResolvers(resolvers) - } else { - err := m.updateWasmResolversData(ctx, event) - if err != nil { - panic(err) - } - } - } -} - -func loadCompilerFromStore(ctx context.Context, store storage.Store, txn storage.Transaction, enablePrintStatements bool, popts ast.ParserOptions) (*ast.Compiler, error) { - policies, err := store.ListPolicies(ctx, txn) - if err != nil { - return nil, err - } - modules := map[string]*ast.Module{} - - for _, policy := range policies { - bs, err := store.GetPolicy(ctx, txn, policy) - if err != nil { - return nil, err - } - module, err := ast.ParseModuleWithOpts(policy, string(bs), popts) - if err != nil { - return nil, err - } - modules[policy] = module - } - - compiler := ast.NewCompiler(). - WithEnablePrintStatements(enablePrintStatements) - - if popts.RegoVersion != ast.RegoUndefined { - compiler = compiler.WithDefaultRegoVersion(popts.RegoVersion) - } - - compiler.Compile(modules) - return compiler, nil -} - -func requiresWasmResolverReload(event storage.TriggerEvent) bool { - // If the data changes touched the bundle path (which includes - // the wasm modules) we will reload them. Otherwise update - // data for each module already on the manager. - for _, dataEvent := range event.Data { - if dataEvent.Path.HasPrefix(bundle.BundlesBasePath) { - return true - } - } - return false -} - -func (m *Manager) updateWasmResolversData(ctx context.Context, event storage.TriggerEvent) error { - m.wasmResolversMtx.Lock() - defer m.wasmResolversMtx.Unlock() - - for _, resolver := range m.wasmResolvers { - for _, dataEvent := range event.Data { - var err error - if dataEvent.Removed { - err = resolver.RemoveDataPath(ctx, dataEvent.Path) - } else { - err = resolver.SetDataPath(ctx, dataEvent.Path, dataEvent.Data) - } - if err != nil { - return fmt.Errorf("failed to update wasm runtime data: %s", err) - } - } - } - return nil -} - -// PublicKeys returns a public keys that can be used for verifying signed bundles. -func (m *Manager) PublicKeys() map[string]*keys.Config { - m.mtx.Lock() - defer m.mtx.Unlock() - - if m.keys == nil { - return make(map[string]*keys.Config) - } - - result := make(map[string]*keys.Config, len(m.keys)) - for k, v := range m.keys { - if v != nil { - copied := *v - result[k] = &copied - } - } - return result -} - -// Client returns a client for communicating with a remote service. -func (m *Manager) Client(name string) rest.Client { - m.mtx.Lock() - defer m.mtx.Unlock() - return m.services[name] -} - -// Services returns a list of services that m can provide clients for. -func (m *Manager) Services() []string { - m.mtx.Lock() - defer m.mtx.Unlock() - s := make([]string, 0, len(m.services)) - for name := range m.services { - s = append(s, name) - } - return s -} - -// Logger gets the standard logger for this plugin manager. -func (m *Manager) Logger() logging.Logger { - return m.logger -} - -// ConsoleLogger gets the console logger for this plugin manager. -func (m *Manager) ConsoleLogger() logging.Logger { - return m.consoleLogger -} - -func (m *Manager) PrintHook() print.Hook { - return m.printHook -} - -func (m *Manager) EnablePrintStatements() bool { - return m.enablePrintStatements -} - -// ServerInitialized signals a channel indicating that the OPA -// server has finished initialization. -func (m *Manager) ServerInitialized() { - m.serverInitializedOnce.Do(func() { close(m.serverInitialized) }) -} - -// ServerInitializedChannel returns a receive-only channel that -// is closed when the OPA server has finished initialization. -// Be aware that the socket of the server listener may not be -// open by the time this channel is closed. There is a very -// small window where the socket may still be closed, due to -// a race condition. -func (m *Manager) ServerInitializedChannel() <-chan struct{} { - return m.serverInitialized -} - -// RegisterCacheTrigger accepts a func that receives new inter-query cache config generated by -// a reconfigure of the plugin manager, so that it can be propagated to existing inter-query caches. -func (m *Manager) RegisterCacheTrigger(trigger func(*cache.Config)) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.registeredCacheTriggers = append(m.registeredCacheTriggers, trigger) -} - -// PrometheusRegister gets the prometheus.Registerer for this plugin manager. -func (m *Manager) PrometheusRegister() prometheus.Registerer { - return m.prometheusRegister -} - -// TracerProvider gets the *trace.TracerProvider for this plugin manager. -func (m *Manager) TracerProvider() *trace.TracerProvider { - return m.tracerProvider -} - -func (m *Manager) RegisterNDCacheTrigger(trigger func(bool)) { - m.mtx.Lock() - defer m.mtx.Unlock() - m.registeredNDCacheTriggers = append(m.registeredNDCacheTriggers, trigger) -} - -func (m *Manager) sendOPAUpdateLoop(ctx context.Context) { - ticker := time.NewTicker(time.Duration(int64(time.Second) * defaultUploadIntervalSec)) - mr.New(mr.NewSource(time.Now().UnixNano())) - - ctx, cancel := context.WithCancel(ctx) - - var opaReportNotify bool - - for { - select { - case <-m.opaReportNotifyCh: - opaReportNotify = true - case <-ticker.C: - ticker.Stop() - - if opaReportNotify { - opaReportNotify = false - _, err := m.reporter.SendReport(ctx) - if err != nil { - m.logger.WithFields(map[string]any{"err": err}).Debug("Unable to send OPA telemetry report.") - } - } - - newInterval := mr.Int63n(defaultUploadIntervalSec) + defaultUploadIntervalSec - ticker = time.NewTicker(time.Duration(int64(time.Second) * newInterval)) - case done := <-m.stop: - cancel() - ticker.Stop() - done <- struct{}{} - return - } - } -} - -func (m *Manager) ParserOptions() ast.ParserOptions { - return m.parserOptions -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/auth.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/auth.go deleted file mode 100644 index 8ec337bd1e93..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/auth.go +++ /dev/null @@ -1,1211 +0,0 @@ -// Copyright 2019 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 rest - -import ( - "context" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/sha512" - "crypto/tls" - "crypto/x509" - "encoding/asn1" - "encoding/base64" - "encoding/hex" - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "hash" - "io" - "maps" - "math/big" - "net/http" - "net/url" - "os" - "strings" - "time" - - "github.com/lestrrat-go/jwx/v3/jwa" - "github.com/lestrrat-go/jwx/v3/jws" - "github.com/open-policy-agent/opa/internal/providers/aws" - "github.com/open-policy-agent/opa/internal/uuid" - "github.com/open-policy-agent/opa/v1/keys" - "github.com/open-policy-agent/opa/v1/logging" -) - -const ( - // Default to s3 when the service for sigv4 signing is not specified for backwards compatibility - awsSigv4SigningDefaultService = "s3" - // Default to urn:ietf:params:oauth:client-assertion-type:jwt-bearer for ClientAssertionType when not specified - defaultClientAssertionType = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" -) - -// DefaultTLSConfig defines standard TLS configurations based on the Config -func DefaultTLSConfig(c Config) (*tls.Config, error) { - t := &tls.Config{} - url, err := url.Parse(c.URL) - if err != nil { - return nil, err - } - if url.Scheme == "https" { - t.InsecureSkipVerify = c.AllowInsecureTLS - } - - if c.TLS != nil && c.TLS.CACert != "" { - caCert, err := os.ReadFile(c.TLS.CACert) - if err != nil { - return nil, err - } - - var rootCAs *x509.CertPool - if c.TLS.SystemCARequired { - rootCAs, err = x509.SystemCertPool() - if err != nil { - return nil, err - } - } else { - rootCAs = x509.NewCertPool() - } - - ok := rootCAs.AppendCertsFromPEM(caCert) - if !ok { - return nil, errors.New("unable to parse and append CA certificate to certificate pool") - } - t.RootCAs = rootCAs - } - - return t, nil -} - -// DefaultRoundTripperClient is a reasonable set of defaults for HTTP auth plugins -func DefaultRoundTripperClient(t *tls.Config, timeout int64) *http.Client { - // Ensure we use a http.Transport with proper settings: the zero values are not - // a good choice, as they cause leaking connections: - // https://github.com/golang/go/issues/19620 - - // copy, we don't want to alter the default client's Transport - tr := http.DefaultTransport.(*http.Transport).Clone() - tr.ResponseHeaderTimeout = time.Duration(timeout) * time.Second - tr.TLSClientConfig = t - - c := *http.DefaultClient - c.Transport = tr - return &c -} - -// defaultAuthPlugin represents baseline 'no auth' behavior if no alternative plugin is specified for a service -type defaultAuthPlugin struct{} - -func (*defaultAuthPlugin) NewClient(c Config) (*http.Client, error) { - t, err := DefaultTLSConfig(c) - if err != nil { - return nil, err - } - return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil -} - -func (*defaultAuthPlugin) Prepare(*http.Request) error { - return nil -} - -type serverTLSConfig struct { - CACert string `json:"ca_cert,omitempty"` - SystemCARequired bool `json:"system_ca_required,omitempty"` -} - -// bearerAuthPlugin represents authentication via a bearer token in the HTTP Authorization header -type bearerAuthPlugin struct { - Token string `json:"token"` - TokenPath string `json:"token_path"` - Scheme string `json:"scheme,omitempty"` - - // 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 - } - - if ap.Token != "" && ap.TokenPath != "" { - return nil, errors.New("invalid config: specify a value for either the \"token\" or \"token_path\" field") - } - - if ap.Scheme == "" { - ap.Scheme = "Bearer" - } - - if c.Type == "oci" { - // Standard rest clients use the bearer token as it is defined in the Config - // but the OCIDownloader needs it encoded to base64 before using to sign a request. - ap.encode = true - } - - return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil -} - -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) - if err != nil { - return err - } - token = strings.TrimSpace(string(bytes)) - } - - if ap.encode { - token = base64.StdEncoding.EncodeToString([]byte(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 -} - -type tokenEndpointResponse struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - ExpiresIn int64 `json:"expires_in"` -} - -type awsKmsKeyConfig struct { - Name string `json:"name"` - Algorithm string `json:"algorithm"` -} - -type azureKeyVaultConfig struct { - Key string `json:"key"` - KeyVersion string `json:"key_version"` - Alg string `json:"key_algorithm"` - Vault string `json:"vault"` - URL *url.URL - APIVersion string `json:"api_version"` -} - -func convertSignatureToBase64(alg string, der []byte) (string, error) { - r, s, derErr := pointsFromDER(der) - if derErr != nil { - return "", fmt.Errorf("failed to read points from der %v", derErr) - } - - signatureData, err := convertPointsToBase64(alg, r.Bytes(), s.Bytes()) - if err != nil { - return "", err - } - return signatureData, nil -} - -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 { - return nil, nil, fmt.Errorf("failed to unmarshall the signature from DER format %v", err) - - } - // https://docs.aws.amazon.com/kms/latest/APIReference/API_Sign.html#API_Sign_ResponseSyntax - // https://datatracker.ietf.org/doc/html/rfc3279#section-2.2.3 - // The format of our DER string is 0x02 + rlen + r + 0x02 + slen + s - rLen := data.Bytes[1] // The entire length of R + offset of 2 for 0x02 and rlen - r := data.Bytes[2 : rLen+2] - // Ignore the next 0x02 and slen bytes and just take the start of S to the end of the byte array - s := data.Bytes[rLen+4:] - R.SetBytes(r) - S.SetBytes(s) - return -} - -func convertPointsToBase64(alg string, r, s []byte) (string, error) { - curveBits, err := retrieveCurveBits(alg) - if err != nil { - return "", err - } - keyBytes := curveBits / 8 - if curveBits%8 > 0 { - keyBytes++ - } - // We serialize the outputs (r and s) into big-endian byte arrays and pad - // them with zeros on the left to make sure the sizes work out. Both arrays - // must be keyBytes long, and the output must be 2*keyBytes long. - rBytesPadded := make([]byte, keyBytes) - copy(rBytesPadded[keyBytes-len(r):], r) - sBytesPadded := make([]byte, keyBytes) - copy(sBytesPadded[keyBytes-len(s):], s) - signatureEnc := append(rBytesPadded, sBytesPadded...) - - return base64.RawURLEncoding.EncodeToString(signatureEnc), nil -} - -func retrieveCurveBits(alg string) (int, error) { - var curveBits int - switch alg { - case "ECDSA_SHA_256": - curveBits = 256 - case "ECDSA_SHA_384": - curveBits = 384 - case "ECDSA_SHA_512": - curveBits = 512 - default: - return 0, fmt.Errorf("unsupported sign algorithm %s", alg) - } - return curveBits, nil -} - -func messageDigest(message []byte, alg string) ([]byte, error) { - var digest hash.Hash - - switch alg { - case "ECDSA_SHA_256", "ES256", "ES256K", "PS256", "RS256": - digest = sha256.New() - case "ECDSA_SHA_384", "ES384", "PS384", "RS384": - digest = sha512.New384() - case "ECDSA_SHA_512", "ES512", "PS512", "RS512": - digest = sha512.New() - default: - return []byte{}, fmt.Errorf("unsupported sign algorithm %s", alg) - } - - _, err := digest.Write(message) - if err != nil { - return nil, err - } - return digest.Sum(nil), nil -} - -// oauth2ClientCredentialsAuthPlugin represents authentication via a bearer token in the HTTP Authorization header -// obtained through the OAuth2 client credentials flow -type oauth2ClientCredentialsAuthPlugin struct { - GrantType string `json:"grant_type"` - TokenURL string `json:"token_url"` - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - SigningKeyID string `json:"signing_key"` - Thumbprint string `json:"thumbprint"` - Claims map[string]any `json:"additional_claims"` - IncludeJti bool `json:"include_jti_claim"` - Scopes []string `json:"scopes,omitempty"` - AdditionalHeaders map[string]string `json:"additional_headers,omitempty"` - AdditionalParameters map[string]string `json:"additional_parameters,omitempty"` - AWSKmsKey *awsKmsKeyConfig `json:"aws_kms,omitempty"` - AWSSigningPlugin *awsSigningAuthPlugin `json:"aws_signing,omitempty"` - AzureKeyVault *azureKeyVaultConfig `json:"azure_keyvault,omitempty"` - AzureSigningPlugin *azureSigningAuthPlugin `json:"azure_signing,omitempty"` - ClientAssertionType string `json:"client_assertion_type"` - ClientAssertion string `json:"client_assertion"` - ClientAssertionPath string `json:"client_assertion_path"` - - signingKey *keys.Config - signingKeyParsed any - tokenCache *oauth2Token - tlsSkipVerify bool - logger logging.Logger -} - -type oauth2Token struct { - Token string - ExpiresAt time.Time -} - -func (ap *oauth2ClientCredentialsAuthPlugin) createJWSParts(extClaims map[string]any) ([]byte, []byte, string, error) { - now := time.Now() - claims := map[string]any{ - "iat": now.Unix(), - "exp": now.Add(10 * time.Minute).Unix(), - } - maps.Copy(claims, extClaims) - - if len(ap.Scopes) > 0 { - claims["scope"] = strings.Join(ap.Scopes, " ") - } - - if ap.IncludeJti { - jti, err := uuid.New(rand.Reader) - if err != nil { - return nil, nil, "", err - } - claims["jti"] = jti - } - - payload, err := json.Marshal(claims) - if err != nil { - return nil, nil, "", err - } - - var jwsHeaders []byte - var signatureAlg string - switch { - case ap.AWSKmsKey == nil && ap.AzureKeyVault == nil: - signatureAlg = ap.signingKey.Algorithm - case ap.AWSKmsKey != nil && ap.AWSKmsKey.Algorithm != "": - signatureAlg, err = ap.mapKMSAlgToSign(ap.AWSKmsKey.Algorithm) - if err != nil { - return nil, nil, "", err - } - case ap.AzureKeyVault != nil && ap.AzureKeyVault.Alg != "": - signatureAlg = ap.AzureKeyVault.Alg - } - if ap.Thumbprint != "" { - bytes, err := hex.DecodeString(ap.Thumbprint) - if err != nil { - return nil, nil, "", err - } - x5t := base64.URLEncoding.EncodeToString(bytes) - jwsHeaders = fmt.Appendf(nil, `{"typ":"JWT","alg":"%s","x5t":"%s"}`, signatureAlg, x5t) - } else { - jwsHeaders = fmt.Appendf(nil, `{"typ":"JWT","alg":"%s"}`, signatureAlg) - } - - return jwsHeaders, payload, signatureAlg, nil -} - -func (ap *oauth2ClientCredentialsAuthPlugin) createAuthJWT(ctx context.Context, extClaims map[string]any, signingKey any) (*string, error) { - header, payload, alg, err := ap.createJWSParts(extClaims) - if err != nil { - return nil, err - } - - var clientAssertion []byte - switch { - case ap.AWSKmsKey != nil: - clientAssertion, err = ap.SignWithKMS(ctx, payload, header) - case ap.AzureKeyVault != nil: - clientAssertion, err = ap.SignWithKeyVault(ctx, payload, header) - default: - // Parse the algorithm string to jwa.SignatureAlgorithm - algObj, ok := jwa.LookupSignatureAlgorithm(alg) - if !ok { - return nil, fmt.Errorf("unknown signature algorithm: %s", alg) - } - - // Parse headers - var headers map[string]any - if err := json.Unmarshal(header, &headers); err != nil { - return nil, err - } - - // Create protected headers - protectedHeaders := jws.NewHeaders() - for k, v := range headers { - if err := protectedHeaders.Set(k, v); err != nil { - return nil, err - } - } - - clientAssertion, err = jws.Sign(payload, - jws.WithKey(algObj, signingKey, jws.WithProtectedHeaders(protectedHeaders))) - } - if err != nil { - return nil, err - } - jwt := string(clientAssertion) - - return &jwt, nil -} - -func (*oauth2ClientCredentialsAuthPlugin) mapKMSAlgToSign(alg string) (string, error) { - switch alg { - case "ECDSA_SHA_256": - return "ES256", nil - case "ECDSA_SHA_384": - return "ES384", nil - case "ECDSA_SHA_512": - return "ES512", nil - default: - return "", fmt.Errorf("unsupported sign algorithm %s", alg) - } -} - -// SignWithKMS will sign the JWT in AWS using the key stored in the supplied kmsArn -func (ap *oauth2ClientCredentialsAuthPlugin) SignWithKMS(ctx context.Context, payload []byte, hdrBuf []byte) ([]byte, error) { - - encodedHdr := base64.RawURLEncoding.EncodeToString(hdrBuf) - encodedPayload := base64.RawURLEncoding.EncodeToString(payload) - input := encodedHdr + "." + encodedPayload - digest, err := messageDigest([]byte(input), ap.AWSKmsKey.Algorithm) - if err != nil { - return nil, err - } - if ap.AWSSigningPlugin != nil { - signature, err := ap.AWSSigningPlugin.SignDigest(ctx, digest, ap.AWSKmsKey.Name, ap.AWSKmsKey.Algorithm) - if err != nil { - return nil, err - } - der, err := base64.StdEncoding.DecodeString(signature) - if err != nil { - return nil, err - } - signatureData, err := convertSignatureToBase64(ap.AWSKmsKey.Algorithm, der) - if err != nil { - return nil, err - } - - signedAssertion := input + "." + signatureData - - return []byte(signedAssertion), nil - } - return nil, errors.New("missing AWS credentials, failed to sign the assertion with kms") -} - -func (ap *oauth2ClientCredentialsAuthPlugin) SignWithKeyVault(ctx context.Context, payload []byte, hdrBuf []byte) ([]byte, error) { - if ap.AzureSigningPlugin == nil { - return nil, errors.New("missing Azure credentials, failed to sign the assertion with KeyVault") - } - - encodedHdr := base64.RawURLEncoding.EncodeToString(hdrBuf) - encodedPayload := base64.RawURLEncoding.EncodeToString(payload) - input := encodedHdr + "." + encodedPayload - digest, err := messageDigest([]byte(input), ap.AzureSigningPlugin.keyVaultSignPlugin.config.Alg) - if err != nil { - fmt.Println("unsupported algorithm", ap.AzureSigningPlugin.keyVaultSignPlugin.config.Alg) - return nil, err - } - - signature, err := ap.AzureSigningPlugin.SignDigest(ctx, digest) - if err != nil { - return nil, err - } - - return []byte(input + "." + signature), nil -} - -func (ap *oauth2ClientCredentialsAuthPlugin) parseSigningKey(c Config) (err error) { - if ap.SigningKeyID == "" { - return errors.New("signing_key required for jwt_bearer grant type") - } - - if val, ok := c.keys[ap.SigningKeyID]; ok { - if val.PrivateKey == "" { - return errors.New("referenced signing_key does not include a private key") - } - ap.signingKey = val - } else { - return errors.New("signing_key refers to non-existent key") - } - - alg, ok := jwa.LookupSignatureAlgorithm(ap.signingKey.Algorithm) - if !ok { - return fmt.Errorf("unknown signature algorithm: %s", ap.signingKey.Algorithm) - } - - // Parse the private key directly - keyData := ap.signingKey.PrivateKey - - // For HMAC algorithms, return the key as bytes - if alg == jwa.HS256() || alg == jwa.HS384() || alg == jwa.HS512() { - ap.signingKeyParsed = []byte(keyData) - return nil - } - - // For RSA/ECDSA algorithms, parse the PEM-encoded key - block, _ := pem.Decode([]byte(keyData)) - if block == nil { - return errors.New("failed to decode PEM key") - } - - switch block.Type { - case "RSA PRIVATE KEY": - ap.signingKeyParsed, err = x509.ParsePKCS1PrivateKey(block.Bytes) - case "PRIVATE KEY": - ap.signingKeyParsed, err = x509.ParsePKCS8PrivateKey(block.Bytes) - case "EC PRIVATE KEY": - ap.signingKeyParsed, err = x509.ParseECPrivateKey(block.Bytes) - default: - return fmt.Errorf("unsupported key type: %s", block.Type) - } - - if err != nil { - return err - } - - return nil -} - -func (ap *oauth2ClientCredentialsAuthPlugin) NewClient(c Config) (*http.Client, error) { - t, err := DefaultTLSConfig(c) - if err != nil { - return nil, err - } - - if ap.GrantType == "" { - // Use client_credentials as default to not break existing config - ap.GrantType = grantTypeClientCredentials - } else if ap.GrantType != grantTypeClientCredentials && ap.GrantType != grantTypeJwtBearer { - return nil, errors.New("grant_type must be either client_credentials or jwt_bearer") - } - - if ap.GrantType == grantTypeJwtBearer || (ap.GrantType == grantTypeClientCredentials && ap.SigningKeyID != "") { - if err = ap.parseSigningKey(c); err != nil { - return nil, err - } - } - - // Inherit skip verify from the "parent" settings. Should this be configurable on the credentials too? - ap.tlsSkipVerify = c.AllowInsecureTLS - - ap.logger = c.logger - - if !strings.HasPrefix(ap.TokenURL, "https://") { - return nil, errors.New("token_url required to use https scheme") - } - if ap.GrantType == grantTypeClientCredentials { - clientCredentialExists := make(map[string]bool) - clientCredentialExists["client_secret"] = ap.ClientSecret != "" - clientCredentialExists["signing_key"] = ap.SigningKeyID != "" - clientCredentialExists["aws_kms"] = ap.AWSKmsKey != nil - clientCredentialExists["azure_keyvault"] = ap.AzureKeyVault != nil - clientCredentialExists["client_assertion"] = ap.ClientAssertion != "" - clientCredentialExists["client_assertion_path"] = ap.ClientAssertionPath != "" - - var notEmptyVarCount int - - for _, credentialSet := range clientCredentialExists { - if credentialSet { - notEmptyVarCount++ - } - } - - if notEmptyVarCount == 0 { - return nil, errors.New("please provide one of client_secret, signing_key, aws_kms, azure_keyvault, client_assertion, or client_assertion_path required") - } - - if notEmptyVarCount > 1 { - return nil, errors.New("can only use one of client_secret, signing_key, aws_kms, azure_keyvault, client_assertion, or client_assertion_path") - } - - switch { - case clientCredentialExists["aws_kms"]: - if ap.AWSSigningPlugin == nil { - return nil, errors.New("aws_kms and aws_signing required") - } - // initialize the awsSigningAuthPlugin - _, err = ap.AWSSigningPlugin.NewClient(c) - if err != nil { - return nil, err - } - case clientCredentialExists["azure_keyvault"]: - _, err := ap.AzureSigningPlugin.NewClient(c) - if err != nil { - return nil, err - } - case clientCredentialExists["client_assertion"]: - if ap.ClientAssertionType == "" { - ap.ClientAssertionType = defaultClientAssertionType - } - if ap.ClientID == "" { - return nil, errors.New("client_id and client_assertion required") - } - case clientCredentialExists["client_assertion_path"]: - if ap.ClientAssertionType == "" { - ap.ClientAssertionType = defaultClientAssertionType - } - if ap.ClientID == "" { - return nil, errors.New("client_id and client_assertion_path required") - } - case clientCredentialExists["client_secret"] && ap.ClientID == "": - return nil, errors.New("client_id and client_secret required") - } - } - - return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil -} - -func (ap *oauth2ClientCredentialsAuthPlugin) createTokenReqBody(ctx context.Context) (url.Values, error) { - body := url.Values{} - - if len(ap.Scopes) > 0 { - body.Add("scope", strings.Join(ap.Scopes, " ")) - } - - for k, v := range ap.AdditionalParameters { - body.Set(k, v) - } - - if ap.GrantType == grantTypeJwtBearer { - authJWT, err := ap.createAuthJWT(ctx, ap.Claims, ap.signingKeyParsed) - if err != nil { - return nil, err - } - body.Add("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer") - body.Add("assertion", *authJWT) - return body, nil - } - - body.Add("grant_type", grantTypeClientCredentials) - - switch { - case ap.SigningKeyID != "" || ap.AWSKmsKey != nil || ap.AzureKeyVault != nil: - authJwt, err := ap.createAuthJWT(ctx, ap.Claims, ap.signingKeyParsed) - if err != nil { - return nil, err - } - body.Add("client_assertion_type", defaultClientAssertionType) - body.Add("client_assertion", *authJwt) - - if ap.ClientID != "" { - body.Add("client_id", ap.ClientID) - } - case ap.ClientAssertion != "": - if ap.ClientAssertionType == "" { - ap.ClientAssertionType = defaultClientAssertionType - } - if ap.ClientID != "" { - body.Add("client_id", ap.ClientID) - } - body.Add("client_assertion_type", ap.ClientAssertionType) - body.Add("client_assertion", ap.ClientAssertion) - - case ap.ClientAssertionPath != "": - if ap.ClientAssertionType == "" { - ap.ClientAssertionType = defaultClientAssertionType - } - bytes, err := os.ReadFile(ap.ClientAssertionPath) - if err != nil { - return nil, err - } - if ap.ClientID != "" { - body.Add("client_id", ap.ClientID) - } - body.Add("client_assertion_type", ap.ClientAssertionType) - body.Add("client_assertion", strings.TrimSpace(string(bytes))) - } - - return body, nil -} - -// requestToken tries to obtain an access token using either the client credentials flow -// https://tools.ietf.org/html/rfc6749#section-4.4 -// or the JWT authorization grant -// https://tools.ietf.org/html/rfc7523 -func (ap *oauth2ClientCredentialsAuthPlugin) requestToken(ctx context.Context) (*oauth2Token, error) { - body, err := ap.createTokenReqBody(ctx) - if err != nil { - return nil, err - } - - r, err := http.NewRequestWithContext(ctx, http.MethodPost, ap.TokenURL, strings.NewReader(body.Encode())) - if err != nil { - return nil, err - } - r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - - if ap.GrantType == grantTypeClientCredentials && ap.ClientSecret != "" { - r.SetBasicAuth(ap.ClientID, ap.ClientSecret) - } - - for k, v := range ap.AdditionalHeaders { - r.Header.Add(k, v) - } - - client := DefaultRoundTripperClient(&tls.Config{InsecureSkipVerify: ap.tlsSkipVerify}, 10) - response, err := client.Do(r) - if err != nil { - return nil, err - } - defer response.Body.Close() - - bodyRaw, err := io.ReadAll(response.Body) - if err != nil { - return nil, err - } - - if response.StatusCode != 200 { - return nil, fmt.Errorf("error in response from OAuth2 token endpoint: %v", string(bodyRaw)) - } - - var tokenResponse tokenEndpointResponse - err = json.Unmarshal(bodyRaw, &tokenResponse) - if err != nil { - return nil, err - } - - if !strings.EqualFold(tokenResponse.TokenType, "bearer") { - return nil, errors.New("unknown token type returned from token endpoint") - } - - return &oauth2Token{ - Token: strings.TrimSpace(tokenResponse.AccessToken), - ExpiresAt: time.Now().Add(time.Duration(tokenResponse.ExpiresIn) * time.Second), - }, nil -} - -func (ap *oauth2ClientCredentialsAuthPlugin) Prepare(req *http.Request) error { - minTokenLifetime := float64(10) - if ap.tokenCache == nil || time.Until(ap.tokenCache.ExpiresAt).Seconds() < minTokenLifetime { - ap.logger.Debug("Requesting token from token_url %v", ap.TokenURL) - token, err := ap.requestToken(req.Context()) - if err != nil { - return err - } - ap.tokenCache = token - } - - req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", ap.tokenCache.Token)) - return nil -} - -// clientTLSAuthPlugin represents authentication via client certificate on a TLS connection -type clientTLSAuthPlugin struct { - Cert string `json:"cert"` - PrivateKey string `json:"private_key"` - PrivateKeyPassphrase string `json:"private_key_passphrase,omitempty"` - CACert string `json:"ca_cert,omitempty"` // Deprecated: Use `services[_].tls.ca_cert` instead - SystemCARequired bool `json:"system_ca_required,omitempty"` // Deprecated: Use `services[_].tls.system_ca_required` instead -} - -func (ap *clientTLSAuthPlugin) NewClient(c Config) (*http.Client, error) { - tlsConfig, err := DefaultTLSConfig(c) - if err != nil { - return nil, err - } - - if ap.Cert == "" { - return nil, errors.New("client certificate is needed when client TLS is enabled") - } - if ap.PrivateKey == "" { - return nil, errors.New("private key is needed when client TLS is enabled") - } - - var keyPEMBlock []byte - data, err := os.ReadFile(ap.PrivateKey) - if err != nil { - return nil, err - } - - block, _ := pem.Decode(data) - if block == nil { - return nil, errors.New("PEM data could not be found") - } - - // nolint: staticcheck // We don't want to forbid users from using this encryption. - if x509.IsEncryptedPEMBlock(block) { - if ap.PrivateKeyPassphrase == "" { - return nil, errors.New("client certificate passphrase is needed, because the certificate is password encrypted") - } - // nolint: staticcheck // We don't want to forbid users from using this encryption. - block, err := x509.DecryptPEMBlock(block, []byte(ap.PrivateKeyPassphrase)) - if err != nil { - return nil, err - } - key, err := x509.ParsePKCS8PrivateKey(block) - if err != nil { - key, err = x509.ParsePKCS1PrivateKey(block) - if err != nil { - return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v", err) - } - } - rsa, ok := key.(*rsa.PrivateKey) - if !ok { - return nil, errors.New("private key is invalid") - } - keyPEMBlock = pem.EncodeToMemory( - &pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(rsa), - }, - ) - } else { - keyPEMBlock = data - } - - certPEMBlock, err := os.ReadFile(ap.Cert) - if err != nil { - return nil, err - } - - cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock) - if err != nil { - return nil, err - } - tlsConfig.Certificates = []tls.Certificate{cert} - - var client *http.Client - - if c.TLS != nil && c.TLS.CACert != "" { - client = DefaultRoundTripperClient(tlsConfig, *c.ResponseHeaderTimeoutSeconds) - } else { - if ap.CACert != "" { - c.logger.Warn("Deprecated 'services[_].credentials.client_tls.ca_cert' configuration specified. Use 'services[_].tls.ca_cert' instead. See https://www.openpolicyagent.org/docs/latest/configuration/#services") - caCert, err := os.ReadFile(ap.CACert) - if err != nil { - return nil, err - } - - var caCertPool *x509.CertPool - if ap.SystemCARequired { - caCertPool, err = x509.SystemCertPool() - if err != nil { - return nil, err - } - } else { - caCertPool = x509.NewCertPool() - } - - ok := caCertPool.AppendCertsFromPEM(caCert) - if !ok { - return nil, errors.New("unable to parse and append CA certificate to certificate pool") - } - tlsConfig.RootCAs = caCertPool - } - - client = DefaultRoundTripperClient(tlsConfig, *c.ResponseHeaderTimeoutSeconds) - } - - return client, nil -} - -func (*clientTLSAuthPlugin) Prepare(_ *http.Request) error { - return nil -} - -// awsSigningAuthPlugin represents authentication using AWS V4 HMAC signing in the Authorization header -type awsSigningAuthPlugin struct { - AWSEnvironmentCredentials *awsEnvironmentCredentialService `json:"environment_credentials,omitempty"` - AWSMetadataCredentials *awsMetadataCredentialService `json:"metadata_credentials,omitempty"` - AWSAssumeRoleCredentials *awsAssumeRoleCredentialService `json:"assume_role_credentials,omitempty"` - AWSWebIdentityCredentials *awsWebIdentityCredentialService `json:"web_identity_credentials,omitempty"` - AWSProfileCredentials *awsProfileCredentialService `json:"profile_credentials,omitempty"` - AWSSSOCredentials *awsSSOCredentialsService `json:"sso_credentials,omitempty"` - - AWSService string `json:"service,omitempty"` - AWSSignatureVersion string `json:"signature_version,omitempty"` - - host string - ecrAuthPlugin *ecrAuthPlugin - kmsSignPlugin *awsKMSSignPlugin - - logger logging.Logger -} - -type awsCredentialServiceChain struct { - awsCredentialServices []awsCredentialService - logger logging.Logger -} - -func (acs *awsCredentialServiceChain) addService(service awsCredentialService) { - acs.awsCredentialServices = append(acs.awsCredentialServices, service) -} - -type awsCredentialCheckErrors []*awsCredentialCheckError - -func (e awsCredentialCheckErrors) Error() string { - - if len(e) == 0 { - return "no error(s)" - } - - if len(e) == 1 { - return fmt.Sprintf("1 error occurred: %v", e[0].Error()) - } - - s := make([]string, len(e)) - for i, err := range e { - s[i] = err.Error() - } - - return fmt.Sprintf("%d errors occurred:\n%s", len(e), strings.Join(s, "\n")) -} - -type awsCredentialCheckError struct { - message string -} - -func newAWSCredentialError(message string) *awsCredentialCheckError { - return &awsCredentialCheckError{ - message: message, - } -} - -func (e *awsCredentialCheckError) Error() string { - return e.message -} - -func (acs *awsCredentialServiceChain) credentials(ctx context.Context) (aws.Credentials, error) { - var errs awsCredentialCheckErrors - - for _, service := range acs.awsCredentialServices { - credential, err := service.credentials(ctx) - if err != nil { - acs.logger.Debug("awsSigningAuthPlugin:%T failed: %v", service, err) - - if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { - return aws.Credentials{}, err - } - - errs = append(errs, newAWSCredentialError(err.Error())) - continue - } - - acs.logger.Debug("awsSigningAuthPlugin:%T successful", service) - return credential, nil - } - - return aws.Credentials{}, fmt.Errorf("all AWS credential providers failed: %v", errs) -} - -func (ap *awsSigningAuthPlugin) awsCredentialService() awsCredentialService { - chain := awsCredentialServiceChain{ - logger: ap.logger, - } - - /* - Here we maintain the order of addition to the chain inline with - the order of credential providers followed by default by the - AWS SDK. For example - - https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html - */ - - if ap.AWSEnvironmentCredentials != nil { - ap.AWSEnvironmentCredentials.logger = ap.logger - chain.addService(ap.AWSEnvironmentCredentials) - } - - if ap.AWSAssumeRoleCredentials != nil { - ap.AWSAssumeRoleCredentials.logger = ap.logger - chain.addService(ap.AWSAssumeRoleCredentials) - } - - if ap.AWSWebIdentityCredentials != nil { - ap.AWSWebIdentityCredentials.logger = ap.logger - chain.addService(ap.AWSWebIdentityCredentials) - } - - if ap.AWSProfileCredentials != nil { - ap.AWSProfileCredentials.logger = ap.logger - chain.addService(ap.AWSProfileCredentials) - } - - if ap.AWSMetadataCredentials != nil { - ap.AWSMetadataCredentials.logger = ap.logger - chain.addService(ap.AWSMetadataCredentials) - } - - if ap.AWSSSOCredentials != nil { - ap.AWSSSOCredentials.logger = ap.logger - chain.addService(ap.AWSSSOCredentials) - } - - return &chain -} - -func (ap *awsSigningAuthPlugin) NewClient(c Config) (*http.Client, error) { - t, err := DefaultTLSConfig(c) - if err != nil { - return nil, err - } - - url, err := url.Parse(c.URL) - if err != nil { - return nil, err - } - - ap.host = url.Host - - if ap.logger == nil { - ap.logger = c.logger - } - - if err := ap.validateAndSetDefaults(c.Type); err != nil { - return nil, err - } - - return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil -} - -func (ap *awsSigningAuthPlugin) Prepare(req *http.Request) error { - if ap.host != req.URL.Host { - // Return early if the host does not match. - // This can happen when the OCI registry responded with a redirect to another host. - // For instance, ECR redirects to S3 and the ECR auth header should not be included in the S3 request. - return nil - } - - switch ap.AWSService { - case "ecr": - return ap.ecrAuthPlugin.Prepare(req) - default: - creds, err := ap.awsCredentialService().credentials(req.Context()) - if err != nil { - return fmt.Errorf("failed to get aws credentials: %w", err) - } - - ap.logger.Debug("Signing request with AWS credentials.") - - return aws.SignRequest(req, ap.AWSService, creds, time.Now(), ap.AWSSignatureVersion) - } -} - -func (ap *awsSigningAuthPlugin) validateAndSetDefaults(serviceType string) error { - cfgs := map[bool]int{} - cfgs[ap.AWSEnvironmentCredentials != nil]++ - cfgs[ap.AWSMetadataCredentials != nil]++ - cfgs[ap.AWSAssumeRoleCredentials != nil]++ - cfgs[ap.AWSWebIdentityCredentials != nil]++ - cfgs[ap.AWSProfileCredentials != nil]++ - cfgs[ap.AWSSSOCredentials != nil]++ - - if cfgs[true] == 0 { - return errors.New("a AWS credential service must be specified when S3 signing is enabled") - } - - if ap.AWSMetadataCredentials != nil { - if ap.AWSMetadataCredentials.RegionName == "" { - return errors.New("at least aws_region must be specified for AWS metadata credential service") - } - } - - if ap.AWSAssumeRoleCredentials != nil { - if err := ap.AWSAssumeRoleCredentials.populateFromEnv(); err != nil { - return err - } - } - - if ap.AWSWebIdentityCredentials != nil { - if err := ap.AWSWebIdentityCredentials.populateFromEnv(); err != nil { - return err - } - } - - ap.AWSService = strings.ToLower(ap.AWSService) - - // Only allow ECR for OCI service types - if serviceType == "oci" { - if ap.AWSService == "" { - ap.AWSService = "ecr" - } - - if ap.AWSService != "ecr" { - return fmt.Errorf(`cannot use aws service %q with service type "oci"`, ap.AWSService) - } - - // We need to setup a special auth plugin for ECR. - ap.ecrAuthPlugin = newECRAuthPlugin(ap) - } else { - // Disallow ECR for non-OCI service types - if ap.AWSService == "ecr" { - return errors.New(`aws service "ecr" must be used with service type "oci"`) - } - if ap.AWSService == "kms" && ap.kmsSignPlugin == nil { - // We need a special plugin for KMS. - ap.kmsSignPlugin = newKMSSignPlugin(ap) - } - if ap.AWSService == "" { - ap.AWSService = awsSigv4SigningDefaultService - } - } - - if ap.AWSSignatureVersion == "" { - ap.AWSSignatureVersion = "4" - } - - return nil -} - -func (ap *awsSigningAuthPlugin) SignDigest(ctx context.Context, digest []byte, keyID string, signingAlgorithm string) (string, error) { - switch ap.AWSService { - case "kms": - return ap.kmsSignPlugin.SignDigest(ctx, digest, keyID, signingAlgorithm) - default: - return "", fmt.Errorf(`cannot use SignDigest with aws service %q`, ap.AWSService) - } -} - -type azureSigningAuthPlugin struct { - MIAuthPlugin *azureManagedIdentitiesAuthPlugin `json:"azure_managed_identity,omitempty"` - keyVaultSignPlugin *azureKeyVaultSignPlugin - keyVaultConfig *azureKeyVaultConfig - host string - Service string `json:"service"` - logger logging.Logger -} - -func (ap *azureSigningAuthPlugin) NewClient(c Config) (*http.Client, error) { - t, err := DefaultTLSConfig(c) - if err != nil { - return nil, err - } - - tknURL, err := url.Parse(c.URL) - if err != nil { - return nil, err - } - - ap.host = tknURL.Host - - if ap.logger == nil { - ap.logger = c.logger - } - - if c.Credentials.OAuth2.AzureKeyVault == nil { - return nil, errors.New("missing keyvault config") - } - ap.keyVaultConfig = c.Credentials.OAuth2.AzureKeyVault - - if err := ap.validateAndSetDefaults(); err != nil { - return nil, err - } - - return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil -} - -func (ap *azureSigningAuthPlugin) validateAndSetDefaults() error { - if ap.MIAuthPlugin == nil { - return errors.New("missing azure managed identity config") - } - ap.MIAuthPlugin.setDefaults() - - if ap.keyVaultSignPlugin != nil { - return nil - } - ap.keyVaultConfig.URL = &url.URL{ - Scheme: "https", - Host: ap.keyVaultConfig.Vault + ".vault.azure.net", - } - ap.keyVaultSignPlugin = newKeyVaultSignPlugin(ap.MIAuthPlugin, ap.keyVaultConfig) - ap.keyVaultSignPlugin.setDefaults() - ap.keyVaultConfig = &ap.keyVaultSignPlugin.config - - return nil -} - -func (ap *azureSigningAuthPlugin) Prepare(req *http.Request) error { - switch ap.Service { - case "keyvault": - tkn, err := ap.keyVaultSignPlugin.tokener() - if err != nil { - return err - } - req.Header.Add("Authorization", "Bearer "+tkn) - return nil - default: - return fmt.Errorf("azureSigningAuthPlugin.Prepare() with %s not supported", ap.Service) - } -} - -func (ap *azureSigningAuthPlugin) SignDigest(ctx context.Context, digest []byte) (string, error) { - switch ap.Service { - case "keyvault": - return ap.keyVaultSignPlugin.SignDigest(ctx, digest) - default: - return "", fmt.Errorf(`cannot use SignDigest with azure service %q`, ap.Service) - } -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/aws.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/aws.go deleted file mode 100644 index 45c708ab80d4..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/aws.go +++ /dev/null @@ -1,1088 +0,0 @@ -// Copyright 2019 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 rest - -import ( - "bytes" - "context" - "crypto/sha1" - "encoding/hex" - "encoding/json" - "encoding/xml" - "errors" - "fmt" - "net/http" - "net/url" - "os" - "path" - "path/filepath" - "strings" - "time" - - "github.com/go-ini/ini" - "github.com/open-policy-agent/opa/internal/providers/aws" - "github.com/open-policy-agent/opa/v1/logging" -) - -const ( - // ref. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html - ec2DefaultCredServicePath = "http://169.254.169.254/latest/meta-data/iam/security-credentials/" - - // ref. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html - ec2DefaultTokenPath = "http://169.254.169.254/latest/api/token" - - // ref. https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-iam-roles.html - ecsDefaultCredServicePath = "http://169.254.170.2" - ecsRelativePathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" - ecsFullPathEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" - ecsAuthorizationTokenEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN" - ecsAuthorizationTokenFileEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE" - - // ref. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html - stsDefaultDomain = "amazonaws.com" - stsDefaultPath = "https://sts.%s" - stsRegionPath = "https://sts.%s.%s" - - // ref. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html - accessKeyEnvVar = "AWS_ACCESS_KEY_ID" - secretKeyEnvVar = "AWS_SECRET_ACCESS_KEY" - securityTokenEnvVar = "AWS_SECURITY_TOKEN" - sessionTokenEnvVar = "AWS_SESSION_TOKEN" - awsRegionEnvVar = "AWS_REGION" - awsDomainEnvVar = "AWS_DOMAIN" - awsRoleArnEnvVar = "AWS_ROLE_ARN" - awsWebIdentityTokenFileEnvVar = "AWS_WEB_IDENTITY_TOKEN_FILE" - awsCredentialsFileEnvVar = "AWS_SHARED_CREDENTIALS_FILE" - awsConfigFileEnvVar = "AWS_CONFIG_FILE" - awsProfileEnvVar = "AWS_PROFILE" - - // ref. https://docs.aws.amazon.com/sdkref/latest/guide/settings-global.html - accessKeyGlobalSetting = "aws_access_key_id" - secretKeyGlobalSetting = "aws_secret_access_key" - securityTokenGlobalSetting = "aws_session_token" -) - -// awsCredentialService represents the interface for AWS credential providers -type awsCredentialService interface { - credentials(context.Context) (aws.Credentials, error) -} - -// awsEnvironmentCredentialService represents an static environment-variable credential provider for AWS -type awsEnvironmentCredentialService struct { - logger logging.Logger -} - -func (*awsEnvironmentCredentialService) credentials(context.Context) (aws.Credentials, error) { - var creds aws.Credentials - creds.AccessKey = os.Getenv(accessKeyEnvVar) - if creds.AccessKey == "" { - return creds, errors.New("no " + accessKeyEnvVar + " set in environment") - } - creds.SecretKey = os.Getenv(secretKeyEnvVar) - if creds.SecretKey == "" { - return creds, errors.New("no " + secretKeyEnvVar + " set in environment") - } - creds.RegionName = os.Getenv(awsRegionEnvVar) - if creds.RegionName == "" { - return creds, errors.New("no " + awsRegionEnvVar + " set in environment") - } - // SessionToken is required if using temporary ENV credentials from assumed IAM role - // Missing SessionToken results with 403 s3 error. - creds.SessionToken = os.Getenv(sessionTokenEnvVar) - if creds.SessionToken == "" { - // In case of missing SessionToken try to get SecurityToken - // AWS switched to use SessionToken, but SecurityToken was left for backward compatibility - creds.SessionToken = os.Getenv(securityTokenEnvVar) - } - - return creds, nil -} - -type ssoSessionDetails struct { - StartUrl string `json:"startUrl"` - Region string `json:"region"` - Name string - AccountID string - RoleName string - AccessToken string `json:"accessToken"` - ExpiresAt time.Time `json:"expiresAt"` - RegistrationExpiresAt time.Time `json:"registrationExpiresAt"` - RefreshToken string `json:"refreshToken"` - ClientId string `json:"clientId"` - ClientSecret string `json:"clientSecret"` -} - -type awsSSOCredentialsService struct { - Path string `json:"path,omitempty"` - SSOCachePath string `json:"cache_path,omitempty"` - - Profile string `json:"profile,omitempty"` - - logger logging.Logger - - creds aws.Credentials - - credentialsExpiresAt time.Time - - session *ssoSessionDetails -} - -func (cs *awsSSOCredentialsService) configPath() (string, error) { - if len(cs.Path) != 0 { - return cs.Path, nil - } - - if cs.Path = os.Getenv(awsConfigFileEnvVar); len(cs.Path) != 0 { - return cs.Path, nil - } - - homeDir, err := os.UserHomeDir() - if err != nil { - return "", fmt.Errorf("user home directory not found: %w", err) - } - - cs.Path = filepath.Join(homeDir, ".aws", "config") - - return cs.Path, nil -} -func (cs *awsSSOCredentialsService) ssoCachePath() (string, error) { - if len(cs.SSOCachePath) != 0 { - return cs.SSOCachePath, nil - } - - homeDir, err := os.UserHomeDir() - if err != nil { - return "", fmt.Errorf("user home directory not found: %w", err) - } - - cs.Path = filepath.Join(homeDir, ".aws", "sso", "cache") - - return cs.Path, nil -} - -func (cs *awsSSOCredentialsService) cacheKeyFileName() (string, error) { - - val := cs.session.StartUrl - if cs.session.Name != "" { - val = cs.session.Name - } - - hash := sha1.New() - hash.Write([]byte(val)) - cacheKey := hex.EncodeToString(hash.Sum(nil)) - - return cacheKey + ".json", nil -} - -func (cs *awsSSOCredentialsService) loadSSOCredentials() error { - ssoCachePath, err := cs.ssoCachePath() - if err != nil { - return fmt.Errorf("failed to get sso cache path: %w", err) - } - - cacheKeyFile, err := cs.cacheKeyFileName() - if err != nil { - return err - } - - cacheFile := path.Join(ssoCachePath, cacheKeyFile) - cache, err := os.ReadFile(cacheFile) - if err != nil { - return fmt.Errorf("failed to load cache file: %v", err) - } - - if err := json.Unmarshal(cache, &cs.session); err != nil { - return fmt.Errorf("failed to unmarshal cache file: %v", err) - } - - return nil - -} - -func (cs *awsSSOCredentialsService) loadSession() error { - configPath, err := cs.configPath() - if err != nil { - return fmt.Errorf("failed to get config path: %w", err) - } - config, err := ini.Load(configPath) - if err != nil { - return fmt.Errorf("failed to load config file: %w", err) - } - - section, err := config.GetSection("profile " + cs.Profile) - - if err != nil { - return fmt.Errorf("failed to find profile %s", cs.Profile) - } - - accountID, err := section.GetKey("sso_account_id") - if err != nil { - return fmt.Errorf("failed to find sso_account_id key in profile %s", cs.Profile) - } - - region, err := section.GetKey("region") - if err != nil { - return fmt.Errorf("failed to find region key in profile %s", cs.Profile) - } - - roleName, err := section.GetKey("sso_role_name") - if err != nil { - return fmt.Errorf("failed to find sso_role_name key in profile %s", cs.Profile) - } - - ssoSession, err := section.GetKey("sso_session") - if err != nil { - return fmt.Errorf("failed to find sso_session key in profile %s", cs.Profile) - } - - sessionName := ssoSession.Value() - - session, err := config.GetSection("sso-session " + sessionName) - if err != nil { - return fmt.Errorf("failed to find sso-session %s", sessionName) - } - - startUrl, err := session.GetKey("sso_start_url") - if err != nil { - return fmt.Errorf("failed to find sso_start_url key in sso-session %s", sessionName) - } - - cs.session = &ssoSessionDetails{ - StartUrl: startUrl.Value(), - Name: sessionName, - AccountID: accountID.Value(), - Region: region.Value(), - RoleName: roleName.Value(), - } - - return nil -} - -func (cs *awsSSOCredentialsService) tryRefreshToken() error { - // Check if refresh token is empty - if cs.session.RefreshToken == "" { - return errors.New("refresh token is empty") - } - - // Use the refresh token to get a new access token - // using the clientId, clientSecret and refreshToken from the loaded token - // return the new token - // if error, return error - - type refreshTokenRequest struct { - ClientId string `json:"clientId"` - ClientSecret string `json:"clientSecret"` - RefreshToken string `json:"refreshToken"` - GrantType string `json:"grantType"` - } - - data := refreshTokenRequest{ - ClientId: cs.session.ClientId, - ClientSecret: cs.session.ClientSecret, - RefreshToken: cs.session.RefreshToken, - GrantType: "refresh_token", - } - - body, err := json.Marshal(data) - if err != nil { - return fmt.Errorf("failed to marshal refresh token request: %v", err) - } - - endpoint := fmt.Sprintf("https://oidc.%s.amazonaws.com/token", cs.session.Region) - r, err := http.NewRequest("POST", endpoint, bytes.NewReader(body)) - if err != nil { - return fmt.Errorf("failed to create new request: %v", err) - } - - r.Header.Add("Content-Type", "application/json") - c := &http.Client{} - resp, err := c.Do(r) - if err != nil { - return fmt.Errorf("failed to do request: %v", err) - } - defer resp.Body.Close() - - type refreshTokenResponse struct { - AccessToken string `json:"accessToken"` - ExpiresIn int `json:"expiresIn"` - RefreshToken string `json:"refreshToken"` - } - - refreshedToken := refreshTokenResponse{} - - if err := json.NewDecoder(resp.Body).Decode(&refreshedToken); err != nil { - return fmt.Errorf("failed to decode response: %v", err) - } - - cs.session.AccessToken = refreshedToken.AccessToken - cs.session.ExpiresAt = time.Now().Add(time.Duration(refreshedToken.ExpiresIn) * time.Second) - cs.session.RefreshToken = refreshedToken.RefreshToken - - return nil -} - -func (cs *awsSSOCredentialsService) refreshCredentials() error { - url := fmt.Sprintf("https://portal.sso.%s.amazonaws.com/federation/credentials?account_id=%s&role_name=%s", cs.session.Region, cs.session.AccountID, cs.session.RoleName) - - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return err - } - - req.Header.Set("Authorization", "Bearer "+cs.session.AccessToken) - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - type roleCredentials struct { - AccessKeyId string `json:"accessKeyId"` - SecretAccessKey string `json:"secretAccessKey"` - SessionToken string `json:"sessionToken"` - Expiration int64 `json:"expiration"` - } - type getRoleCredentialsResponse struct { - RoleCredentials roleCredentials `json:"roleCredentials"` - } - - var result getRoleCredentialsResponse - - if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { - return fmt.Errorf("failed to decode response: %v", err) - } - - cs.creds = aws.Credentials{ - AccessKey: result.RoleCredentials.AccessKeyId, - SecretKey: result.RoleCredentials.SecretAccessKey, - SessionToken: result.RoleCredentials.SessionToken, - RegionName: cs.session.Region, - } - - cs.credentialsExpiresAt = time.Unix(result.RoleCredentials.Expiration, 0) - - return nil -} - -func (cs *awsSSOCredentialsService) loadProfile() { - if cs.Profile != "" { - return - } - - cs.Profile = os.Getenv(awsProfileEnvVar) - - if cs.Profile == "" { - cs.Profile = "default" - } - -} - -func (cs *awsSSOCredentialsService) init() error { - cs.loadProfile() - - if err := cs.loadSession(); err != nil { - return fmt.Errorf("failed to load session: %w", err) - } - - if err := cs.loadSSOCredentials(); err != nil { - return fmt.Errorf("failed to load SSO credentials: %w", err) - } - - // this enforces fetching credentials - cs.credentialsExpiresAt = time.Unix(0, 0) - return nil -} - -func (cs *awsSSOCredentialsService) credentials(context.Context) (aws.Credentials, error) { - if cs.session == nil { - if err := cs.init(); err != nil { - return aws.Credentials{}, err - } - } - - if cs.credentialsExpiresAt.Before(time.Now().Add(5 * time.Minute)) { - // Check if the sso token we have is still valid, - // if not, try to refresh it - if cs.session.ExpiresAt.Before(time.Now()) { - // we try and get a new token if we can - if cs.session.RegistrationExpiresAt.Before(time.Now()) { - return aws.Credentials{}, errors.New("cannot refresh token, registration expired") - } - - if err := cs.tryRefreshToken(); err != nil { - return aws.Credentials{}, fmt.Errorf("failed to refresh token: %w", err) - } - } - - if err := cs.refreshCredentials(); err != nil { - return aws.Credentials{}, fmt.Errorf("failed to refresh credentials: %w", err) - } - } - - return cs.creds, nil -} - -// awsProfileCredentialService represents a credential provider for AWS that extracts credentials from the AWS -// credentials file -type awsProfileCredentialService struct { - - // Path to the credentials file. - // - // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the - // env value is empty will default to current user's home directory. - // Linux/OSX: "$HOME/.aws/credentials" - // Windows: "%USERPROFILE%\.aws\credentials" - Path string `json:"path,omitempty"` - - // AWS Profile to extract credentials from the credentials file. If empty - // will default to environment variable "AWS_PROFILE" or "default" if - // environment variable is also not set. - Profile string `json:"profile,omitempty"` - - RegionName string `json:"aws_region"` - - logger logging.Logger -} - -func (cs *awsProfileCredentialService) credentials(context.Context) (aws.Credentials, error) { - var creds aws.Credentials - - filename, err := cs.path() - if err != nil { - return creds, err - } - - cfg, err := ini.Load(filename) - if err != nil { - return creds, fmt.Errorf("failed to read credentials file: %v", err) - } - - profile, err := cfg.GetSection(cs.profile()) - if err != nil { - return creds, fmt.Errorf("failed to get profile: %v", err) - } - - creds.AccessKey = profile.Key(accessKeyGlobalSetting).String() - if creds.AccessKey == "" { - return creds, fmt.Errorf("profile \"%v\" in credentials file %v does not contain \"%v\"", cs.Profile, cs.Path, accessKeyGlobalSetting) - } - - creds.SecretKey = profile.Key(secretKeyGlobalSetting).String() - if creds.SecretKey == "" { - return creds, fmt.Errorf("profile \"%v\" in credentials file %v does not contain \"%v\"", cs.Profile, cs.Path, secretKeyGlobalSetting) - } - - creds.SessionToken = profile.Key(securityTokenGlobalSetting).String() // default to empty string - - if cs.RegionName == "" { - if cs.RegionName = os.Getenv(awsRegionEnvVar); cs.RegionName == "" { - return creds, errors.New("no " + awsRegionEnvVar + " set in environment or configuration") - } - } - creds.RegionName = cs.RegionName - - return creds, nil -} - -func (cs *awsProfileCredentialService) path() (string, error) { - if len(cs.Path) != 0 { - return cs.Path, nil - } - - if cs.Path = os.Getenv(awsCredentialsFileEnvVar); len(cs.Path) != 0 { - return cs.Path, nil - } - - homeDir, err := os.UserHomeDir() - if err != nil { - return "", fmt.Errorf("user home directory not found: %w", err) - } - - cs.Path = filepath.Join(homeDir, ".aws", "credentials") - - return cs.Path, nil -} - -func (cs *awsProfileCredentialService) profile() string { - if cs.Profile != "" { - return cs.Profile - } - - cs.Profile = os.Getenv(awsProfileEnvVar) - - if cs.Profile == "" { - cs.Profile = "default" - } - - return cs.Profile -} - -// awsMetadataCredentialService represents an EC2 metadata service credential provider for AWS -type awsMetadataCredentialService struct { - RoleName string `json:"iam_role,omitempty"` - RegionName string `json:"aws_region"` - creds aws.Credentials - expiration time.Time - credServicePath string - tokenPath string - logger logging.Logger -} - -func (cs *awsMetadataCredentialService) urlForMetadataService() (string, error) { - // override default path for testing - if cs.credServicePath != "" { - return cs.credServicePath + cs.RoleName, nil - } - // otherwise, normal flow - // if a role name is provided, look up via the EC2 credential service - if cs.RoleName != "" { - return ec2DefaultCredServicePath + cs.RoleName, nil - } - // otherwise, check environment to see if it looks like we're in an ECS - // container (with implied role association) - if isECS() { - // first check if the relative env var exists; if so we use that otherwise we - // use the "full" var - if _, relativeExists := os.LookupEnv(ecsRelativePathEnvVar); relativeExists { - return ecsDefaultCredServicePath + os.Getenv(ecsRelativePathEnvVar), nil - } - return os.Getenv(ecsFullPathEnvVar), nil - } - // if there's no role name and we don't appear to have a path to the - // ECS container service, then the configuration is invalid - return "", errors.New("metadata endpoint cannot be determined from settings and environment") -} - -func (cs *awsMetadataCredentialService) tokenRequest(ctx context.Context) (*http.Request, error) { - tokenURL := ec2DefaultTokenPath - if cs.tokenPath != "" { - // override for testing - tokenURL = cs.tokenPath - } - req, err := http.NewRequestWithContext(ctx, http.MethodPut, tokenURL, nil) - if err != nil { - return nil, err - } - - // we are going to use the token in the immediate future, so a long TTL is not necessary - req.Header.Set("X-aws-ec2-metadata-token-ttl-seconds", "60") - return req, nil -} - -func (cs *awsMetadataCredentialService) refreshFromService(ctx context.Context) error { - // define the expected JSON payload from the EC2 credential service - // ref. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html - type metadataPayload struct { - Code string - AccessKeyID string `json:"AccessKeyId"` - SecretAccessKey string - Token string - Expiration time.Time - } - - // Short circuit if a reasonable amount of time until credential expiration remains - const tokenExpirationMargin = 5 * time.Minute - - if time.Now().Add(tokenExpirationMargin).Before(cs.expiration) { - cs.logger.Debug("Credentials previously obtained from metadata service still valid.") - return nil - } - - cs.logger.Debug("Obtaining credentials from metadata service.") - metaDataURL, err := cs.urlForMetadataService() - if err != nil { - // configuration issue or missing ECS environment - return err - } - - // construct an HTTP client with a reasonably short timeout - client := &http.Client{Timeout: time.Second * 10} - req, err := http.NewRequestWithContext(ctx, http.MethodGet, metaDataURL, nil) - if err != nil { - return errors.New("unable to construct metadata HTTP request: " + err.Error()) - } - - // if using the AWS_CONTAINER_CREDENTIALS_FULL_URI variable, we need to associate the token - // to the request - if _, useFullPath := os.LookupEnv(ecsFullPathEnvVar); useFullPath { - var token string - tokenFilePath, tokenFilePathExists := os.LookupEnv(ecsAuthorizationTokenFileEnvVar) - - if tokenFilePathExists { - tokenBytes, err := os.ReadFile(tokenFilePath) - if err != nil { - return errors.New("failed to read ECS metadata authorization token from file: " + err.Error()) - } - token = string(tokenBytes) - // If token doesn't exist as a file check if it exists as an environment variable - } else { - var tokenExists bool - token, tokenExists = os.LookupEnv(ecsAuthorizationTokenEnvVar) - if !tokenExists { - return errors.New("unable to get ECS metadata authorization token") - } - } - req.Header.Set("Authorization", token) - } - - // if in the EC2 environment, we will use IMDSv2, which requires a session cookie from a - // PUT request on the token endpoint before it will give the credentials, this provides - // protection from SSRF attacks - if !isECS() { - tokenReq, err := cs.tokenRequest(ctx) - if err != nil { - return errors.New("unable to construct metadata token HTTP request: " + err.Error()) - } - body, err := aws.DoRequestWithClient(tokenReq, client, "metadata token", cs.logger) - if err != nil { - return err - } - // token is the body of response; add to header of metadata request - req.Header.Set("X-aws-ec2-metadata-token", string(body)) - } - - body, err := aws.DoRequestWithClient(req, client, "metadata", cs.logger) - if err != nil { - return err - } - - var payload metadataPayload - err = json.Unmarshal(body, &payload) - if err != nil { - return errors.New("failed to parse credential response from metadata service: " + err.Error()) - } - - // Only the EC2 endpoint returns the "Code" element which indicates whether the query was - // successful; the ECS endpoint does not! Some other fields are missing in the ECS payload - // but we do not depend on them. - if cs.RoleName != "" && payload.Code != "Success" { - return errors.New("metadata service query did not succeed: " + payload.Code) - } - - cs.expiration = payload.Expiration - cs.creds.AccessKey = payload.AccessKeyID - cs.creds.SecretKey = payload.SecretAccessKey - cs.creds.SessionToken = payload.Token - cs.creds.RegionName = cs.RegionName - - return nil -} - -func (cs *awsMetadataCredentialService) credentials(ctx context.Context) (aws.Credentials, error) { - err := cs.refreshFromService(ctx) - if err != nil { - return cs.creds, err - } - return cs.creds, nil -} - -// awsAssumeRoleCredentialService represents a STS credential service that uses active IAM credentials -// to obtain temporary security credentials generated by AWS STS via AssumeRole API operation -type awsAssumeRoleCredentialService struct { - RegionName string `json:"aws_region"` - RoleArn string `json:"iam_role_arn"` - SessionName string `json:"session_name"` - Domain string `json:"aws_domain"` - AWSSigningPlugin *awsSigningAuthPlugin `json:"aws_signing,omitempty"` - stsURL string - creds aws.Credentials - expiration time.Time - logger logging.Logger -} - -func (cs *awsAssumeRoleCredentialService) populateFromEnv() error { - if cs.AWSSigningPlugin == nil { - return errors.New("a AWS signing plugin must be specified when AssumeRole credential provider is enabled") - } - - switch { - case cs.AWSSigningPlugin.AWSEnvironmentCredentials != nil: - case cs.AWSSigningPlugin.AWSProfileCredentials != nil: - case cs.AWSSigningPlugin.AWSMetadataCredentials != nil: - default: - return errors.New("unsupported AWS signing plugin with AssumeRole credential provider") - } - - if cs.AWSSigningPlugin.AWSMetadataCredentials != nil { - if cs.AWSSigningPlugin.AWSMetadataCredentials.RegionName == "" { - if cs.AWSSigningPlugin.AWSMetadataCredentials.RegionName = os.Getenv(awsRegionEnvVar); cs.AWSSigningPlugin.AWSMetadataCredentials.RegionName == "" { - return errors.New("no " + awsRegionEnvVar + " set in environment or configuration") - } - } - } - - if cs.AWSSigningPlugin.AWSSignatureVersion == "" { - cs.AWSSigningPlugin.AWSSignatureVersion = "4" - } - - if cs.Domain == "" { - cs.Domain = os.Getenv(awsDomainEnvVar) - } - - if cs.RegionName == "" { - if cs.RegionName = os.Getenv(awsRegionEnvVar); cs.RegionName == "" { - return errors.New("no " + awsRegionEnvVar + " set in environment or configuration") - } - } - - if cs.RoleArn == "" { - if cs.RoleArn = os.Getenv(awsRoleArnEnvVar); cs.RoleArn == "" { - return errors.New("no " + awsRoleArnEnvVar + " set in environment or configuration") - } - } - - return nil -} - -func (cs *awsAssumeRoleCredentialService) signingCredentials(ctx context.Context) (aws.Credentials, error) { - if cs.AWSSigningPlugin.AWSEnvironmentCredentials != nil { - cs.AWSSigningPlugin.AWSEnvironmentCredentials.logger = cs.logger - return cs.AWSSigningPlugin.AWSEnvironmentCredentials.credentials(ctx) - } - - if cs.AWSSigningPlugin.AWSProfileCredentials != nil { - cs.AWSSigningPlugin.AWSProfileCredentials.logger = cs.logger - return cs.AWSSigningPlugin.AWSProfileCredentials.credentials(ctx) - } - - cs.AWSSigningPlugin.AWSMetadataCredentials.logger = cs.logger - return cs.AWSSigningPlugin.AWSMetadataCredentials.credentials(ctx) -} - -func (cs *awsAssumeRoleCredentialService) stsPath() string { - return getSTSPath(cs.Domain, cs.stsURL, cs.RegionName) -} - -func (cs *awsAssumeRoleCredentialService) refreshFromService(ctx context.Context) error { - // define the expected JSON payload from the EC2 credential service - // ref. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html - type responsePayload struct { - Result struct { - Credentials struct { - SessionToken string - SecretAccessKey string - Expiration time.Time - AccessKeyID string `xml:"AccessKeyId"` - } - } `xml:"AssumeRoleResult"` - } - - // short circuit if a reasonable amount of time until credential expiration remains - if time.Now().Add(time.Minute * 5).Before(cs.expiration) { - cs.logger.Debug("Credentials previously obtained from sts service still valid.") - return nil - } - - cs.logger.Debug("Obtaining credentials from sts for role %s.", cs.RoleArn) - - var sessionName string - if cs.SessionName == "" { - sessionName = "open-policy-agent" - } else { - sessionName = cs.SessionName - } - - queryVals := url.Values{ - "Action": []string{"AssumeRole"}, - "RoleSessionName": []string{sessionName}, - "RoleArn": []string{cs.RoleArn}, - "Version": []string{"2011-06-15"}, - } - stsRequestURL, _ := url.Parse(cs.stsPath()) - - // construct an HTTP client with a reasonably short timeout - client := &http.Client{Timeout: time.Second * 10} - req, err := http.NewRequestWithContext(ctx, http.MethodPost, stsRequestURL.String(), strings.NewReader(queryVals.Encode())) - if err != nil { - return errors.New("unable to construct STS HTTP request: " + err.Error()) - } - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - // Note: Calls to AWS STS AssumeRole must be signed using the access key ID - // and secret access key - signingCreds, err := cs.signingCredentials(ctx) - if err != nil { - return err - } - - err = aws.SignRequest(req, "sts", signingCreds, time.Now(), cs.AWSSigningPlugin.AWSSignatureVersion) - if err != nil { - return err - } - - body, err := aws.DoRequestWithClient(req, client, "STS", cs.logger) - if err != nil { - return err - } - - var payload responsePayload - err = xml.Unmarshal(body, &payload) - if err != nil { - return errors.New("failed to parse credential response from STS service: " + err.Error()) - } - - cs.expiration = payload.Result.Credentials.Expiration - cs.creds.AccessKey = payload.Result.Credentials.AccessKeyID - cs.creds.SecretKey = payload.Result.Credentials.SecretAccessKey - cs.creds.SessionToken = payload.Result.Credentials.SessionToken - cs.creds.RegionName = cs.RegionName - - return nil -} - -func (cs *awsAssumeRoleCredentialService) credentials(ctx context.Context) (aws.Credentials, error) { - err := cs.refreshFromService(ctx) - if err != nil { - return cs.creds, err - } - return cs.creds, nil -} - -// awsWebIdentityCredentialService represents an STS WebIdentity credential services -type awsWebIdentityCredentialService struct { - RoleArn string - WebIdentityTokenFile string - RegionName string `json:"aws_region"` - SessionName string `json:"session_name"` - Domain string `json:"aws_domain"` - stsURL string - creds aws.Credentials - expiration time.Time - logger logging.Logger -} - -func (cs *awsWebIdentityCredentialService) populateFromEnv() error { - cs.RoleArn = os.Getenv(awsRoleArnEnvVar) - if cs.RoleArn == "" { - return errors.New("no " + awsRoleArnEnvVar + " set in environment") - } - cs.WebIdentityTokenFile = os.Getenv(awsWebIdentityTokenFileEnvVar) - if cs.WebIdentityTokenFile == "" { - return errors.New("no " + awsWebIdentityTokenFileEnvVar + " set in environment") - } - - if cs.Domain == "" { - cs.Domain = os.Getenv(awsDomainEnvVar) - } - - if cs.RegionName == "" { - if cs.RegionName = os.Getenv(awsRegionEnvVar); cs.RegionName == "" { - return errors.New("no " + awsRegionEnvVar + " set in environment or configuration") - } - } - return nil -} - -func (cs *awsWebIdentityCredentialService) stsPath() string { - return getSTSPath(cs.Domain, cs.stsURL, cs.RegionName) -} - -func (cs *awsWebIdentityCredentialService) refreshFromService(ctx context.Context) error { - // define the expected JSON payload from the EC2 credential service - // ref. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html - type responsePayload struct { - Result struct { - Credentials struct { - SessionToken string - SecretAccessKey string - Expiration time.Time - AccessKeyID string `xml:"AccessKeyId"` - } - } `xml:"AssumeRoleWithWebIdentityResult"` - } - - // short circuit if a reasonable amount of time until credential expiration remains - if time.Now().Add(time.Minute * 5).Before(cs.expiration) { - cs.logger.Debug("Credentials previously obtained from sts service still valid.") - return nil - } - - cs.logger.Debug("Obtaining credentials from sts for role %s.", cs.RoleArn) - - var sessionName string - if cs.SessionName == "" { - sessionName = "open-policy-agent" - } else { - sessionName = cs.SessionName - } - - tokenData, err := os.ReadFile(cs.WebIdentityTokenFile) - if err != nil { - return errors.New("unable to read web token for sts HTTP request: " + err.Error()) - } - - token := string(tokenData) - - queryVals := url.Values{ - "Action": []string{"AssumeRoleWithWebIdentity"}, - "RoleSessionName": []string{sessionName}, - "RoleArn": []string{cs.RoleArn}, - "WebIdentityToken": []string{token}, - "Version": []string{"2011-06-15"}, - } - stsRequestURL, _ := url.Parse(cs.stsPath()) - - // construct an HTTP client with a reasonably short timeout - client := &http.Client{Timeout: time.Second * 10} - req, err := http.NewRequestWithContext(ctx, http.MethodPost, stsRequestURL.String(), strings.NewReader(queryVals.Encode())) - if err != nil { - return errors.New("unable to construct STS HTTP request: " + err.Error()) - } - - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - - body, err := aws.DoRequestWithClient(req, client, "STS", cs.logger) - if err != nil { - return err - } - - var payload responsePayload - err = xml.Unmarshal(body, &payload) - if err != nil { - return errors.New("failed to parse credential response from STS service: " + err.Error()) - } - - cs.expiration = payload.Result.Credentials.Expiration - cs.creds.AccessKey = payload.Result.Credentials.AccessKeyID - cs.creds.SecretKey = payload.Result.Credentials.SecretAccessKey - cs.creds.SessionToken = payload.Result.Credentials.SessionToken - cs.creds.RegionName = cs.RegionName - - return nil -} - -func (cs *awsWebIdentityCredentialService) credentials(ctx context.Context) (aws.Credentials, error) { - err := cs.refreshFromService(ctx) - if err != nil { - return cs.creds, err - } - return cs.creds, nil -} - -func isECS() bool { - // the special relative path URI is set by the container agent in the ECS environment only - _, isECSRelative := os.LookupEnv(ecsRelativePathEnvVar) - _, isECSFull := os.LookupEnv(ecsFullPathEnvVar) - return isECSRelative || isECSFull -} - -// ecrAuthPlugin authorizes requests to AWS ECR. -type ecrAuthPlugin struct { - token aws.ECRAuthorizationToken - - // awsAuthPlugin is used to sign ecr authorization token requests. - awsAuthPlugin *awsSigningAuthPlugin - - // ecr represents the service we request tokens from. - ecr ecr - - logger logging.Logger -} - -type ecr interface { - GetAuthorizationToken(context.Context, aws.Credentials, string) (aws.ECRAuthorizationToken, error) -} - -func newECRAuthPlugin(ap *awsSigningAuthPlugin) *ecrAuthPlugin { - return &ecrAuthPlugin{ - awsAuthPlugin: ap, - ecr: aws.NewECR(ap.logger), - logger: ap.logger, - } -} - -// Prepare should be called with any request to AWS ECR. -// It takes care of retrieving an ECR authorization token to sign -// the request with. -func (ap *ecrAuthPlugin) Prepare(r *http.Request) error { - if !ap.token.IsValid() { - ap.logger.Debug("Refreshing ECR auth token") - if err := ap.refreshAuthorizationToken(r.Context()); err != nil { - return err - } - } - - ap.logger.Debug("Signing request with ECR authorization token") - - r.Header.Set("Authorization", "Basic "+ap.token.AuthorizationToken) - return nil -} - -func (ap *ecrAuthPlugin) refreshAuthorizationToken(ctx context.Context) error { - creds, err := ap.awsAuthPlugin.awsCredentialService().credentials(ctx) - if err != nil { - return fmt.Errorf("failed to get aws credentials: %w", err) - } - - token, err := ap.ecr.GetAuthorizationToken(ctx, creds, ap.awsAuthPlugin.AWSSignatureVersion) - if err != nil { - return fmt.Errorf("ecr: failed to get authorization token: %w", err) - } - - ap.token = token - return nil -} - -// awsKMSSignPlugin signs digests using AWS KMS. -type awsKMSSignPlugin struct { - - // awsAuthPlugin is used to sign kms sign requests. - awsAuthPlugin *awsSigningAuthPlugin - - // kms represents the service for signing digests. - kms awskms - - logger logging.Logger -} - -type awskms interface { - SignDigest(ctx context.Context, digest []byte, keyID string, signingAlgorithm string, creds aws.Credentials, signatureVersion string) (string, error) -} - -func newKMSSignPlugin(ap *awsSigningAuthPlugin) *awsKMSSignPlugin { - return &awsKMSSignPlugin{ - awsAuthPlugin: ap, - kms: aws.NewKMS(ap.logger), - logger: ap.logger, - } -} - -func (ap *awsKMSSignPlugin) SignDigest(ctx context.Context, digest []byte, keyID string, signingAlgorithm string) (string, error) { - creds, err := ap.awsAuthPlugin.awsCredentialService().credentials(ctx) - if err != nil { - return "", fmt.Errorf("failed to get aws credentials: %w", err) - } - - signature, err := ap.kms.SignDigest(ctx, digest, keyID, signingAlgorithm, creds, ap.awsAuthPlugin.AWSSignatureVersion) - if err != nil { - return "", fmt.Errorf("kms: failed to sign digest: %w", err) - } - - return signature, nil -} - -func getSTSPath(stsDomain, stsURL, regionName string) string { - var domain string - if stsDomain != "" { - domain = strings.ToLower(stsDomain) - } else { - domain = stsDefaultDomain - } - - var stsPath string - switch { - case stsURL != "": - stsPath = stsURL - case regionName != "": - stsPath = fmt.Sprintf(stsRegionPath, strings.ToLower(regionName), domain) - default: - stsPath = fmt.Sprintf(stsDefaultPath, domain) - } - return stsPath -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/azure.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/azure.go deleted file mode 100644 index 9f7a164327f0..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/azure.go +++ /dev/null @@ -1,287 +0,0 @@ -package rest - -import ( - "bytes" - "context" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "os" - "time" -) - -var ( - azureIMDSEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" - defaultAPIVersion = "2018-02-01" - defaultResource = "https://storage.azure.com/" - timeout = 5 * time.Second - defaultAPIVersionForAppServiceMsi = "2019-08-01" - defaultKeyVaultAPIVersion = "7.4" -) - -// azureManagedIdentitiesToken holds a token for managed identities for Azure resources -type azureManagedIdentitiesToken struct { - AccessToken string `json:"access_token"` - ExpiresIn string `json:"expires_in"` - ExpiresOn string `json:"expires_on"` - NotBefore string `json:"not_before"` - Resource string `json:"resource"` - TokenType string `json:"token_type"` -} - -// azureManagedIdentitiesError represents an error fetching an azureManagedIdentitiesToken -type azureManagedIdentitiesError struct { - Err string `json:"error"` - Description string `json:"error_description"` - Endpoint string - StatusCode int -} - -func (e *azureManagedIdentitiesError) Error() string { - return fmt.Sprintf("%v %s retrieving azure token from %s: %s", e.StatusCode, e.Err, e.Endpoint, e.Description) -} - -// azureManagedIdentitiesAuthPlugin uses an azureManagedIdentitiesToken.AccessToken for bearer authorization -type azureManagedIdentitiesAuthPlugin struct { - Endpoint string `json:"endpoint"` - APIVersion string `json:"api_version"` - Resource string `json:"resource"` - ObjectID string `json:"object_id"` - ClientID string `json:"client_id"` - MiResID string `json:"mi_res_id"` - UseAppServiceMsi bool `json:"use_app_service_msi,omitempty"` -} - -func (ap *azureManagedIdentitiesAuthPlugin) setDefaults() { - if ap.Endpoint == "" { - identityEndpoint := os.Getenv("IDENTITY_ENDPOINT") - if identityEndpoint != "" { - ap.UseAppServiceMsi = true - ap.Endpoint = identityEndpoint - } else { - ap.Endpoint = azureIMDSEndpoint - } - } - - if ap.Resource == "" { - ap.Resource = defaultResource - } - - if ap.APIVersion == "" { - if ap.UseAppServiceMsi { - ap.APIVersion = defaultAPIVersionForAppServiceMsi - } else { - ap.APIVersion = defaultAPIVersion - } - } - -} - -func (ap *azureManagedIdentitiesAuthPlugin) NewClient(c Config) (*http.Client, error) { - if c.Type == "oci" { - return nil, errors.New("azure managed identities auth: OCI service not supported") - } - ap.setDefaults() - t, err := DefaultTLSConfig(c) - if err != nil { - return nil, err - } - - return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil -} - -func (ap *azureManagedIdentitiesAuthPlugin) Prepare(req *http.Request) error { - token, err := azureManagedIdentitiesTokenRequest( - ap.Endpoint, ap.APIVersion, ap.Resource, - ap.ObjectID, ap.ClientID, ap.MiResID, - ap.UseAppServiceMsi, - ) - if err != nil { - return err - } - - req.Header.Add("Authorization", "Bearer "+token.AccessToken) - return nil -} - -// azureManagedIdentitiesTokenRequest fetches an azureManagedIdentitiesToken -func azureManagedIdentitiesTokenRequest( - endpoint, apiVersion, resource, objectID, clientID, miResID string, - useAppServiceMsi bool, -) (azureManagedIdentitiesToken, error) { - var token azureManagedIdentitiesToken - e := buildAzureManagedIdentitiesRequestPath(endpoint, apiVersion, resource, objectID, clientID, miResID) - - request, err := http.NewRequest("GET", e, nil) - if err != nil { - return token, err - } - if useAppServiceMsi { - identityHeader := os.Getenv("IDENTITY_HEADER") - if identityHeader == "" { - return token, errors.New("azure managed identities auth: IDENTITY_HEADER env var not found") - } - request.Header.Add("x-identity-header", identityHeader) - } else { - request.Header.Add("Metadata", "true") - } - - httpClient := http.Client{Timeout: timeout} - response, err := httpClient.Do(request) - if err != nil { - return token, err - } - defer response.Body.Close() - - data, err := io.ReadAll(response.Body) - if err != nil { - return token, err - } - - if s := response.StatusCode; s != http.StatusOK { - var azureError azureManagedIdentitiesError - err = json.Unmarshal(data, &azureError) - if err != nil { - return token, err - } - - azureError.Endpoint = e - azureError.StatusCode = s - return token, &azureError - } - - err = json.Unmarshal(data, &token) - if err != nil { - return token, err - } - return token, nil -} - -// buildAzureManagedIdentitiesRequestPath constructs the request URL for an Azure managed identities token request -func buildAzureManagedIdentitiesRequestPath( - endpoint, apiVersion, resource, objectID, clientID, miResID string, -) string { - params := url.Values{ - "api-version": []string{apiVersion}, - "resource": []string{resource}, - } - - if objectID != "" { - params.Add("object_id", objectID) - } - - if clientID != "" { - params.Add("client_id", clientID) - } - - if miResID != "" { - params.Add("mi_res_id", miResID) - } - - return endpoint + "?" + params.Encode() -} - -type azureKeyVaultSignPlugin struct { - config azureKeyVaultConfig - tokener func() (string, error) -} - -func newKeyVaultSignPlugin(ap *azureManagedIdentitiesAuthPlugin, cfg *azureKeyVaultConfig) *azureKeyVaultSignPlugin { - resp := &azureKeyVaultSignPlugin{ - tokener: func() (string, error) { - resp, err := azureManagedIdentitiesTokenRequest( - ap.Endpoint, - ap.APIVersion, - cfg.URL.String(), - ap.ObjectID, - ap.ClientID, - ap.MiResID, - ap.UseAppServiceMsi) - if err != nil { - return "", err - } - return resp.AccessToken, nil - }, - config: *cfg, - } - return resp -} - -func (akv *azureKeyVaultSignPlugin) setDefaults() { - if akv.config.APIVersion == "" { - akv.config.APIVersion = defaultKeyVaultAPIVersion - } -} - -type kvRequest struct { - Alg string `json:"alg"` - Value string `json:"value"` -} - -type kvResponse struct { - KID string `json:"kid"` - Value string `json:"value"` -} - -// SignDigest() uses the Microsoft keyvault rest api to sign a byte digest -// https://learn.microsoft.com/en-us/rest/api/keyvault/keys/sign/sign -func (ap *azureKeyVaultSignPlugin) SignDigest(ctx context.Context, digest []byte) (string, error) { - tkn, err := ap.tokener() - if err != nil { - return "", err - } - if ap.config.URL.Host == "" { - return "", errors.New("keyvault host not set") - } - - signingURL := ap.config.URL.JoinPath("keys", ap.config.Key, ap.config.KeyVersion, "sign") - q := signingURL.Query() - q.Set("api-version", ap.config.APIVersion) - signingURL.RawQuery = q.Encode() - reqBody, err := json.Marshal(kvRequest{ - Alg: ap.config.Alg, - Value: base64.StdEncoding.EncodeToString(digest)}) - if err != nil { - return "", err - } - - req, err := http.NewRequestWithContext(ctx, http.MethodPost, signingURL.String(), bytes.NewBuffer(reqBody)) - if err != nil { - return "", err - } - - req.Header.Add("Authorization", "Bearer "+tkn) - req.Header.Add("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return "", err - } - - if resp.StatusCode != http.StatusOK { - if resp.Body != nil { - defer resp.Body.Close() - b, _ := io.ReadAll(resp.Body) - return "", fmt.Errorf("non 200 status code, got: %d. Body: %v", resp.StatusCode, string(b)) - } - return "", fmt.Errorf("non 200 status code from keyvault sign, got: %d", resp.StatusCode) - } - defer resp.Body.Close() - - respBytes, err := io.ReadAll(resp.Body) - if err != nil { - return "", errors.New("failed to read keyvault response body") - } - - var res kvResponse - err = json.Unmarshal(respBytes, &res) - if err != nil { - return "", fmt.Errorf("no valid keyvault response, got: %v", string(respBytes)) - } - - return res.Value, nil -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/gcp.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/gcp.go deleted file mode 100644 index c717105c7f3e..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/gcp.go +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2020 The OPA Authors. All rights reserved. -// Use of this source code is governed by an Apache2 -// license that can be found in the LICENSE file. - -package rest - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "strings" - "time" -) - -var ( - defaultGCPMetadataEndpoint = "http://metadata.google.internal" - defaultAccessTokenPath = "/computeMetadata/v1/instance/service-accounts/default/token" - defaultIdentityTokenPath = "/computeMetadata/v1/instance/service-accounts/default/identity" -) - -// AccessToken holds a GCP access token. -type AccessToken struct { - AccessToken string `json:"access_token"` - ExpiresIn int64 `json:"expires_in"` - TokenType string `json:"token_type"` -} - -type gcpMetadataError struct { - err error - endpoint string - statusCode int -} - -func (e *gcpMetadataError) Error() string { - return fmt.Sprintf("error retrieving gcp ID token from %s %d: %v", e.endpoint, e.statusCode, e.err) -} - -func (e *gcpMetadataError) Unwrap() error { return e.err } - -var ( - errGCPMetadataNotFound = errors.New("not found") - errGCPMetadataInvalidRequest = errors.New("invalid request") - errGCPMetadataUnexpected = errors.New("unexpected error") -) - -// gcpMetadataAuthPlugin represents authentication via GCP metadata service. -type gcpMetadataAuthPlugin struct { - AccessTokenPath string `json:"access_token_path"` - Audience string `json:"audience"` - Endpoint string `json:"endpoint"` - IdentityTokenPath string `json:"identity_token_path"` - Scopes []string `json:"scopes"` -} - -func (ap *gcpMetadataAuthPlugin) NewClient(c Config) (*http.Client, error) { - if ap.Audience == "" && len(ap.Scopes) == 0 { - return nil, errors.New("audience or scopes is required when gcp metadata is enabled") - } - - if ap.Audience != "" && len(ap.Scopes) > 0 { - return nil, errors.New("either audience or scopes can be set, not both, when gcp metadata is enabled") - } - - if ap.Endpoint == "" { - ap.Endpoint = defaultGCPMetadataEndpoint - } - - if ap.AccessTokenPath == "" { - ap.AccessTokenPath = defaultAccessTokenPath - } - - if ap.IdentityTokenPath == "" { - ap.IdentityTokenPath = defaultIdentityTokenPath - } - - t, err := DefaultTLSConfig(c) - if err != nil { - return nil, err - } - - return DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil -} - -func (ap *gcpMetadataAuthPlugin) Prepare(req *http.Request) error { - var err error - var token string - - if ap.Audience != "" { - token, err = identityTokenFromMetadataService(ap.Endpoint, ap.IdentityTokenPath, ap.Audience) - if err != nil { - return fmt.Errorf("error retrieving identity token from gcp metadata service: %w", err) - } - } - - if len(ap.Scopes) != 0 { - token, err = accessTokenFromMetadataService(ap.Endpoint, ap.AccessTokenPath, ap.Scopes) - if err != nil { - return fmt.Errorf("error retrieving access token from gcp metadata service: %w", err) - } - } - - req.Header.Add("Authorization", fmt.Sprintf("Bearer %v", token)) - return nil -} - -// accessTokenFromMetadataService returns an access token based on the scopes. -func accessTokenFromMetadataService(endpoint, path string, scopes []string) (string, error) { - s := strings.Join(scopes, ",") - - e := fmt.Sprintf("%s%s?scopes=%s", endpoint, path, s) - - data, err := gcpMetadataServiceRequest(e) - if err != nil { - return "", err - } - - var accessToken AccessToken - err = json.Unmarshal(data, &accessToken) - if err != nil { - return "", err - } - - return accessToken.AccessToken, nil -} - -// identityTokenFromMetadataService returns an identity token based on the audience. -func identityTokenFromMetadataService(endpoint, path, audience string) (string, error) { - e := fmt.Sprintf("%s%s?audience=%s", endpoint, path, audience) - - data, err := gcpMetadataServiceRequest(e) - if err != nil { - return "", err - } - return string(data), nil -} - -func gcpMetadataServiceRequest(endpoint string) ([]byte, error) { - request, err := http.NewRequest("GET", endpoint, nil) - if err != nil { - return nil, err - } - - request.Header.Add("Metadata-Flavor", "Google") - - timeout := time.Duration(5) * time.Second - httpClient := http.Client{Timeout: timeout} - - response, err := httpClient.Do(request) - if err != nil { - return nil, err - } - defer response.Body.Close() - - switch s := response.StatusCode; s { - case 200: - break - case 400: - return nil, &gcpMetadataError{errGCPMetadataInvalidRequest, endpoint, s} - case 404: - return nil, &gcpMetadataError{errGCPMetadataNotFound, endpoint, s} - default: - return nil, &gcpMetadataError{errGCPMetadataUnexpected, endpoint, s} - } - - data, err := io.ReadAll(response.Body) - if err != nil { - return nil, err - } - - return data, nil -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/rest.go b/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/rest.go deleted file mode 100644 index f8be30af5e31..000000000000 --- a/vendor/github.com/open-policy-agent/opa/v1/plugins/rest/rest.go +++ /dev/null @@ -1,366 +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 rest implements a REST client for communicating with remote services. -package rest - -import ( - "bytes" - "context" - "encoding/json" - "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/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 ( - defaultResponseHeaderTimeoutSeconds = int64(10) - defaultResponseSizeLimitBytes = 1024 - - grantTypeClientCredentials = "client_credentials" - grantTypeJwtBearer = "jwt_bearer" -) - -var maskedHeaderKeys = map[string]struct{}{ - "Authorization": {}, - "X-Amz-Security-Token": {}, -} - -// An HTTPAuthPlugin represents a mechanism to construct and configure HTTP authentication for a REST service -type HTTPAuthPlugin interface { - // implementations can assume NewClient will be called before Prepare - NewClient(Config) (*http.Client, error) - Prepare(*http.Request) error -} - -// Config represents configuration for a REST client. -type Config struct { - Name string `json:"name"` - URL string `json:"url"` - Headers map[string]string `json:"headers"` - AllowInsecureTLS bool `json:"allow_insecure_tls,omitempty"` - ResponseHeaderTimeoutSeconds *int64 `json:"response_header_timeout_seconds,omitempty"` - TLS *serverTLSConfig `json:"tls,omitempty"` - Credentials struct { - Bearer *bearerAuthPlugin `json:"bearer,omitempty"` - OAuth2 *oauth2ClientCredentialsAuthPlugin `json:"oauth2,omitempty"` - ClientTLS *clientTLSAuthPlugin `json:"client_tls,omitempty"` - S3Signing *awsSigningAuthPlugin `json:"s3_signing,omitempty"` - GCPMetadata *gcpMetadataAuthPlugin `json:"gcp_metadata,omitempty"` - AzureManagedIdentity *azureManagedIdentitiesAuthPlugin `json:"azure_managed_identity,omitempty"` - Plugin *string `json:"plugin,omitempty"` - } `json:"credentials"` - Type string `json:"type,omitempty"` - keys map[string]*keys.Config - logger logging.Logger -} - -// Equal returns true if this client config is equal to the other. -func (c *Config) Equal(other *Config) bool { - otherWithoutLogger := *other - otherWithoutLogger.logger = c.logger - return reflect.DeepEqual(c, &otherWithoutLogger) -} - -// An AuthPluginLookupFunc can lookup auth plugins by their name. -type AuthPluginLookupFunc func(name string) HTTPAuthPlugin - -// AuthPlugin should be used to get an authentication method from the config. -func (c *Config) AuthPlugin(lookup AuthPluginLookupFunc) (HTTPAuthPlugin, error) { - var candidate HTTPAuthPlugin - if c.Credentials.Plugin != nil { - if lookup == nil { - // if no authPluginLookup function is passed we can't resolve the plugin - return nil, errors.New("missing auth plugin lookup function") - } - - candidate := lookup(*c.Credentials.Plugin) - if candidate == nil { - return nil, fmt.Errorf("auth plugin %q not found", *c.Credentials.Plugin) - } - - return candidate, nil - } - // reflection avoids need for this code to change as auth plugins are added - s := reflect.ValueOf(c.Credentials) - for i := range s.NumField() { - if s.Field(i).IsNil() { - continue - } - - if candidate != nil { - return nil, errors.New("a maximum one credential method must be specified") - } - - candidate = s.Field(i).Interface().(HTTPAuthPlugin) - } - - if candidate == nil { - return &defaultAuthPlugin{}, nil - } - return candidate, nil -} - -func (c *Config) authHTTPClient(lookup AuthPluginLookupFunc) (*http.Client, error) { - plugin, err := c.AuthPlugin(lookup) - if err != nil { - return nil, err - } - return plugin.NewClient(*c) -} - -func (c *Config) authPrepare(req *http.Request, lookup AuthPluginLookupFunc) error { - plugin, err := c.AuthPlugin(lookup) - if err != nil { - return err - } - return plugin.Prepare(req) -} - -// Client implements an HTTP/REST client for communicating with remote -// services. -type Client struct { - bytes *[]byte - json *any - config Config - headers map[string]string - authPluginLookup AuthPluginLookupFunc - logger logging.Logger - loggerFields map[string]any - distributedTacingOpts tracing.Options -} - -// Name returns an option that overrides the service name on the client. -func Name(s string) func(*Client) { - return func(c *Client) { - c.config.Name = s - } -} - -// AuthPluginLookup assigns a function to lookup an HTTPAuthPlugin to a new Client. -// It's intended to be used when creating a Client using New(). Usually this is passed -// the plugins.AuthPlugin func, which retrieves a registered HTTPAuthPlugin from the -// plugin manager. -func AuthPluginLookup(l AuthPluginLookupFunc) func(*Client) { - return func(c *Client) { - c.authPluginLookup = l - } -} - -// Logger assigns a logger to the client -func Logger(l logging.Logger) func(*Client) { - return func(c *Client) { - c.logger = l - } -} - -// DistributedTracingOpts sets the options to be used by distributed tracing. -func DistributedTracingOpts(tr tracing.Options) func(*Client) { - return func(c *Client) { - c.distributedTacingOpts = tr - } -} - -// New returns a new Client for config. -func New(config []byte, keys map[string]*keys.Config, opts ...func(*Client)) (Client, error) { - var parsedConfig Config - if err := util.Unmarshal(config, &parsedConfig); err != nil { - return Client{}, err - } - - parsedConfig.URL = strings.TrimRight(parsedConfig.URL, "/") - - if parsedConfig.ResponseHeaderTimeoutSeconds == nil { - timeout := defaultResponseHeaderTimeoutSeconds - parsedConfig.ResponseHeaderTimeoutSeconds = &timeout - } - - parsedConfig.keys = keys - - client := Client{ - config: parsedConfig, - } - - for _, f := range opts { - f(&client) - } - - if client.logger == nil { - client.logger = logging.Get() - } - - client.config.logger = client.logger - - return client, nil -} - -// AuthPluginLookup returns the lookup function to find a custom registered -// auth plugin by its name. -func (c Client) AuthPluginLookup() AuthPluginLookupFunc { - return c.authPluginLookup -} - -// Service returns the name of the service this Client is configured for. -func (c Client) Service() string { - return c.config.Name -} - -// Config returns this Client's configuration -func (c Client) Config() *Config { - return &c.config -} - -// SetResponseHeaderTimeout sets the "ResponseHeaderTimeout" in the http client's Transport -func (c Client) SetResponseHeaderTimeout(timeout *int64) Client { - c.config.ResponseHeaderTimeoutSeconds = timeout - return c -} - -// Logger returns the logger assigned to the Client -func (c Client) Logger() logging.Logger { - return c.logger -} - -// LoggerFields returns the fields used for log statements used by Client -func (c Client) LoggerFields() map[string]any { - return c.loggerFields -} - -// WithHeader returns a shallow copy of the client with a header to include the -// requests. -func (c Client) WithHeader(k, v string) Client { - if v == "" { - return c - } - if c.headers == nil { - c.headers = map[string]string{} - } - c.headers[k] = v - return c -} - -// WithJSON returns a shallow copy of the client with the JSON value set as the -// message body to include the requests. This function sets the Content-Type -// header. -func (c Client) WithJSON(body any) Client { - c = c.WithHeader("Content-Type", "application/json") - c.json = &body - return c -} - -// WithBytes returns a shallow copy of the client with the bytes set as the -// message body to include in the requests. -func (c Client) WithBytes(body []byte) Client { - c.bytes = &body - return c -} - -// Do executes a request using the client. -func (c Client) Do(ctx context.Context, method, path string) (*http.Response, error) { - - httpClient, err := c.config.authHTTPClient(c.authPluginLookup) - if err != nil { - return nil, err - } - - if len(c.distributedTacingOpts) > 0 { - httpClient.Transport = tracing.NewTransport(httpClient.Transport, c.distributedTacingOpts) - } - - path = strings.Trim(path, "/") - - var body io.Reader - - if c.bytes != nil { - body = bytes.NewReader(*c.bytes) - } else if c.json != nil { - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(*c.json); err != nil { - return nil, err - } - body = &buf - } - - url := c.config.URL + "/" + path - req, err := http.NewRequestWithContext(ctx, method, url, body) - if err != nil { - return nil, err - } - - headers := map[string]string{ - "User-Agent": version.UserAgent, - } - - // Copy custom headers from config. - maps.Copy(headers, c.config.Headers) - - // Overwrite with headers set directly on client. - maps.Copy(headers, c.headers) - - for key, value := range headers { - req.Header.Add(key, value) - } - - if err = c.config.authPrepare(req, c.authPluginLookup); err != nil { - return nil, err - } - - if c.logger.GetLevel() >= logging.Debug { - c.loggerFields = map[string]any{ - "method": method, - "url": url, - "headers": withMaskedHeaders(req.Header), - } - - c.logger.WithFields(c.loggerFields).Debug("Sending request.") - } - - resp, err := httpClient.Do(req) - - if resp != nil && c.logger.GetLevel() >= logging.Debug { - // Only log for debug purposes. If an error occurred, the caller should handle - // that. In the non-error case, the caller may not do anything. - c.loggerFields["status"] = resp.Status - c.loggerFields["headers"] = resp.Header - - if resp.StatusCode < 200 || resp.StatusCode >= 300 { - dump, err := httputil.DumpResponse(resp, true) - if err != nil { - return nil, err - } - - if len(dump) < defaultResponseSizeLimitBytes { - c.loggerFields["response"] = string(dump) - } else { - c.loggerFields["response"] = fmt.Sprintf("%v...", string(dump[:defaultResponseSizeLimitBytes])) - } - } - c.logger.WithFields(c.loggerFields).Debug("Received response.") - } - - return resp, err -} - -func withMaskedHeaders(headers http.Header) http.Header { - masked := make(http.Header) - for k, v := range headers { - if _, ok := maskedHeaderKeys[k]; ok { - masked.Set(k, "REDACTED") - } else { - masked[k] = v - } - } - return masked -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/rego/rego.go b/vendor/github.com/open-policy-agent/opa/v1/rego/rego.go index 2c4d8a8d9161..042d8014ea1d 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/rego/rego.go +++ b/vendor/github.com/open-policy-agent/opa/v1/rego/rego.go @@ -25,8 +25,8 @@ import ( "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/loader/filter" "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" @@ -44,7 +44,7 @@ const ( wasmVarPrefix = "^" ) -// nolint: deadcode,varcheck +// nolint:varcheck const ( targetWasm = "wasm" targetRego = "rego" @@ -235,6 +235,7 @@ func EvalInstrument(instrument bool) EvalOption { } // EvalTracer configures a tracer for a Prepared Query's evaluation +// // Deprecated: Use EvalQueryTracer instead. func EvalTracer(tracer topdown.Tracer) EvalOption { return func(e *EvalContext) { @@ -664,12 +665,11 @@ type Rego struct { enablePrintStatements bool distributedTracingOpts tracing.Options strict bool - pluginMgr *plugins.Manager - plugins []TargetPlugin targetPrepState TargetPluginEval regoVersion ast.RegoVersion compilerHook func(*ast.Compiler) evalMode *ast.CompilerEvalMode + filter filter.LoaderFilter } func (r *Rego) RegoVersion() ast.RegoVersion { @@ -1046,6 +1046,12 @@ func LoadBundle(path string) func(r *Rego) { } } +func WithFilter(f filter.LoaderFilter) func(r *Rego) { + return func(r *Rego) { + r.filter = f + } +} + // ParsedBundle returns an argument that adds a bundle to be loaded. func ParsedBundle(name string, b *bundle.Bundle) func(r *Rego) { return func(r *Rego) { @@ -1071,6 +1077,16 @@ func Store(s storage.Store) func(r *Rego) { } } +// Data returns an argument that sets the Rego data document. Data should be +// a map representing the data document. This is a simpler alternative to +// using Store with inmem.NewFromObject for cases where an in-memory store +// with static data is sufficient. +func Data(x map[string]any) func(r *Rego) { + return func(r *Rego) { + r.store = inmem.NewFromObject(x) + } +} + // StoreReadAST returns an argument that sets whether the store should eagerly convert data to AST values. // // Only applicable when no store has been set on the Rego object through the Store option. @@ -1115,6 +1131,7 @@ func Trace(yes bool) func(r *Rego) { } // Tracer returns an argument that adds a query tracer to r. +// // Deprecated: Use QueryTracer instead. func Tracer(t topdown.Tracer) func(r *Rego) { return func(r *Rego) { @@ -1408,15 +1425,6 @@ func New(options ...func(r *Rego)) *Rego { r.generateJSON = generateJSON } - if r.pluginMgr != nil { - for _, pluginName := range r.pluginMgr.Plugins() { - p := r.pluginMgr.Plugin(pluginName) - if p0, ok := p.(TargetPlugin); ok { - r.plugins = append(r.plugins, p0) - } - } - } - if t := r.targetPlugin(r.target); t != nil { r.compiler = r.compiler.WithEvalMode(ast.EvalModeIR) } @@ -2044,6 +2052,7 @@ func (r *Rego) loadBundles(_ context.Context, _ storage.Transaction, m metrics.M WithSkipBundleVerification(r.skipBundleVerification). WithRegoVersion(r.regoVersion). WithCapabilities(r.capabilities). + WithFilter(r.filter). AsBundle(path) if err != nil { return fmt.Errorf("loading error: %s", err) @@ -2201,7 +2210,7 @@ func (r *Rego) compileQuery(query ast.Body, imports []*ast.Import, _ metrics.Met if r.pkg != "" { var err error - pkg, err = ast.ParsePackage(fmt.Sprintf("package %v", r.pkg)) + pkg, err = ast.ParsePackage("package " + r.pkg) if err != nil { return nil, nil, err } @@ -2220,7 +2229,7 @@ func (r *Rego) compileQuery(query ast.Body, imports []*ast.Import, _ metrics.Met WithStrict(false) for _, extra := range extras { - qc = qc.WithStageAfter(extra.after, extra.stage) + qc = qc.WithStageAfterID(extra.after, extra.stage) } compiled, err := qc.Compile(query) @@ -2868,7 +2877,7 @@ func (m rawModule) ParseWithOpts(opts ast.ParserOptions) (*ast.Module, error) { } type extraStage struct { - after string + after ast.StageID stage ast.QueryCompilerStageDefinition } diff --git a/vendor/github.com/open-policy-agent/opa/v1/rego/resultset.go b/vendor/github.com/open-policy-agent/opa/v1/rego/resultset.go index 983de2223e79..f1618799eb12 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/rego/resultset.go +++ b/vendor/github.com/open-policy-agent/opa/v1/rego/resultset.go @@ -79,12 +79,24 @@ func (ev *ExpressionValue) String() string { // return `true` for a query like `data.authz.allow = x`, which always has result // set element with value true, but could also have a binding `x: false`. func (rs ResultSet) Allowed() bool { + x, _ := ResultValue[bool](rs) + return x +} + +// ResultValue is a helper function that'll return a value of type T if all of +// these conditions hold: +// - the result set only has one element +// - there is only one expression in the result set's only element +// - that expression has type T +// - there are no bindings. +func ResultValue[T any](rs ResultSet) (T, bool) { + var zero T if len(rs) == 1 && len(rs[0].Bindings) == 0 { if exprs := rs[0].Expressions; len(exprs) == 1 { - if b, ok := exprs[0].Value.(bool); ok { - return b + if v, ok := exprs[0].Value.(T); ok { + return v, true } } } - return false + return zero, false } diff --git a/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/inmem.go b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/inmem.go index cdc43424dd5b..9fa145a0513a 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/inmem.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/inmem/inmem.go @@ -349,10 +349,25 @@ func (h *handle) Unregister(_ context.Context, txn storage.Transaction) { } func (db *store) runOnCommitTriggers(ctx context.Context, txn storage.Transaction, event storage.TriggerEvent) { - if db.returnASTValuesOnRead && len(db.triggers) > 0 { - // FIXME: Not very performant for large data. + // While it's unlikely, the API allows one trigger to be configured to want + // data conversion, and another that doesn't. So let's handle that properly. + var wantsDataConversion bool + if db.returnASTValuesOnRead && len(event.Data) > 0 { + for _, t := range db.triggers { + if !t.SkipDataConversion { + wantsDataConversion = true + break + } + } + } - dataEvents := make([]storage.DataEvent, 0, len(event.Data)) + var converted storage.TriggerEvent + if wantsDataConversion { + converted = storage.TriggerEvent{ + Policy: event.Policy, + Data: make([]storage.DataEvent, 0, len(event.Data)), + Context: event.Context, + } for _, dataEvent := range event.Data { if astData, ok := dataEvent.Data.(ast.Value); ok { @@ -360,25 +375,21 @@ func (db *store) runOnCommitTriggers(ctx context.Context, txn storage.Transactio if err != nil { panic(err) } - dataEvents = append(dataEvents, storage.DataEvent{ + converted.Data = append(converted.Data, storage.DataEvent{ Path: dataEvent.Path, Data: jsn, Removed: dataEvent.Removed, }) - } else { - dataEvents = append(dataEvents, dataEvent) } } - - event = storage.TriggerEvent{ - Policy: event.Policy, - Data: dataEvents, - Context: event.Context, - } } for _, t := range db.triggers { - t.OnCommit(ctx, txn, event) + if wantsDataConversion && !t.SkipDataConversion { + t.OnCommit(ctx, txn, converted) + } else { + t.OnCommit(ctx, txn, event) + } } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/storage/interface.go b/vendor/github.com/open-policy-agent/opa/v1/storage/interface.go index a783caae090a..cb2e811dc496 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/storage/interface.go +++ b/vendor/github.com/open-policy-agent/opa/v1/storage/interface.go @@ -54,6 +54,14 @@ type NonEmptyer interface { NonEmpty(context.Context, Transaction) func([]string) (bool, error) } +// Closer is an optional interface that storage implementations can implement +// to perform cleanup operations when the store is being shut down. +// If a Store implements this interface, Close will be called during +// graceful shutdown of the OPA runtime. +type Closer interface { + Close(context.Context) error +} + // TransactionParams describes a new transaction. type TransactionParams struct { @@ -210,6 +218,10 @@ func (e TriggerEvent) DataChanged() bool { // TriggerConfig contains the trigger registration configuration. type TriggerConfig struct { + // SkipDataConversion when set to true, avoids converting data passed to + // trigger functions from the store to Go types, and instead passes the + // original representation (e.g., ast.Value). + SkipDataConversion bool // OnCommit is invoked when a transaction is successfully committed. The // callback is invoked with a handle to the write transaction that diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/aggregates.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/aggregates.go index 03d07668d850..356e7b38b0cd 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/aggregates.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/aggregates.go @@ -45,12 +45,13 @@ func builtinSum(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err // Non-integer values found, so we need to sum as floats. sum := big.NewFloat(0) + tmp := new(big.Float) err := a.Iter(func(x *ast.Term) error { n, ok := x.Value.(ast.Number) if !ok { return builtins.NewOperandElementErr(1, a, x.Value, "number") } - sum = new(big.Float).Add(sum, builtins.NumberToFloat(n)) + sum = new(big.Float).Add(sum, builtins.NumberToFloatInto(tmp, n)) return nil }) if err != nil { @@ -74,12 +75,13 @@ func builtinSum(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err } sum := big.NewFloat(0) + tmp := new(big.Float) err := a.Iter(func(x *ast.Term) error { n, ok := x.Value.(ast.Number) if !ok { return builtins.NewOperandElementErr(1, a, x.Value, "number") } - sum = new(big.Float).Add(sum, builtins.NumberToFloat(n)) + sum = new(big.Float).Add(sum, builtins.NumberToFloatInto(tmp, n)) return nil }) if err != nil { @@ -94,12 +96,13 @@ func builtinProduct(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) switch a := operands[0].Value.(type) { case *ast.Array: product := big.NewFloat(1) + tmp := new(big.Float) err := a.Iter(func(x *ast.Term) error { n, ok := x.Value.(ast.Number) if !ok { return builtins.NewOperandElementErr(1, a, x.Value, "number") } - product = new(big.Float).Mul(product, builtins.NumberToFloat(n)) + product = new(big.Float).Mul(product, builtins.NumberToFloatInto(tmp, n)) return nil }) if err != nil { @@ -108,12 +111,13 @@ func builtinProduct(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return iter(ast.NewTerm(builtins.FloatToNumber(product))) case ast.Set: product := big.NewFloat(1) + tmp := new(big.Float) err := a.Iter(func(x *ast.Term) error { n, ok := x.Value.(ast.Number) if !ok { return builtins.NewOperandElementErr(1, a, x.Value, "number") } - product = new(big.Float).Mul(product, builtins.NumberToFloat(n)) + product = new(big.Float).Mul(product, builtins.NumberToFloatInto(tmp, n)) return nil }) if err != nil { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/array.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/array.go index 526e3ed26ded..ca40b7793fec 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/array.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/array.go @@ -43,6 +43,42 @@ func builtinArrayConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T return iter(ast.ArrayTerm(arrC...)) } +func builtinArrayFlatten(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + arr, err := builtins.ArrayOperand(operands[0].Value, 1) + if err != nil { + return err + } + + size := arr.Len() + preAlloc := size + containsArray := false + + for i := range size { + if nested, ok := arr.Elem(i).Value.(*ast.Array); ok { + containsArray = true + preAlloc += nested.Len() - 1 + } + } + + if !containsArray && size == preAlloc { + return iter(operands[0]) // Empty array, or no nested arrays -> nothing to flatten. + } + + flattened := make([]*ast.Term, 0, preAlloc) + for i := range size { + elem := arr.Elem(i) + if nested, ok := elem.Value.(*ast.Array); ok { + for j := range nested.Len() { + flattened = append(flattened, nested.Elem(j)) + } + } else { + flattened = append(flattened, elem) + } + } + + return iter(ast.ArrayTerm(flattened...)) +} + func builtinArraySlice(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { arr, err := builtins.ArrayOperand(operands[0].Value, 1) if err != nil { @@ -59,12 +95,14 @@ func builtinArraySlice(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te return err } + l := arr.Len() + // Clamp stopIndex to avoid out-of-range errors. If negative, clamp to zero. // Otherwise, clamp to length of array. if stopIndex < 0 { stopIndex = 0 - } else if stopIndex > arr.Len() { - stopIndex = arr.Len() + } else if stopIndex > l { + stopIndex = l } // Clamp startIndex to avoid out-of-range errors. If negative, clamp to zero. @@ -75,7 +113,7 @@ func builtinArraySlice(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te startIndex = stopIndex } - if startIndex == 0 && stopIndex >= arr.Len() { + if startIndex == 0 && stopIndex >= l { return iter(operands[0]) } @@ -89,8 +127,16 @@ func builtinArrayReverse(_ BuiltinContext, operands []*ast.Term, iter func(*ast. } length := arr.Len() - reversedArr := make([]*ast.Term, length) + if length == 0 { + return iter(ast.InternedEmptyArray) + } + + if length == 1 { + return iter(operands[0]) + } + + reversedArr := make([]*ast.Term, length) for index := range length { reversedArr[index] = arr.Elem(length - index - 1) } @@ -100,6 +146,7 @@ func builtinArrayReverse(_ BuiltinContext, operands []*ast.Term, iter func(*ast. func init() { RegisterBuiltinFunc(ast.ArrayConcat.Name, builtinArrayConcat) + RegisterBuiltinFunc(ast.ArrayFlatten.Name, builtinArrayFlatten) RegisterBuiltinFunc(ast.ArraySlice.Name, builtinArraySlice) RegisterBuiltinFunc(ast.ArrayReverse.Name, builtinArrayReverse) } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/bindings.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/bindings.go index 9dd55f1ba741..809a31676c45 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/bindings.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/bindings.go @@ -40,6 +40,14 @@ func newBindings(id uint64, instr *Instrumentation) *bindings { return &bindings{id, values, instr} } +// newBindingsWithSize creates bindings pre-sized for the expected number of entries. +// This avoids over-allocation when the binding count is known in advance (e.g., function arguments). +// For sizeHint <= maxLinearScan, it uses array mode; for larger hints, it pre-allocates a map. +func newBindingsWithSize(id uint64, instr *Instrumentation, sizeHint int) *bindings { + values := newBindingsArrayHashmapWithSize(sizeHint) + return &bindings{id, values, instr} +} + func (u *bindings) Iter(caller *bindings, iter func(*ast.Term, *ast.Term) error) error { var err error @@ -216,16 +224,25 @@ func (vis namespacingVisitor) Visit(x any) bool { switch x := x.(type) { case *ast.ArrayComprehension: x.Term = vis.namespaceTerm(x.Term) - ast.NewGenericVisitor(vis.Visit).Walk(x.Body) + vis := ast.NewGenericVisitor(vis.Visit) + for _, expr := range x.Body { + vis.Walk(expr) + } return true case *ast.SetComprehension: x.Term = vis.namespaceTerm(x.Term) - ast.NewGenericVisitor(vis.Visit).Walk(x.Body) + vis := ast.NewGenericVisitor(vis.Visit) + for _, expr := range x.Body { + vis.Walk(expr) + } return true case *ast.ObjectComprehension: x.Key = vis.namespaceTerm(x.Key) x.Value = vis.namespaceTerm(x.Value) - ast.NewGenericVisitor(vis.Visit).Walk(x.Body) + vis := ast.NewGenericVisitor(vis.Visit) + for _, expr := range x.Body { + vis.Walk(expr) + } return true case *ast.Expr: switch terms := x.Terms.(type) { @@ -291,12 +308,16 @@ func (vis namespacingVisitor) namespaceTerm(a *ast.Term) *ast.Term { const maxLinearScan = 16 -// bindingsArrayHashMap uses an array with linear scan instead +// bindingsArrayHashMap uses a dynamically growing slice with linear scan instead // of a hash map for smaller # of entries. Hash maps start to // show off their performance advantage only after 16 keys. +// +// Memory optimization: The slice grows incrementally (2 -> 4 -> 8 -> 16) to avoid +// wasting memory when only a few bindings are used. This is critical for scenarios +// like comprehensions and functions with few arguments that are called thousands of times. type bindingsArrayHashmap struct { - n int // Entries in the array. - a *[maxLinearScan]bindingArrayKeyValue + n int // Entries in the slice. + a []bindingArrayKeyValue m map[ast.Var]bindingArrayKeyValue } @@ -309,29 +330,74 @@ func newBindingsArrayHashmap() bindingsArrayHashmap { return bindingsArrayHashmap{} } +// newBindingsArrayHashmapWithSize creates a bindingsArrayHashmap pre-sized for the expected number of entries. +// This optimization reduces memory waste when the binding count is known in advance. +// +// Size selection strategy: +// - sizeHint == 0: lazy allocation (no pre-allocation) +// - sizeHint <= maxLinearScan: pre-allocate slice with exact capacity to avoid reallocation +// - sizeHint > maxLinearScan: pre-allocate map with exact capacity +// +// Memory impact example: +// - Without hint: dynamic growth 0 -> 2 -> 4 -> 8 -> 16 (saves memory for small counts) +// - With hint=2: pre-allocates slice with capacity 2 (exact fit, no waste) +// - With hint=20: pre-allocates map with capacity 20 (saves array allocation + reallocation) +func newBindingsArrayHashmapWithSize(sizeHint int) bindingsArrayHashmap { + if sizeHint <= 0 { + // For unknown sizes, use default lazy allocation with dynamic growth. + return bindingsArrayHashmap{} + } + + if sizeHint <= maxLinearScan { + // For small known sizes, pre-allocate slice with exact capacity to avoid growth overhead. + return bindingsArrayHashmap{ + a: make([]bindingArrayKeyValue, 0, sizeHint), + } + } + + // For larger sizes, pre-allocate map to avoid array allocation + transition cost. + return bindingsArrayHashmap{ + m: make(map[ast.Var]bindingArrayKeyValue, sizeHint), + } +} + func (b *bindingsArrayHashmap) Put(key *ast.Term, value value) { if b.m == nil { - if b.a == nil { - b.a = new([maxLinearScan]bindingArrayKeyValue) - } else if i := b.find(key); i >= 0 { + // Check if key already exists and update value + if i := b.find(key); i >= 0 { b.a[i].value = value return } + // Still room in slice mode (< maxLinearScan) if b.n < maxLinearScan { - b.a[b.n] = bindingArrayKeyValue{key, value} + // Grow slice if needed using exponential growth strategy + if b.n == cap(b.a) { + newCap := cap(b.a) * 2 + if newCap == 0 { + newCap = 2 // Start with 2 elements + } + if newCap > maxLinearScan { + newCap = maxLinearScan + } + newA := make([]bindingArrayKeyValue, b.n, newCap) + copy(newA, b.a) + b.a = newA + } + b.a = append(b.a, bindingArrayKeyValue{key, value}) b.n++ return } - // Array is full, revert to using the hash map instead. - + // Slice is full (reached maxLinearScan), transition to map mode. b.m = make(map[ast.Var]bindingArrayKeyValue, maxLinearScan+1) - for _, kv := range *b.a { + for _, kv := range b.a { b.m[kv.key.Value.(ast.Var)] = bindingArrayKeyValue{kv.key, kv.value} } b.m[key.Value.(ast.Var)] = bindingArrayKeyValue{key, value} + // Clear slice to allow GC + b.a = nil b.n = 0 return } @@ -363,7 +429,8 @@ func (b *bindingsArrayHashmap) Delete(key *ast.Term) { if i < n { b.a[i] = b.a[n] } - + // Shrink slice to reflect deletion + b.a = b.a[:n] b.n = n } return @@ -374,9 +441,11 @@ 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 := range b.n { - if f(b.a[i].key, b.a[i].value) { - return + if b.a != nil { + for i := range b.n { + if f(b.a[i].key, b.a[i].value) { + return + } } } return @@ -390,6 +459,9 @@ func (b *bindingsArrayHashmap) Iter(f func(k *ast.Term, v value) bool) { } func (b *bindingsArrayHashmap) find(key *ast.Term) int { + if b.a == nil || b.n == 0 { + return -1 + } v := key.Value.(ast.Var) for i := range b.n { if b.a[i].key.Value.(ast.Var) == v { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins/builtins.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins/builtins.go index 7a1bdede6b28..c81b77248414 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins/builtins.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/builtins/builtins.go @@ -209,8 +209,7 @@ func SetOperand(x ast.Value, pos int) (ast.Set, error) { return s, nil } -// StringOperand converts x to a string. If the cast fails, a descriptive error is -// returned. +// StringOperand returns x as [ast.String], or a descriptive error if the conversion fails. func StringOperand(x ast.Value, pos int) (ast.String, error) { s, ok := x.(ast.String) if !ok { @@ -219,6 +218,17 @@ func StringOperand(x ast.Value, pos int) (ast.String, error) { return s, nil } +// StringOperandByteSlice returns x a []byte, assuming x is [ast.String], or a descriptive error +// if that is not the case. The returned byte slice points directly at the underlying array backing +// the string, and should not be modified. +func StringOperandByteSlice(x ast.Value, pos int) ([]byte, error) { + s, err := StringOperand(x, pos) + if err != nil { + return nil, err + } + return util.StringToByteSlice(string(s)), nil +} + // ObjectOperand converts x to an object. If the cast fails, a descriptive // error is returned. func ObjectOperand(x ast.Value, pos int) (ast.Object, error) { @@ -241,11 +251,18 @@ func ArrayOperand(x ast.Value, pos int) (*ast.Array, error) { // NumberToFloat converts n to a big float. func NumberToFloat(n ast.Number) *big.Float { - r, ok := new(big.Float).SetString(string(n)) - if !ok { + return NumberToFloatInto(nil, n) +} + +// NumberToFloatInto converts n to a big float, storing it in dst when provided. +func NumberToFloatInto(dst *big.Float, n ast.Number) *big.Float { + if dst == nil { + dst = new(big.Float) + } + if _, ok := dst.SetString(string(n)); !ok { panic("illegal value") } - return r + return dst } // FloatToNumber converts f to a number. diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/cache/cache.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/cache/cache.go index d514bed787ed..1c2eacc99e21 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/cache/cache.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/cache/cache.go @@ -32,7 +32,7 @@ func getDefaultInterQueryBuiltinValueCacheConfig(name string) *NamedValueCacheCo // 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. +// To disable a named cache when not configured, pass a config with the disabled value set to true. func RegisterDefaultInterQueryBuiltinValueCacheConfig(name string, config *NamedValueCacheConfig) { interQueryBuiltinValueCacheDefaultConfigs[name] = config } @@ -58,7 +58,8 @@ func (c *Config) Clone() *Config { // 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"` + MaxNumEntries *int `json:"max_num_entries,omitempty"` + Disabled *bool `json:"disabled,omitempty"` } // Clone creates a deep copy of NamedValueCacheConfig. @@ -73,6 +74,10 @@ func (n *NamedValueCacheConfig) Clone() *NamedValueCacheConfig { maxEntries := *n.MaxNumEntries clone.MaxNumEntries = &maxEntries } + if n.Disabled != nil { + disabled := *n.Disabled + clone.Disabled = &disabled + } return clone } @@ -220,9 +225,15 @@ 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) + if namedConfig == nil || (namedConfig.MaxNumEntries == nil && namedConfig.Disabled == nil) { + return fmt.Errorf("missing configuration for named cache %v", name) + } + + if namedConfig.MaxNumEntries != nil { + numEntries := *namedConfig.MaxNumEntries + if numEntries < 0 { + return fmt.Errorf("invalid max_num_entries %v for named cache %v", numEntries, name) + } } } @@ -605,6 +616,10 @@ func (c *interQueryBuiltinValueCache) GetCache(name string) InterQueryValueCache return nil } + if config.Disabled != nil && *config.Disabled { + return nil + } + nc = &interQueryValueCacheBucket{ items: *newItemsMap(), config: config, diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/cidr.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/cidr.go index 12a441496356..e6e2bb3ae772 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/cidr.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/cidr.go @@ -300,7 +300,7 @@ func builtinNetCIDRMerge(_ BuiltinContext, operands []*ast.Term, iter func(*ast. merged := evalNetCIDRMerge(networks) - result := ast.NewSet() + result := ast.NewSetWithCapacity(len(merged)) for _, network := range merged { result.Add(ast.StringTerm(network.String())) } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/copypropagation.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/copypropagation.go index 7767e7ff5207..607855632d4e 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/copypropagation.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/copypropagation/copypropagation.go @@ -9,6 +9,7 @@ import ( "sort" "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) // CopyPropagator implements a simple copy propagation optimization to remove @@ -49,17 +50,7 @@ func (l *localVarGenerator) Generate() ast.Var { // New returns a new CopyPropagator that optimizes queries while preserving vars // in the livevars set. func New(livevars ast.VarSet) *CopyPropagator { - - sorted := make([]ast.Var, 0, len(livevars)) - for v := range livevars { - sorted = append(sorted, v) - } - - sort.Slice(sorted, func(i, j int) bool { - return sorted[i].Compare(sorted[j]) < 0 - }) - - return &CopyPropagator{livevars: livevars, sorted: sorted, localvargen: &localVarGenerator{}} + return &CopyPropagator{livevars: livevars, sorted: util.KeysSorted(livevars), localvargen: &localVarGenerator{}} } // WithEnsureNonEmptyBody configures p to ensure that results are always non-empty. @@ -344,7 +335,7 @@ func (p *CopyPropagator) livevarRef(a *ast.Term) bool { } for _, v := range p.sorted { - if ref[0].Value.Compare(v) == 0 { + if v.Equal(ref[0].Value) { return true } } @@ -403,7 +394,7 @@ func containedIn(value ast.Value, x any) bool { if v, ok := value.(ast.Ref); ok { match = x.HasPrefix(v) } else { - match = x.Compare(value) == 0 + match = x.Equal(value) } if stop || match { stop = true diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/crypto.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/crypto.go index 144c01ee9535..f4ca23fae559 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/crypto.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/crypto.go @@ -255,17 +255,17 @@ func extractVerifyOpts(options ast.Object) (verifyOpt x509.VerifyOptions, err er } func builtinCryptoX509ParseKeyPair(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - certificate, err := builtins.StringOperand(operands[0].Value, 1) + certificate, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - key, err := builtins.StringOperand(operands[1].Value, 1) + key, err := builtins.StringOperandByteSlice(operands[1].Value, 1) if err != nil { return err } - certs, err := getTLSx509KeyPairFromString([]byte(certificate), []byte(key)) + certs, err := getTLSx509KeyPairFromString(certificate, key) if err != nil { return err } @@ -326,10 +326,7 @@ func builtinCryptoX509ParseCertificateRequest(_ BuiltinContext, operands []*ast. } func builtinCryptoJWKFromPrivateKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - var x any - - a := operands[0].Value - input, err := builtins.StringOperand(a, 1) + input, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { return err } @@ -371,6 +368,7 @@ func builtinCryptoJWKFromPrivateKey(_ BuiltinContext, operands []*ast.Term, iter return err } + var x any if err := util.UnmarshalJSON(jsonKey, &x); err != nil { return err } @@ -430,53 +428,51 @@ func toHexEncodedString(src []byte) string { } func builtinCryptoMd5(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - s, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - md5sum := md5.Sum([]byte(s)) + md5sum := md5.Sum(bs) return iter(ast.StringTerm(toHexEncodedString(md5sum[:]))) } func builtinCryptoSha1(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - s, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - sha1sum := sha1.Sum([]byte(s)) + sha1sum := sha1.Sum(bs) return iter(ast.StringTerm(toHexEncodedString(sha1sum[:]))) } func builtinCryptoSha256(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - s, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - sha256sum := sha256.Sum256([]byte(s)) + sha256sum := sha256.Sum256(bs) return iter(ast.StringTerm(toHexEncodedString(sha256sum[:]))) } func hmacHelper(operands []*ast.Term, iter func(*ast.Term) error, h func() hash.Hash) error { - a1 := operands[0].Value - message, err := builtins.StringOperand(a1, 1) + message, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - a2 := operands[1].Value - key, err := builtins.StringOperand(a2, 2) + key, err := builtins.StringOperandByteSlice(operands[1].Value, 2) if err != nil { return err } - mac := hmac.New(h, []byte(key)) - mac.Write([]byte(message)) + mac := hmac.New(h, key) + mac.Write(message) messageDigest := mac.Sum(nil) return iter(ast.StringTerm(hex.EncodeToString(messageDigest))) @@ -499,21 +495,17 @@ func builtinCryptoHmacSha512(_ BuiltinContext, operands []*ast.Term, iter func(* } func builtinCryptoHmacEqual(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - a1 := operands[0].Value - mac1, err := builtins.StringOperand(a1, 1) + mac1, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - a2 := operands[1].Value - mac2, err := builtins.StringOperand(a2, 2) + mac2, err := builtins.StringOperandByteSlice(operands[1].Value, 2) if err != nil { return err } - res := hmac.Equal([]byte(mac1), []byte(mac2)) - - return iter(ast.InternedTerm(res)) + return iter(ast.InternedTerm(hmac.Equal(mac1, mac2))) } func init() { @@ -668,7 +660,7 @@ func addCACertsFromFile(pool *x509.CertPool, filePath string) (*x509.CertPool, e pool = x509.NewCertPool() } - caCert, err := readCertFromFile(filePath) + caCert, err := os.ReadFile(filePath) if err != nil { return nil, err } @@ -703,17 +695,7 @@ func addCACertsFromEnv(pool *x509.CertPool, envName string) (*x509.CertPool, err return nil, fmt.Errorf("could not add CA certificates from envvar %q: %w", envName, err) } - return pool, err -} - -// ReadCertFromFile reads a cert from file -func readCertFromFile(localCertFile string) ([]byte, error) { - // Read in the cert file - certPEM, err := os.ReadFile(localCertFile) - if err != nil { - return nil, err - } - return certPEM, nil + return pool, nil } var beginPrefix = []byte("-----BEGIN ") @@ -771,13 +753,3 @@ func getTLSx509KeyPairFromString(certPemBlock []byte, keyPemBlock []byte) (*tls. return &cert, nil } - -// ReadKeyFromFile reads a key from file -func readKeyFromFile(localKeyFile string) ([]byte, error) { - // Read in the cert file - key, err := os.ReadFile(localKeyFile) - if err != nil { - return nil, err - } - return key, nil -} diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/encoding.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/encoding.go index 541b50d0a96e..5ed8df68f36d 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/encoding.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/encoding.go @@ -5,7 +5,6 @@ package topdown import ( - "bytes" "encoding/base64" "encoding/hex" "encoding/json" @@ -21,7 +20,6 @@ import ( ) func builtinJSONMarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - asJSON, err := ast.JSON(operands[0].Value) if err != nil { return err @@ -32,11 +30,10 @@ func builtinJSONMarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T return err } - return iter(ast.StringTerm(string(bs))) + return iter(ast.StringTerm(util.ByteSliceToString(bs))) } func builtinJSONMarshalWithOpts(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - asJSON, err := ast.JSON(operands[0].Value) if err != nil { return err @@ -101,36 +98,34 @@ func builtinJSONMarshalWithOpts(_ BuiltinContext, operands []*ast.Term, iter fun } var bs []byte - if shouldPrettyPrint { bs, err = json.MarshalIndent(asJSON, prefixWith, indentWith) } else { bs, err = json.Marshal(asJSON) } - if err != nil { return err } + s := util.ByteSliceToString(bs) + if shouldPrettyPrint { // json.MarshalIndent() function will not prefix the first line of emitted JSON - return iter(ast.StringTerm(prefixWith + string(bs))) + return iter(ast.StringTerm(prefixWith + s)) } - return iter(ast.StringTerm(string(bs))) + return iter(ast.StringTerm(s)) } func builtinJSONUnmarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - - str, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } var x any - - if err := util.UnmarshalJSON([]byte(str), &x); err != nil { + if err := util.UnmarshalJSON(bs, &x); err != nil { return err } v, err := ast.InterfaceToValue(x) @@ -141,22 +136,21 @@ func builtinJSONUnmarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast } func builtinJSONIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - - str, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return iter(ast.InternedTerm(false)) } - return iter(ast.InternedTerm(json.Valid([]byte(str)))) + return iter(ast.InternedTerm(json.Valid(bs))) } func builtinBase64Encode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - str, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - return iter(ast.StringTerm(base64.StdEncoding.EncodeToString([]byte(str)))) + return iter(ast.StringTerm(base64.StdEncoding.EncodeToString(bs))) } func builtinBase64Decode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -183,20 +177,20 @@ func builtinBase64IsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast } func builtinBase64UrlEncode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - str, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - return iter(ast.StringTerm(base64.URLEncoding.EncodeToString([]byte(str)))) + return iter(ast.StringTerm(base64.URLEncoding.EncodeToString(bs))) } func builtinBase64UrlEncodeNoPad(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - str, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - return iter(ast.StringTerm(base64.RawURLEncoding.EncodeToString([]byte(str)))) + return iter(ast.StringTerm(base64.RawURLEncoding.EncodeToString(bs))) } func builtinBase64UrlDecode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -293,7 +287,7 @@ func builtinURLQueryDecodeObject(_ BuiltinContext, operands []*ast.Term, iter fu return err } - queryObject := ast.NewObject() + queryObject := ast.NewObjectWithCapacity(len(queryParams)) for k, v := range queryParams { paramsArray := make([]*ast.Term, len(v)) for i, param := range v { @@ -306,45 +300,39 @@ func builtinURLQueryDecodeObject(_ BuiltinContext, operands []*ast.Term, iter fu } func builtinYAMLMarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - asJSON, err := ast.JSON(operands[0].Value) if err != nil { return err } - var buf bytes.Buffer - encoder := json.NewEncoder(&buf) - if err := encoder.Encode(asJSON); err != nil { - return err - } - - bs, err := yaml.JSONToYAML(buf.Bytes()) + bs, err := yaml.Marshal(asJSON) if err != nil { return err } - return iter(ast.StringTerm(string(bs))) + return iter(ast.StringTerm(util.ByteSliceToString(bs))) } func builtinYAMLUnmarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - - str, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - bs, err := yaml.YAMLToJSON([]byte(str)) + js, err := yaml.YAMLToJSON(bs) if err != nil { return err } - buf := bytes.NewBuffer(bs) - decoder := util.NewJSONDecoder(buf) + reader := ast.BytesReaderPool.Get() + defer ast.BytesReaderPool.Put(reader) + reader.Reset(js) + var val any - err = decoder.Decode(&val) - if err != nil { + if err = util.NewJSONDecoder(reader).Decode(&val); err != nil { return err } + v, err := ast.InterfaceToValue(val) if err != nil { return err @@ -353,22 +341,22 @@ 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) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return iter(ast.InternedTerm(false)) } var x any - err = yaml.Unmarshal([]byte(str), &x) + err = yaml.Unmarshal(bs, &x) return iter(ast.InternedTerm(err == nil)) } func builtinHexEncode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - str, err := builtins.StringOperand(operands[0].Value, 1) + bs, err := builtins.StringOperandByteSlice(operands[0].Value, 1) if err != nil { return err } - return iter(ast.StringTerm(hex.EncodeToString([]byte(str)))) + return iter(ast.StringTerm(hex.EncodeToString(bs))) } func builtinHexDecode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/errors.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/errors.go index cadd163198cd..e80339e31296 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/errors.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/errors.go @@ -6,9 +6,9 @@ package topdown import ( "errors" - "fmt" "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/util" ) // Halt is a special error type that built-in function implementations return to indicate @@ -82,13 +82,27 @@ func (e *Error) Is(target error) bool { } func (e *Error) Error() string { - msg := fmt.Sprintf("%v: %v", e.Code, e.Message) + buf, _ := e.AppendText(make([]byte, 0, e.StringLength())) + return util.ByteSliceToString(buf) +} +func (e *Error) AppendText(buf []byte) ([]byte, error) { if e.Location != nil { - msg = e.Location.String() + ": " + msg + buf, _ := e.Location.AppendText(buf) + buf = append(append(buf, ": "...), e.Code...) + buf = append(append(buf, ": "...), e.Message...) + return buf, nil } - return msg + return append(append(append(buf, e.Code...), ": "...), e.Message...), nil +} + +func (e *Error) StringLength() int { + l := len(e.Code) + 2 + len(e.Message) + if e.Location != nil { + l += e.Location.StringLength() + 2 + } + return l } func (e *Error) Wrap(err error) *Error { @@ -124,11 +138,11 @@ func objectDocKeyConflictErr(loc *ast.Location) error { } } -func unsupportedBuiltinErr(loc *ast.Location) error { +func unsupportedBuiltinErr(loc *ast.Location, name string) error { return &Error{ Code: InternalErr, Location: loc, - Message: "unsupported built-in", + Message: "unsupported built-in: " + name, } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go index f05fd9d94a2d..0d4c89963574 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go @@ -32,6 +32,13 @@ type queryIDFactory struct { curr uint64 } +type biunifyArraysRecParams struct { + a, b *ast.Array + b1, b2 *bindings + iter unifyIterator + idx int +} + // Note: The first call to Next() returns 0. func (f *queryIDFactory) Next() uint64 { curr := f.curr @@ -119,25 +126,53 @@ type eval struct { defined bool } -type evp struct { - pool sync.Pool +type ( + evfp struct{ pool sync.Pool } + evbp struct{ pool sync.Pool } +) + +func (ep *evfp) Put(e *evalFunc) { + if e != nil { + e.e, e.terms, e.ir = nil, nil, nil + ep.pool.Put(e) + } +} + +func (ep *evfp) Get() *evalFunc { + return ep.pool.Get().(*evalFunc) } -func (ep *evp) Put(e *eval) { - ep.pool.Put(e) +func (ep *evbp) Put(e *evalBuiltin) { + if e != nil { + e.e, e.bi, e.bctx, e.f, e.terms = nil, nil, nil, nil, nil + ep.pool.Put(e) + } } -func (ep *evp) Get() *eval { - return ep.pool.Get().(*eval) +func (ep *evbp) Get() *evalBuiltin { + return ep.pool.Get().(*evalBuiltin) } -var evalPool = evp{ - pool: sync.Pool{ - New: func() any { - return &eval{} +var ( + evalPool = util.NewSyncPool[eval]() + deecPool = util.NewSyncPool[deferredEarlyExitContainer]() + resolverPool = util.NewSyncPool[evalResolver]() + arraysRecPool = util.NewSyncPool[biunifyArraysRecParams]() + evalFuncPool = &evfp{ + pool: sync.Pool{ + New: func() any { + return &evalFunc{} + }, }, - }, -} + } + evalBuiltinPool = &evbp{ + pool: sync.Pool{ + New: func() any { + return &evalBuiltin{} + }, + }, + } +) func (e *eval) Run(iter evalIterator) error { if !e.traceEnabled { @@ -195,12 +230,14 @@ func (e *eval) closure(query ast.Body, cpy *eval) { cpy.findOne = false } -func (e *eval) child(query ast.Body, cpy *eval) { +// childWithBindingSizeHint creates a child evaluator with bindings pre-sized for the expected number of variables. +// This reduces memory waste when evaluating functions or rules with known argument counts. +func (e *eval) childWithBindingSizeHint(query ast.Body, cpy *eval, sizeHint int) { *cpy = *e cpy.index = 0 cpy.query = query cpy.queryID = cpy.queryIDFact.Next() - cpy.bindings = newBindings(cpy.queryID, e.instr) + cpy.bindings = newBindingsWithSize(cpy.queryID, e.instr, sizeHint) cpy.parent = e cpy.findOne = false } @@ -401,9 +438,11 @@ func (e *eval) evalExpr(iter evalIterator) error { } return nil } - expr := e.query[e.index] - e.traceEval(expr) + expr := e.query[e.index] + if e.traceEnabled { + e.traceEval(expr) + } if len(expr.With) > 0 { return e.evalWith(iter) @@ -521,7 +560,7 @@ func (e *eval) evalStep(iter evalIterator) error { // 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) { + if e.saveSet != nil && e.saveSet.Contains(rterm, e.bindings) { return e.saveExpr(ast.NewExpr(rterm), e.bindings, func() error { return iter(e) }) @@ -888,13 +927,12 @@ func (e *eval) evalNotPartialSupport(negationID uint64, expr *ast.Expr, unknowns } func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error { - ref := terms[0].Value.(ast.Ref) 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 - mockCall := append([]*ast.Term{ast.NewTerm(m)}, terms[1:]...) + mockCall := append([]*ast.Term{mock}, terms[1:]...) e.functionMocks.Push() err := e.evalCall(mockCall, func() error { @@ -912,8 +950,8 @@ 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(f.Arity(), terms, mock, iter) + arity := e.compiler.TypeEnv.GetByRef(ref).(*types.Function).Arity() + return e.evalCallValue(arity, terms, mock, iter) } var ir *ast.IndexResult @@ -928,18 +966,20 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error { return err } - eval := evalFunc{ - e: e, - terms: terms, - ir: ir, - } + eval := evalFuncPool.Get() + defer evalFuncPool.Put(eval) + + eval.e = e + eval.terms = terms + eval.ir = ir + return eval.eval(iter) } builtinName := ref.String() bi, f, ok := e.builtinFunc(builtinName) if !ok { - return unsupportedBuiltinErr(e.query[e.index].Location) + return unsupportedBuiltinErr(e.query[e.index].Location, builtinName) } if mocked { // value replacement of built-in call @@ -991,13 +1031,14 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error { } } - eval := evalBuiltin{ - e: e, - bi: bi, - bctx: bctx, - f: f, - terms: terms[1:], - } + eval := evalBuiltinPool.Get() + defer evalBuiltinPool.Put(eval) + + eval.e = e + eval.bi = bi + eval.bctx = bctx + eval.f = f + eval.terms = terms[1:] return eval.eval(iter) } @@ -1054,7 +1095,14 @@ func (e *eval) biunify(a, b *ast.Term, b1, b2 *bindings, iter unifyIterator) err case ast.Var, ast.Ref, *ast.ArrayComprehension: return e.biunifyValues(a, b, b1, b2, iter) case *ast.Array: - return e.biunifyArrays(vA, vB, b1, b2, iter) + if vA.Len() == vB.Len() { + params := arraysRecPool.Get() + params.a, params.b = vA, vB + params.b1, params.b2 = b1, b2 + params.iter = iter + params.idx = 0 + return e.biunifyArraysRec(params) + } } case ast.Object: switch vB := b.Value.(type) { @@ -1069,19 +1117,15 @@ func (e *eval) biunify(a, b *ast.Term, b1, b2 *bindings, iter unifyIterator) err return nil } -func (e *eval) biunifyArrays(a, b *ast.Array, b1, b2 *bindings, iter unifyIterator) error { - if a.Len() != b.Len() { - return nil - } - return e.biunifyArraysRec(a, b, b1, b2, iter, 0) -} - -func (e *eval) biunifyArraysRec(a, b *ast.Array, b1, b2 *bindings, iter unifyIterator, idx int) error { - if idx == a.Len() { - return iter() +func (e *eval) biunifyArraysRec(params *biunifyArraysRecParams) error { + if params.idx == params.a.Len() { + err := params.iter() + arraysRecPool.Put(params) + return err } - return e.biunify(a.Elem(idx), b.Elem(idx), b1, b2, func() error { - return e.biunifyArraysRec(a, b, b1, b2, iter, idx+1) + return e.biunify(params.a.Elem(params.idx), params.b.Elem(params.idx), params.b1, params.b2, func() error { + params.idx++ + return e.biunifyArraysRec(params) }) } @@ -1217,7 +1261,6 @@ func (e *eval) biunifyValues(a, b *ast.Term, b1, b2 *bindings, iter unifyIterato } func (e *eval) biunifyRef(a, b *ast.Term, b1, b2 *bindings, iter unifyIterator) error { - ref := a.Value.(ast.Ref) if ref[0].Equal(ast.DefaultRootDocument) { @@ -1341,7 +1384,7 @@ func (e *eval) buildComprehensionCacheArray(x *ast.ArrayComprehension, keys []*a child := evalPool.Get() defer evalPool.Put(child) - e.child(x.Body, child) + e.childWithBindingSizeHint(x.Body, child, ast.EstimateBodyBindingCount(x.Body)) node := newComprehensionCacheElem() return node, child.Run(func(child *eval) error { values := make([]*ast.Term, len(keys)) @@ -1363,7 +1406,7 @@ func (e *eval) buildComprehensionCacheSet(x *ast.SetComprehension, keys []*ast.T child := evalPool.Get() defer evalPool.Put(child) - e.child(x.Body, child) + e.childWithBindingSizeHint(x.Body, child, ast.EstimateBodyBindingCount(x.Body)) node := newComprehensionCacheElem() return node, child.Run(func(child *eval) error { values := make([]*ast.Term, len(keys)) @@ -1386,7 +1429,7 @@ func (e *eval) buildComprehensionCacheObject(x *ast.ObjectComprehension, keys [] child := evalPool.Get() defer evalPool.Put(child) - e.child(x.Body, child) + e.childWithBindingSizeHint(x.Body, child, ast.EstimateBodyBindingCount(x.Body)) node := newComprehensionCacheElem() return node, child.Run(func(child *eval) error { values := make([]*ast.Term, len(keys)) @@ -1466,36 +1509,50 @@ 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() + var elements []*ast.Term 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)) + elements = append(elements, child.bindings.Plug(x.Term)) return nil }) if err != nil { return err } - return e.biunify(ast.NewTerm(result), b, b1, b2, iter) + + if len(elements) == 0 { + return e.biunify(ast.InternedEmptyArray, b, b1, b2, iter) + } + + return e.biunify(ast.NewTerm(ast.NewArray(elements...)), b, b1, b2, iter) } func (e *eval) biunifyComprehensionSet(x *ast.SetComprehension, b *ast.Term, b1, b2 *bindings, iter unifyIterator) error { - result := ast.NewSet() child := evalPool.Get() e.closure(x.Body, child) defer evalPool.Put(child) + var result ast.Set err := child.Run(func(child *eval) error { - result.Add(child.bindings.Plug(x.Term)) + if result == nil { + result = ast.NewSet(child.bindings.Plug(x.Term)) + } else { + result.Add(child.bindings.Plug(x.Term)) + } return nil }) if err != nil { return err } + + if result == nil { + return e.biunify(ast.InternedEmptySet, b, b1, b2, iter) + } + return e.biunify(ast.NewTerm(result), b, b1, b2, iter) } @@ -1505,21 +1562,28 @@ func (e *eval) biunifyComprehensionObject(x *ast.ObjectComprehension, b *ast.Ter e.closure(x.Body, child) - result := ast.NewObject() - + var result ast.Object err := child.Run(func(child *eval) error { key := child.bindings.Plug(x.Key) value := child.bindings.Plug(x.Value) - exist := result.Get(key) - if exist != nil && !exist.Equal(value) { - return objectDocKeyConflictErr(x.Key.Location) + if result == nil { + result = ast.NewObject(ast.Item(key, value)) + } else { + if exist := result.Get(key); exist != nil && !exist.Equal(value) { + return objectDocKeyConflictErr(x.Key.Location) + } + result.Insert(key, value) } - result.Insert(key, value) return nil }) if err != nil { return err } + + if result == nil { + return e.biunify(ast.InternedEmptyObject, b, b1, b2, iter) + } + return e.biunify(ast.NewTerm(result), b, b1, b2, iter) } @@ -1638,12 +1702,12 @@ func (e *eval) getRules(ref ast.Ref, args []*ast.Term) (*ast.IndexResult, error) e.instr.startTimer(evalOpRuleIndex) defer e.instr.stopTimer(evalOpRuleIndex) - index := e.compiler.RuleIndex(ref) + index := e.ruleIndex(ref) if index == nil { return nil, nil } - resolver := resolverPool.Get().(*evalResolver) + resolver := resolverPool.Get() defer func() { resolver.e = nil resolver.args = nil @@ -1689,6 +1753,11 @@ func (e *eval) getRules(ref ast.Ref, args []*ast.Term) (*ast.IndexResult, error) return result, err } +// ruleIndex performs a lookup for a RuleIndex in the compiler's RuleTree. +func (e *eval) ruleIndex(ref ast.Ref) ast.RuleIndex { + return e.compiler.RuleIndex(ref) +} + func (e *eval) Resolve(ref ast.Ref) (ast.Value, error) { return (&evalResolver{e: e}).Resolve(ref) } @@ -1698,14 +1767,6 @@ 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) @@ -2052,8 +2113,7 @@ type evalFunc struct { terms []*ast.Term } -func (e evalFunc) eval(iter unifyIterator) error { - +func (e *evalFunc) eval(iter unifyIterator) error { if e.ir.Empty() { return nil } @@ -2065,13 +2125,13 @@ func (e evalFunc) eval(iter unifyIterator) error { argCount = len(e.ir.Default.Head.Args) } - if len(e.ir.Else) > 0 && e.e.unknown(e.e.query[e.e.index], e.e.bindings) { - // Partial evaluation of ordered rules is not supported currently. Save the - // expression and continue. This could be revisited in the future. - return e.e.saveCall(argCount, e.terms, iter) - } - if e.e.partial() { + if len(e.ir.Else) > 0 && e.e.unknown(e.e.query[e.e.index], e.e.bindings) { + // Partial evaluation of ordered rules is not supported currently. Save the + // expression and continue. This could be revisited in the future. + return e.e.saveCall(argCount, e.terms, iter) + } + var mustGenerateSupport bool if defRule := e.ir.Default; defRule != nil { @@ -2109,7 +2169,7 @@ func (e evalFunc) eval(iter unifyIterator) error { return e.evalValue(iter, argCount, e.ir.EarlyExit) } -func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) error { +func (e *evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) error { var cacheKey ast.Ref if !e.e.partial() { var hit bool @@ -2194,7 +2254,7 @@ func (e evalFunc) evalValue(iter unifyIterator, argCount int, findOne bool) erro }) } -func (e evalFunc) evalCache(argCount int, iter unifyIterator) (ast.Ref, bool, error) { +func (e *evalFunc) evalCache(argCount int, iter unifyIterator) (ast.Ref, bool, error) { plen := len(e.terms) if plen == argCount+2 { // func name + output = 2 plen -= 1 @@ -2226,11 +2286,15 @@ 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, args []*ast.Term, 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) - e.e.child(rule.Body, child) + // Optimization: pre-size bindings based on function argument count to reduce memory waste. + // Function argument count is known at compile time and most functions have < 10 arguments. + // This avoids allocating the default 16-slot array when only 2-3 bindings are needed. + sizeHint := len(args) + e.e.childWithBindingSizeHint(rule.Body, child, sizeHint) child.findOne = findOne var result *ast.Term @@ -2288,7 +2352,7 @@ func (e evalFunc) evalOneRule(iter unifyIterator, rule *ast.Rule, args []*ast.Te return result, err } -func (e evalFunc) partialEvalSupport(declArgsLen int, iter unifyIterator) error { +func (e *evalFunc) partialEvalSupport(declArgsLen int, iter unifyIterator) error { path := e.e.namespaceRef(e.terms[0].Value.(ast.Ref)) if !e.e.saveSupport.Exists(path) { @@ -2316,11 +2380,11 @@ func (e evalFunc) partialEvalSupport(declArgsLen int, iter unifyIterator) error return e.e.saveCall(declArgsLen, append([]*ast.Term{term}, e.terms[1:]...), iter) } -func (e evalFunc) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) error { +func (e *evalFunc) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) error { child := evalPool.Get() defer evalPool.Put(child) - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.traceEnter(rule) e.e.saveStack.PushQuery(nil) @@ -2395,12 +2459,6 @@ func (dc *deferredEarlyExitContainer) copyError() *deferredEarlyExitError { return &cpy } -var deecPool = sync.Pool{ - New: func() any { - return &deferredEarlyExitContainer{} - }, -} - type evalTree struct { e *eval bindings *bindings @@ -2475,6 +2533,20 @@ func (e evalTree) next(iter unifyIterator, plugged *ast.Term) error { return cpy.eval(iter) } +// enumerateNext is a helper to avoid closure allocation in enumerate loops. +// Method values don't allocate, unlike explicit closures. +// Using a pointer to evalTree avoids copying the 96-byte structure. +// Fields are ordered by size for optimal memory alignment (16 > 8 > 8 bytes). +type enumerateNext struct { + iter unifyIterator // 16 bytes (interface) + e *evalTree // 8 bytes (pointer) + key *ast.Term // 8 bytes (pointer) +} + +func (en *enumerateNext) call() error { + return en.e.next(en.iter, en.key) +} + func (e evalTree) enumerate(iter unifyIterator) error { if e.e.inliningControl.Disabled(e.plugged[:e.pos], true) { @@ -2486,18 +2558,21 @@ func (e evalTree) enumerate(iter unifyIterator) error { return err } - dc := deecPool.Get().(*deferredEarlyExitContainer) + dc := deecPool.Get() dc.deferred = nil defer deecPool.Put(dc) + // Use method value to avoid closure allocation. + // Create once and reuse for both doc and virtual doc enumeration. + en := enumerateNext{iter: iter, e: &e, key: nil} + if doc != nil { switch doc := doc.(type) { case *ast.Array: for i := range doc.Len() { k := ast.InternedTerm(i) - err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, func() error { - return e.next(iter, k) - }) + en.key = k + err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, en.call) if err := dc.handleErr(err); err != nil { return err @@ -2506,21 +2581,20 @@ func (e evalTree) enumerate(iter unifyIterator) error { case ast.Object: ki := doc.KeysIterator() for k, more := ki.Next(); more; k, more = ki.Next() { - err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, func() error { - return e.next(iter, k) - }) + en.key = k + err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, en.call) if err := dc.handleErr(err); err != nil { return err } } case ast.Set: - if err := doc.Iter(func(elem *ast.Term) error { - err := e.e.biunify(elem, e.ref[e.pos], e.bindings, e.bindings, func() error { - return e.next(iter, elem) - }) - return dc.handleErr(err) - }); err != nil { - return err + // Use Slice() to avoid closure allocation in Iter() + for _, elem := range doc.Slice() { + en.key = elem + err := e.e.biunify(elem, e.ref[e.pos], e.bindings, e.bindings, en.call) + if err := dc.handleErr(err); err != nil { + return err + } } } } @@ -2533,11 +2607,11 @@ func (e evalTree) enumerate(iter unifyIterator) error { return nil } + // Reuse the same enumerateNext for virtual documents for _, k := range e.node.Sorted { key := ast.NewTerm(k) - if err := e.e.biunify(key, e.ref[e.pos], e.bindings, e.bindings, func() error { - return e.next(iter, key) - }); err != nil { + en.key = key + if err := e.e.biunify(key, e.ref[e.pos], e.bindings, e.bindings, en.call); err != nil { return err } } @@ -2585,9 +2659,7 @@ func (e evalTree) leaves(plugged ast.Ref, node *ast.TreeNode) (ast.Object, error result := ast.NewObject() for _, k := range node.Sorted { - child := node.Children[k] - if child.Hide { continue } @@ -2850,7 +2922,7 @@ func (e evalVirtualPartial) evalAllRulesNoCache(rules []*ast.Rule) (*ast.Term, e defer evalPool.Put(child) for _, rule := range rules { - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.traceEnter(rule) err := child.eval(func(*eval) error { child.traceExit(rule) @@ -2886,7 +2958,7 @@ func (e evalVirtualPartial) evalOneRulePreUnify(iter unifyIterator, rule *ast.Ru child := evalPool.Get() defer evalPool.Put(child) - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.traceEnter(rule) var defined bool @@ -2981,7 +3053,7 @@ func (e evalVirtualPartial) evalOneRulePostUnify(iter unifyIterator, rule *ast.R child := evalPool.Get() defer evalPool.Put(child) - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.traceEnter(rule) var defined bool @@ -3068,7 +3140,7 @@ func (e evalVirtualPartial) partialEvalSupportRule(rule *ast.Rule, _ ast.Ref) (b child := evalPool.Get() defer evalPool.Put(child) - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.traceEnter(rule) e.e.saveStack.PushQuery(nil) @@ -3351,7 +3423,12 @@ func getNestedObject(ref ast.Ref, rootObj *ast.Object, b *bindings, l *ast.Locat } func hasCollisions(path ast.Ref, visitedRefs *[]ast.Ref, b *bindings) bool { - collisionPathTerm := b.Plug(ast.NewTerm(path)) + // Avoid allocating a new term just for the sake of a lookup + term := ast.TermPtrPool.Get() + term.Value = path + collisionPathTerm := b.Plug(term) + ast.TermPtrPool.Put(term) + collisionPath := collisionPathTerm.Value.(ast.Ref) for _, c := range *visitedRefs { if collisionPath.HasPrefix(c) && !collisionPath.Equal(c) { @@ -3363,15 +3440,15 @@ func hasCollisions(path ast.Ref, visitedRefs *[]ast.Ref, b *bindings) bool { } func (e evalVirtualPartial) reduce(rule *ast.Rule, b *bindings, result *ast.Term, visitedRefs *[]ast.Ref) (*ast.Term, bool, error) { - var exists bool head := rule.Head switch v := result.Value.(type) { case ast.Set: key := b.Plug(head.Key) - exists = v.Contains(key) - v.Add(key) + if exists = v.Contains(key); !exists { + v.Add(key) + } case ast.Object: // data.p.q[r].s.t := 42 {...} // |----|-| @@ -3553,7 +3630,7 @@ func (e evalVirtualComplete) evalValueRule(iter unifyIterator, rule *ast.Rule, p child := evalPool.Get() defer evalPool.Put(child) - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.findOne = findOne child.traceEnter(rule) var result *ast.Term @@ -3592,7 +3669,7 @@ func (e evalVirtualComplete) partialEval(iter unifyIterator) error { defer evalPool.Put(child) for _, rule := range e.ir.Rules { - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.traceEnter(rule) err := child.eval(func(child *eval) error { @@ -3617,17 +3694,22 @@ func (e evalVirtualComplete) partialEval(iter unifyIterator) error { } func (e evalVirtualComplete) partialEvalSupport(iter unifyIterator) error { - - path := e.e.namespaceRef(e.plugged[:e.pos+1]) + originalPath := e.plugged[:e.pos+1] + namespacePath := e.e.namespaceRef(originalPath) term := ast.NewTerm(e.e.namespaceRef(e.ref)) var defined bool - if e.e.saveSupport.Exists(path) { + if e.e.saveSupport.Exists(namespacePath) { defined = true } else { for i := range e.ir.Rules { - ok, err := e.partialEvalSupportRule(e.ir.Rules[i], path) + // Split the rule from the package + ruleRef := originalPath.Copy()[len(e.ir.Rules[i].Module.Package.Path):] + ruleRef[0].Value = ast.Var(ruleRef[0].Value.(ast.String)) + // Get the namespaced package path without the rule + packagePath := namespacePath.Copy()[:len(namespacePath)-len(ruleRef)] + ok, err := e.partialEvalSupportRule(e.ir.Rules[i], packagePath, ruleRef) if err != nil { return err } @@ -3637,7 +3719,12 @@ func (e evalVirtualComplete) partialEvalSupport(iter unifyIterator) error { } if e.ir.Default != nil { - ok, err := e.partialEvalSupportRule(e.ir.Default, path) + // Split the rule from the package + ruleRef := originalPath.Copy()[len(e.ir.Default.Module.Package.Path):] + ruleRef[0].Value = ast.Var(ruleRef[0].Value.(ast.String)) + // Get the namespaced package path without the rule + packagePath := namespacePath.Copy()[:len(namespacePath)-len(ruleRef)] + ok, err := e.partialEvalSupportRule(e.ir.Default, packagePath, ruleRef) if err != nil { return err } @@ -3654,11 +3741,11 @@ func (e evalVirtualComplete) partialEvalSupport(iter unifyIterator) error { return e.e.saveUnify(term, e.rterm, e.bindings, e.rbindings, iter) } -func (e evalVirtualComplete) partialEvalSupportRule(rule *ast.Rule, path ast.Ref) (bool, error) { +func (e evalVirtualComplete) partialEvalSupportRule(rule *ast.Rule, packagePath ast.Ref, ruleRef ast.Ref) (bool, error) { child := evalPool.Get() defer evalPool.Put(child) - e.e.child(rule.Body, child) + e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body)) child.traceEnter(rule) e.e.saveStack.PushQuery(nil) @@ -3673,7 +3760,6 @@ func (e evalVirtualComplete) partialEvalSupportRule(rule *ast.Rule, path ast.Ref // Skip this rule body if it fails to type-check. // Type-checking failure means the rule body will never succeed. if e.e.compiler.PassesTypeCheck(plugged) { - pkg, ruleRef := splitPackageAndRule(path) head := ast.RefHead(ruleRef, child.bindings.PlugNamespaced(rule.Head.Value, e.e.caller.bindings)) if !e.e.inliningControl.shallow { @@ -3683,7 +3769,7 @@ func (e evalVirtualComplete) partialEvalSupportRule(rule *ast.Rule, path ast.Ref plugged = applyCopyPropagation(cp, e.e.instr, plugged) } - e.e.saveSupport.InsertByPkg(pkg, &ast.Rule{ + e.e.saveSupport.InsertByPkg(packagePath, &ast.Rule{ Head: head, Body: plugged, Default: rule.Default, @@ -3880,12 +3966,10 @@ func (e evalTerm) get(plugged *ast.Term) (*ast.Term, *bindings) { } func (e evalTerm) save(iter unifyIterator) error { - v := e.e.generateVar(fmt.Sprintf("ref_%d", e.e.genvarid)) e.e.genvarid++ return e.e.biunify(e.term, v, e.termbindings, e.bindings, func() error { - suffix := e.ref[e.pos:] ref := make(ast.Ref, len(suffix)+1) ref[0] = v @@ -3904,7 +3988,8 @@ type evalEvery struct { func (e evalEvery) eval(iter unifyIterator) error { // unknowns in domain or body: save the expression, PE its body - if e.e.unknown(e.Domain, e.e.bindings) || e.e.unknown(e.Body, e.e.bindings) { + // partial() check to avoid e.Body -> Node boxing allocation + if e.e.partial() && (e.e.unknown(e.Domain, e.e.bindings) || e.e.unknown(e.Body, e.e.bindings)) { return e.save(iter) } @@ -3943,12 +4028,19 @@ func (e evalEvery) eval(iter unifyIterator) error { child.closure(e.Body, body) body.findOne = true - body.traceEnter(e.Body) + + if e.e.traceEnabled { + body.traceEnter(e.Body) + } + done := false err := body.eval(func(*eval) error { - body.traceExit(e.Body) + if e.e.traceEnabled { + body.traceExit(e.Body) + body.traceRedo(e.Body) + } done = true - body.traceRedo(e.Body) + return nil }) if !done { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go index f3bdf8e414c8..ba65e973f2f6 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go @@ -146,7 +146,7 @@ func pruneIrrelevantGraphQLASTNodes(value ast.Value) ast.Value { // extant ast type! switch x := value.(type) { case *ast.Array: - result := ast.NewArray() + result := ast.NewArrayWithCapacity(x.Len()) // Iterate over the array's elements, and do the following: // - Drop any Nulls // - Drop any any empty object/array value (after running the pruner) @@ -173,7 +173,7 @@ func pruneIrrelevantGraphQLASTNodes(value ast.Value) ast.Value { } return result case ast.Object: - result := ast.NewObject() + result := ast.NewObjectWithCapacity(x.Len()) // Iterate over our object's keys, and do the following: // - Drop "Position". // - Drop any key with a Null value. diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/http.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/http.go index 36c622e5a411..79d49f33ca84 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/http.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/http.go @@ -90,11 +90,9 @@ var cacheableHTTPStatusCodes = [...]int{ } var ( - httpSendNetworkErrTerm = ast.StringTerm(HTTPSendNetworkErr) - httpSendInternalErrTerm = ast.StringTerm(HTTPSendInternalErr) + httpSendNetworkErrTerm, httpSendInternalErrTerm *ast.Term allowedKeys = ast.NewSet() - keyCache = make(map[string]*ast.Term, len(allowedKeyNames)) cacheableCodes = ast.NewSet() requiredKeys = ast.NewSet(ast.InternedTerm("method"), ast.InternedTerm("url")) httpSendLatencyMetricKey = "rego_builtin_http_send" @@ -222,13 +220,13 @@ 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(keyCache["cache_ignored_headers"]) - allHeadersTerm := req.Get(ast.StringTerm("headers")) + cacheIgnoredHeadersTerm := req.Get(ast.InternedTerm("cache_ignored_headers")) + allHeadersTerm := req.Get(ast.InternedTerm("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.InternedNullTerm) + key.Insert(ast.InternedTerm("cache_ignored_headers"), ast.InternedNullTerm) return key, nil } var cacheIgnoredHeaders []string @@ -248,14 +246,22 @@ func getKeyFromRequest(req ast.Object) (ast.Object, error) { if err != nil { return nil, err } - key.Insert(keyCache["headers"], ast.NewTerm(val)) + key.Insert(ast.InternedTerm("headers"), ast.NewTerm(val)) // remove cache_ignored_headers key - key.Insert(keyCache["cache_ignored_headers"], ast.InternedNullTerm) + key.Insert(ast.InternedTerm("cache_ignored_headers"), ast.InternedNullTerm) return key, nil } func init() { - createKeys() + for _, element := range allowedKeyNames { + ast.InternStringTerm(element) + allowedKeys.Add(ast.InternedTerm(element)) + } + + ast.InternStringTerm(HTTPSendNetworkErr, HTTPSendInternalErr) + httpSendNetworkErrTerm = ast.InternedTerm(HTTPSendNetworkErr) + httpSendInternalErrTerm = ast.InternedTerm(HTTPSendInternalErr) + createCacheableHTTPStatusCodes() initDefaults() RegisterBuiltinFunc(ast.HTTPSend.Name, builtinHTTPSend) @@ -279,8 +285,7 @@ func handleHTTPSendErr(bctx BuiltinContext, err error) error { } func initDefaults() { - timeoutDuration := os.Getenv(defaultHTTPRequestTimeoutEnv) - if timeoutDuration != "" { + if timeoutDuration := os.Getenv(defaultHTTPRequestTimeoutEnv); timeoutDuration != "" { var err error defaultHTTPRequestTimeout, err = time.ParseDuration(timeoutDuration) if err != nil { @@ -314,7 +319,6 @@ func validateHTTPRequestOperand(term *ast.Term, pos int) (ast.Object, error) { } return obj, nil - } // canonicalizeHeaders returns a copy of the headers where the keys are in @@ -333,7 +337,7 @@ func canonicalizeHeaders(headers map[string]any) map[string]any { // a DialContext that opens a socket (specified in the http call). // The url is expected to contain socket=/path/to/socket (url encoded) // Ex. "unix://localhost/end/point?socket=%2Ftmp%2Fhttp.sock" -func useSocket(rawURL string, tlsConfig *tls.Config) (bool, string, *http.Transport) { +func useSocket(rawURL string) (bool, string, *http.Transport) { u, err := url.Parse(rawURL) if err != nil { return false, "", nil @@ -362,7 +366,6 @@ func useSocket(rawURL string, tlsConfig *tls.Config) (bool, string, *http.Transp tr.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) { return http.DefaultTransport.(*http.Transport).DialContext(ctx, "unix", socket) } - tr.TLSClientConfig = tlsConfig tr.DisableKeepAlives = true return true, u.String(), tr @@ -533,6 +536,10 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt } } + if len(customHeaders) != 0 { + customHeaders = canonicalizeHeaders(customHeaders) + } + isTLS := false client := &http.Client{ Timeout: timeout, @@ -579,13 +586,6 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt tlsConfig.Certificates = append(tlsConfig.Certificates, cert) } - // Use system certs if no CA cert is provided - // or system certs flag is not set - if len(tlsCaCert) == 0 && tlsCaCertFile == "" && tlsCaCertEnvVar == "" && tlsUseSystemCerts == nil { - trueValue := true - tlsUseSystemCerts = &trueValue - } - // Check the system certificates config first so that we // load additional certificated into the correct pool. if tlsUseSystemCerts != nil && *tlsUseSystemCerts && runtime.GOOS != "windows" { @@ -629,21 +629,31 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt tlsConfig.RootCAs = pool } + // If Host header is set, use it for TLS server name. + if host, hasHost := customHeaders["Host"]; hasHost { + // Only default the ServerName if the caller has + // specified the host. If we don't specify anything, + // Go will default to the target hostname. This name + // is not the same as the default that Go populates + // `req.Host` with, which is why we don't just set + // this unconditionally. + isTLS = true + tlsConfig.ServerName, _ = host.(string) + } + + if tlsServerName != "" { + isTLS = true + tlsConfig.ServerName = tlsServerName + } + var transport *http.Transport - if isTLS { - if ok, parsedURL, tr := useSocket(url, &tlsConfig); ok { - transport = tr - url = parsedURL - } else { - transport = http.DefaultTransport.(*http.Transport).Clone() - transport.TLSClientConfig = &tlsConfig - transport.DisableKeepAlives = true - } - } else { - if ok, parsedURL, tr := useSocket(url, nil); ok { - transport = tr - url = parsedURL - } + if ok, parsedURL, tr := useSocket(url); ok { + transport = tr + url = parsedURL + } else if isTLS { + transport = http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tlsConfig + transport.DisableKeepAlives = true } if bctx.RoundTripper != nil { @@ -676,8 +686,6 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt // Add custom headers if len(customHeaders) != 0 { - customHeaders = canonicalizeHeaders(customHeaders) - for k, v := range customHeaders { header, ok := v.(string) if !ok { @@ -697,21 +705,9 @@ func createHTTPRequest(bctx BuiltinContext, obj ast.Object) (*http.Request, *htt if host, hasHost := customHeaders["Host"]; hasHost { host := host.(string) // We already checked that it's a string. req.Host = host - - // Only default the ServerName if the caller has - // specified the host. If we don't specify anything, - // Go will default to the target hostname. This name - // is not the same as the default that Go populates - // `req.Host` with, which is why we don't just set - // this unconditionally. - tlsConfig.ServerName = host } } - if tlsServerName != "" { - tlsConfig.ServerName = tlsServerName - } - if len(bctx.DistributedTracingOpts) > 0 { client.Transport = tracing.NewTransport(client.Transport, bctx.DistributedTracingOpts) } @@ -723,7 +719,7 @@ func executeHTTPRequest(req *http.Request, client *http.Client, inputReqObj ast. var err error var retry int - retry, err = getNumberValFromReqObj(inputReqObj, keyCache["max_retry_attempts"]) + retry, err = getNumberValFromReqObj(inputReqObj, ast.InternedTerm("max_retry_attempts")) if err != nil { return nil, err } @@ -1017,15 +1013,6 @@ func insertIntoHTTPSendInterQueryCache(bctx BuiltinContext, key ast.Value, resp return nil } -func createKeys() { - for _, element := range allowedKeyNames { - term := ast.StringTerm(element) - - allowedKeys.Add(term) - keyCache[element] = term - } -} - func createCacheableHTTPStatusCodes() { for _, element := range cacheableHTTPStatusCodes { cacheableCodes.Add(ast.InternedTerm(element)) @@ -1089,7 +1076,7 @@ func getNumberValFromReqObj(req ast.Object, key *ast.Term) (int, error) { } func getCachingMode(req ast.Object) (cachingMode, error) { - key := keyCache["caching_mode"] + key := ast.InternedTerm("caching_mode") var s ast.String var ok bool if v := req.Get(key); v != nil { @@ -1192,7 +1179,8 @@ func newInterQueryCacheData(bctx BuiltinContext, resp *http.Response, respBody [ RespBody: respBody, Status: resp.Status, StatusCode: resp.StatusCode, - Headers: resp.Header} + Headers: resp.Header, + } return &cv, nil } @@ -1222,7 +1210,8 @@ func (c *interQueryCacheData) Clone() (cache.InterQueryCacheValue, error) { RespBody: dup, Status: c.Status, StatusCode: c.StatusCode, - Headers: c.Headers.Clone()}, nil + Headers: c.Headers.Clone(), + }, nil } type responseHeaders struct { @@ -1384,7 +1373,6 @@ func parseMaxAgeCacheDirective(cc map[string]string) (deltaSeconds, error) { } func formatHTTPResponseToAST(resp *http.Response, forceJSONDecode, forceYAMLDecode bool) (ast.Value, []byte, error) { - resultRawBody, err := io.ReadAll(resp.Body) if err != nil { return nil, nil, err @@ -1488,11 +1476,11 @@ func (c *interQueryCache) CheckCache() (ast.Value, error) { return resp, nil } - c.forceJSONDecode, err = getBoolValFromReqObj(c.key, keyCache["force_json_decode"]) + c.forceJSONDecode, err = getBoolValFromReqObj(c.key, ast.InternedTerm("force_json_decode")) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } - c.forceYAMLDecode, err = getBoolValFromReqObj(c.key, keyCache["force_yaml_decode"]) + c.forceYAMLDecode, err = getBoolValFromReqObj(c.key, ast.InternedTerm("force_yaml_decode")) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } @@ -1559,11 +1547,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, keyCache["force_json_decode"]) + forceJSONDecode, err := getBoolValFromReqObj(c.key, ast.InternedTerm("force_json_decode")) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } - forceYAMLDecode, err := getBoolValFromReqObj(c.key, keyCache["force_yaml_decode"]) + forceYAMLDecode, err := getBoolValFromReqObj(c.key, ast.InternedTerm("force_yaml_decode")) if err != nil { return nil, handleHTTPSendErr(c.bctx, err) } @@ -1598,12 +1586,12 @@ func (c *intraQueryCache) ExecuteHTTPRequest() (*http.Response, error) { } func useInterQueryCache(req ast.Object) (bool, *forceCacheParams, error) { - value, err := getBoolValFromReqObj(req, keyCache["cache"]) + value, err := getBoolValFromReqObj(req, ast.InternedTerm("cache")) if err != nil { return false, nil, err } - valueForceCache, err := getBoolValFromReqObj(req, keyCache["force_cache"]) + valueForceCache, err := getBoolValFromReqObj(req, ast.InternedTerm("force_cache")) if err != nil { return false, nil, err } @@ -1621,7 +1609,7 @@ type forceCacheParams struct { } func newForceCacheParams(req ast.Object) (*forceCacheParams, error) { - term := req.Get(keyCache["force_cache_duration_seconds"]) + term := req.Get(ast.InternedTerm("force_cache_duration_seconds")) if term == nil { return nil, errors.New("'force_cache' set but 'force_cache_duration_seconds' parameter is missing") } @@ -1639,7 +1627,7 @@ 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(keyCache["raise_error"]); v != nil { + if v := req.Get(ast.InternedTerm("raise_error")); v != nil { if result, ok = v.Value.(ast.Boolean); !ok { return false, errors.New("invalid value for raise_error field") } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup.go index 1b9ffc2350a7..5ad2abd8a874 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup.go @@ -1,5 +1,4 @@ -//go:build !go1.18 || !darwin -// +build !go1.18 !darwin +//go:build !darwin package topdown diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup_darwin.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup_darwin.go index ff3058ef4072..e2941cbfa101 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup_darwin.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/http_fixup_darwin.go @@ -1,6 +1,3 @@ -//go:build go1.18 -// +build go1.18 - package topdown func fixupDarwinGo118(x, y string) string { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/json.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/json.go index 2c7d64288336..9bca11cbe453 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/json.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/json.go @@ -17,8 +17,7 @@ import ( func builtinJSONRemove(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { // Expect an object and a string or array/set of strings - _, err := builtins.ObjectOperand(operands[0].Value, 1) - if err != nil { + if _, err := builtins.ObjectOperand(operands[0].Value, 1); err != nil { return err } @@ -65,7 +64,7 @@ func jsonRemove(a *ast.Term, b *ast.Term) (*ast.Term, error) { case ast.String, ast.Number, ast.Boolean, ast.Null: return a, nil case ast.Object: - newObj := ast.NewObject() + newObj := ast.NewObjectWithCapacity(aValue.Len()) err := aValue.Iter(func(k *ast.Term, v *ast.Term) error { // recurse and add the diff of sub objects as needed diffValue, err := jsonRemove(v, bObj.Get(k)) @@ -80,7 +79,7 @@ func jsonRemove(a *ast.Term, b *ast.Term) (*ast.Term, error) { } return ast.NewTerm(newObj), nil case ast.Set: - newSet := ast.NewSet() + newSet := ast.NewSetWithCapacity(aValue.Len()) err := aValue.Iter(func(v *ast.Term) error { // recurse and add the diff of sub objects as needed diffValue, err := jsonRemove(v, bObj.Get(v)) @@ -97,7 +96,7 @@ func jsonRemove(a *ast.Term, b *ast.Term) (*ast.Term, error) { case *ast.Array: // When indexes are removed we shift left to close empty spots in the array // as per the JSON patch spec. - newArray := ast.NewArray() + newArraySlice := make([]*ast.Term, 0, aValue.Len()) for i := range aValue.Len() { v := aValue.Elem(i) // recurse and add the diff of sub objects as needed @@ -107,10 +106,10 @@ func jsonRemove(a *ast.Term, b *ast.Term) (*ast.Term, error) { return nil, err } if diffValue != nil { - newArray = newArray.Append(diffValue) + newArraySlice = append(newArraySlice, diffValue) } } - return ast.NewTerm(newArray), nil + return ast.ArrayTerm(newArraySlice...), nil default: return nil, fmt.Errorf("invalid value type %T", a) } @@ -139,11 +138,10 @@ func builtinJSONFilter(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te return iter(ast.NewTerm(r)) } -func getJSONPaths(operand ast.Value) ([]ast.Ref, error) { - var paths []ast.Ref - +func getJSONPaths(operand ast.Value) (paths []ast.Ref, err error) { switch v := operand.(type) { case *ast.Array: + paths = make([]ast.Ref, 0, v.Len()) for i := range v.Len() { filter, err := parsePath(v.Elem(i)) if err != nil { @@ -152,16 +150,13 @@ func getJSONPaths(operand ast.Value) ([]ast.Ref, error) { paths = append(paths, filter) } case ast.Set: - err := v.Iter(func(f *ast.Term) error { - filter, err := parsePath(f) + paths = make([]ast.Ref, 0, v.Len()) + for _, item := range v.Slice() { + filter, err := parsePath(item) if err != nil { - return err + return nil, err } paths = append(paths, filter) - return nil - }) - if err != nil { - return nil, err } default: return nil, builtins.NewOperandTypeErr(2, v, "set", "array") @@ -170,6 +165,7 @@ func getJSONPaths(operand ast.Value) ([]ast.Ref, error) { return paths, nil } +// parsePath parses a JSON pointer path or array of path segments into an ast.Ref. func parsePath(path *ast.Term) (ast.Ref, error) { // paths can either be a `/` separated json path or // an array or set of values @@ -177,30 +173,43 @@ func parsePath(path *ast.Term) (ast.Ref, error) { switch p := path.Value.(type) { case ast.String: if p == "" { - return ast.Ref{}, nil + return ast.InternedEmptyRefValue.(ast.Ref), nil } - parts := strings.Split(strings.TrimLeft(string(p), "/"), "/") - for _, part := range parts { - part = strings.ReplaceAll(strings.ReplaceAll(part, "~1", "/"), "~0", "~") - pathSegments = append(pathSegments, ast.StringTerm(part)) + + s := strings.TrimLeft(string(p), "/") + n := strings.Count(s, "/") + 1 + + pathSegments = make(ast.Ref, 0, n) + + part, remaining, found := strings.Cut(s, "/") + unescaped := strings.ReplaceAll(strings.ReplaceAll(part, "~1", "/"), "~0", "~") + pathSegments = append(pathSegments, ast.InternedTerm(unescaped)) + + for found { + part, remaining, found = strings.Cut(remaining, "/") + unescaped := strings.ReplaceAll(strings.ReplaceAll(part, "~1", "/"), "~0", "~") + pathSegments = append(pathSegments, ast.InternedTerm(unescaped)) } case *ast.Array: - p.Foreach(func(term *ast.Term) { - pathSegments = append(pathSegments, term) - }) + pathSegments = make(ast.Ref, 0, p.Len()) + for i := range p.Len() { + pathSegments = append(pathSegments, p.Elem(i)) + } default: - 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 nil, builtins.NewOperandErr(2, + "must be one of {set, array} containing string paths or array of path segments but got "+ast.ValueName(p), + ) } return pathSegments, nil } func pathsToObject(paths []ast.Ref) ast.Object { - root := ast.NewObject() + root := ast.NewObjectWithCapacity(len(paths)) for _, path := range paths { node := root - var done bool + done := false // If the path is an empty JSON path, skip all further processing. if len(path) == 0 { @@ -209,7 +218,6 @@ func pathsToObject(paths []ast.Ref) ast.Object { // Otherwise, we should have 1+ path segments to work with. for i := 0; i < len(path)-1 && !done; i++ { - k := path[i] child := node.Get(k) @@ -238,106 +246,67 @@ func pathsToObject(paths []ast.Ref) ast.Object { return root } -type jsonPatch struct { - op string - path *ast.Term - from *ast.Term - value *ast.Term -} +func applyPatches(source *ast.Term, operations *ast.Array) (*ast.Term, error) { + et := edittree.EditTreeFromPool(source) + defer edittree.Dispose(et) -func getPatch(o ast.Object) (jsonPatch, error) { - validOps := map[string]struct{}{"add": {}, "remove": {}, "replace": {}, "move": {}, "copy": {}, "test": {}} - var out jsonPatch - var ok bool - getAttribute := func(attr string) (*ast.Term, error) { - if term := o.Get(ast.StringTerm(attr)); term != nil { - return term, nil + for i := range operations.Len() { + object, ok := operations.Elem(i).Value.(ast.Object) + if !ok { + return nil, errors.New("must be an array of JSON-Patch objects, but at least one element is not an object") } - return nil, fmt.Errorf("missing '%s' attribute", attr) - } - - opTerm, err := getAttribute("op") - if err != nil { - return out, err - } - op, ok := opTerm.Value.(ast.String) - if !ok { - return out, errors.New("attribute 'op' must be a string") - } - out.op = string(op) - if _, found := validOps[out.op]; !found { - out.op = "" - return out, fmt.Errorf("unrecognized op '%s'", string(op)) - } - - pathTerm, err := getAttribute("path") - if err != nil { - return out, err - } - out.path = pathTerm - - // Only fetch the "from" parameter for move/copy ops. - switch out.op { - case "move", "copy": - fromTerm, err := getAttribute("from") - if err != nil { - return out, err + // Validate + if object.Get(ast.InternedTerm("path")) == nil { + return nil, errors.New("missing required attribute 'path'") } - out.from = fromTerm - } - // Only fetch the "value" parameter for add/replace/test ops. - switch out.op { - case "add", "replace", "test": - valueTerm, err := getAttribute("value") - if err != nil { - return out, err + opTerm := object.Get(ast.InternedTerm("op")) + if opTerm == nil { + return nil, errors.New("missing required attribute 'op'") } - out.value = valueTerm - } - return out, nil -} - -func applyPatches(source *ast.Term, operations *ast.Array) (*ast.Term, error) { - et := edittree.NewEditTree(source) - for i := range operations.Len() { - object, ok := operations.Elem(i).Value.(ast.Object) + opStr, ok := opTerm.Value.(ast.String) if !ok { - return nil, errors.New("must be an array of JSON-Patch objects, but at least one element is not an object") + return nil, errors.New("attribute 'op' must be a string but found: " + ast.ValueName(opTerm.Value)) } - patch, err := getPatch(object) - if err != nil { - return nil, err - } - path, err := parsePath(patch.path) + + path, err := parsePath(object.Get(ast.InternedTerm("path"))) if err != nil { return nil, err } - switch patch.op { + switch string(opStr) { case "add": - _, err = et.InsertAtPath(path, patch.value) - if err != nil { + value := object.Get(ast.InternedTerm("value")) + if value == nil { + return nil, errors.New("missing required attribute 'value'") + } + if _, err = et.InsertAtPath(path, value); err != nil { return nil, err } case "remove": - _, err = et.DeleteAtPath(path) - if err != nil { + if _, err = et.DeleteAtPath(path); err != nil { return nil, err } case "replace": - _, err = et.DeleteAtPath(path) - if err != nil { + if _, err = et.DeleteAtPath(path); err != nil { return nil, err } - _, err = et.InsertAtPath(path, patch.value) - if err != nil { + value := object.Get(ast.InternedTerm("value")) + if value == nil { + return nil, errors.New("missing required attribute 'value'") + } + if _, err = et.InsertAtPath(path, value); err != nil { return nil, err } case "move": - from, err := parsePath(patch.from) + fromValue := object.Get(ast.InternedTerm("from")) + if fromValue == nil { + return nil, errors.New("missing required attribute 'from'") + } + + from, err := parsePath(fromValue) if err != nil { return nil, err } @@ -345,16 +314,18 @@ func applyPatches(source *ast.Term, operations *ast.Array) (*ast.Term, error) { if err != nil { return nil, err } - _, err = et.DeleteAtPath(from) - if err != nil { + if _, err = et.DeleteAtPath(from); err != nil { return nil, err } - _, err = et.InsertAtPath(path, chunk) - if err != nil { + if _, err = et.InsertAtPath(path, chunk); err != nil { return nil, err } case "copy": - from, err := parsePath(patch.from) + fromValue := object.Get(ast.InternedTerm("from")) + if fromValue == nil { + return nil, errors.New("missing required attribute 'from'") + } + from, err := parsePath(fromValue) if err != nil { return nil, err } @@ -362,8 +333,7 @@ func applyPatches(source *ast.Term, operations *ast.Array) (*ast.Term, error) { if err != nil { return nil, err } - _, err = et.InsertAtPath(path, chunk) - if err != nil { + if _, err = et.InsertAtPath(path, chunk); err != nil { return nil, err } case "test": @@ -371,34 +341,41 @@ func applyPatches(source *ast.Term, operations *ast.Array) (*ast.Term, error) { if err != nil { return nil, err } - if !chunk.Equal(patch.value) { - return nil, fmt.Errorf("value from EditTree != patch value.\n\nExpected: %v\n\nFound: %v", patch.value, chunk) + value := object.Get(ast.InternedTerm("value")) + if value == nil { + return nil, errors.New("missing required attribute 'value'") + } + if !chunk.Equal(value) { + return nil, fmt.Errorf("value from EditTree != patch value.\n\nExpected: %v\n\nFound: %v", value, chunk) } + default: + return nil, fmt.Errorf("unrecognized op: '%s'", string(opStr)) } } - final := et.Render() - // TODO: Nil check here? - return final, nil + + return et.Render(), nil } func builtinJSONPatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - // JSON patch supports arrays, objects as well as values as the target. - target := ast.NewTerm(operands[0].Value) - // Expect an array of operations. operations, err := builtins.ArrayOperand(operands[1].Value, 2) if err != nil { return err } - patched, err := applyPatches(target, operations) + // JSON patch supports arrays, objects as well as values as the target. + patched, err := applyPatches(operands[0], operations) if err != nil { - return nil + return err } return iter(patched) } func init() { + for _, key := range []string{"op", "path", "from", "value", "add", "remove", "replace", "move", "copy", "test"} { + ast.InternStringTerm(key) + } + RegisterBuiltinFunc(ast.JSONFilter.Name, builtinJSONFilter) RegisterBuiltinFunc(ast.JSONRemove.Name, builtinJSONRemove) RegisterBuiltinFunc(ast.JSONPatch.Name, builtinJSONPatch) diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/jsonschema.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/jsonschema.go index 699f1d0d9952..e48719d145ca 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/jsonschema.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/jsonschema.go @@ -27,7 +27,7 @@ func astValueToJSONSchemaLoader(value ast.Value) (gojsonschema.JSONLoader, error return nil, errors.New("invalid JSON string") } loader = gojsonschema.NewStringLoader(string(x)) - case ast.Object: + case ast.Object, *ast.Array: // In case of object serialize it to JSON representation. var data any data, err = ast.JSON(value) @@ -110,7 +110,7 @@ func builtinJSONMatchSchema(bctx BuiltinContext, operands []*ast.Term, iter func } // In case of validation errors produce Rego array of objects to describe the errors. - arr := ast.NewArray() + arr := ast.NewArrayWithCapacity(len(result.Errors())) for _, re := range result.Errors() { o := ast.NewObject( [...]*ast.Term{ast.StringTerm("error"), ast.StringTerm(re.String())}, diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/net.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/net.go index 17ed77984492..6caa068b478f 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/net.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/net.go @@ -49,7 +49,7 @@ func builtinLookupIPAddr(bctx BuiltinContext, operands []*ast.Term, iter func(*a return err } - ret := ast.NewSet() + ret := ast.NewSetWithCapacity(len(addrs)) for _, a := range addrs { ret.Add(ast.StringTerm(a.String())) diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/numbers.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/numbers.go index 1e05a247a93c..fdf6444939be 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/numbers.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/numbers.go @@ -96,7 +96,7 @@ func canGenerateCheapRange(operands []*ast.Term) bool { func canGenerateCheapRangeStep(operands []*ast.Term) bool { if canGenerateCheapRange(operands) { - step, err := builtins.IntOperand(operands[1].Value, 3) + step, err := builtins.IntOperand(operands[2].Value, 3) if err == nil && ast.HasInternedIntNumberTerm(step) { return true } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/object.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/object.go index c6fbe7022fbc..fe5ccf093fbc 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/object.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/object.go @@ -52,13 +52,21 @@ func builtinObjectUnionN(_ BuiltinContext, operands []*ast.Term, iter func(*ast. // Example: // Input: [{"a": {"b": 2}}, {"a": 4}, {"a": {"c": 3}}] // Want Output: {"a": {"c": 3}} - result := ast.NewObject() - frozenKeys := map[*ast.Term]struct{}{} - for i := arr.Len() - 1; i >= 0; i-- { + + // First pass: count total keys for pre-allocation + totalSize := 0 + for i := range arr.Len() { o, ok := arr.Elem(i).Value.(ast.Object) if !ok { return builtins.NewOperandElementErr(1, arr, arr.Elem(i).Value, "object") } + totalSize += o.Len() + } + + result := ast.NewObjectWithCapacity(totalSize) + frozenKeys := make(map[*ast.Term]struct{}, totalSize) + for i := arr.Len() - 1; i >= 0; i-- { + o := arr.Elem(i).Value.(ast.Object) // Already validated above mergewithOverwriteInPlace(result, o, frozenKeys) } @@ -77,7 +85,9 @@ func builtinObjectRemove(_ BuiltinContext, operands []*ast.Term, iter func(*ast. if err != nil { return err } - r := ast.NewObject() + + // Pre-allocate with obj size (upper bound for result) + r := ast.NewObjectWithCapacity(obj.Len()) obj.Foreach(func(key *ast.Term, value *ast.Term) { if !keysToRemove.Contains(key) { r.Insert(key, value) @@ -100,7 +110,8 @@ func builtinObjectFilter(_ BuiltinContext, operands []*ast.Term, iter func(*ast. return err } - filterObj := ast.NewObject() + // Pre-allocate with keys size (upper bound for filter object) + filterObj := ast.NewObjectWithCapacity(keys.Len()) keys.Foreach(func(key *ast.Term) { filterObj.Insert(key, ast.InternedNullTerm) }) @@ -158,15 +169,19 @@ func builtinObjectKeys(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te } // getObjectKeysParam returns a set of key values -// from a supplied ast array, object, set value +// from a supplied ast array, object, set value. +// The returned set must not be mutated. For Set +// inputs, it may be the original. func getObjectKeysParam(arrayOrSet ast.Value) (ast.Set, error) { switch v := arrayOrSet.(type) { case *ast.Array: - keys := ast.NewSet() + keys := ast.NewSetWithCapacity(v.Len()) v.Foreach(keys.Add) return keys, nil case ast.Set: - return ast.NewSet(v.Slice()...), nil + // Return directly. Callers only use this for Contains() checks + // without mutating the set. + return v, nil case ast.Object: return ast.NewSet(v.Keys()...), nil } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/print.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/print.go index f852f3e320ac..acf55f0f3fd0 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/print.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/print.go @@ -28,7 +28,6 @@ func (h printHook) Print(_ print.Context, msg string) error { } func builtinPrint(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - if bctx.PrintHook == nil { return iter(nil) } @@ -40,7 +39,7 @@ func builtinPrint(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term buf := make([]string, arr.Len()) - err = builtinPrintCrossProductOperands(bctx, buf, arr, 0, func(buf []string) error { + err = builtinPrintCrossProductOperands(bctx.Location, buf, arr, 0, func(buf []string) error { pctx := print.Context{ Context: bctx.Context, Location: bctx.Location, @@ -54,20 +53,32 @@ func builtinPrint(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term return iter(nil) } -func builtinPrintCrossProductOperands(bctx BuiltinContext, buf []string, operands *ast.Array, i int, f func([]string) error) error { - +func builtinPrintCrossProductOperands(loc *ast.Location, buf []string, operands *ast.Array, i int, f func([]string) error) error { if i >= operands.Len() { return f(buf) } - xs, ok := operands.Elem(i).Value.(ast.Set) + operand := operands.Elem(i) + + // We allow primitives ... + switch x := operand.Value.(type) { + case ast.String: + buf[i] = string(x) + return builtinPrintCrossProductOperands(loc, buf, operands, i+1, f) + case ast.Number, ast.Boolean, ast.Null: + buf[i] = x.String() + return builtinPrintCrossProductOperands(loc, buf, operands, i+1, f) + } + + // ... but all other operand types must be sets. + xs, ok := operand.Value.(ast.Set) if !ok { - return Halt{Err: internalErr(bctx.Location, fmt.Sprintf("illegal argument type: %v", ast.ValueName(operands.Elem(i).Value)))} + return Halt{Err: internalErr(loc, "illegal argument type: "+ast.ValueName(operand.Value))} } if xs.Len() == 0 { buf[i] = "" - return builtinPrintCrossProductOperands(bctx, buf, operands, i+1, f) + return builtinPrintCrossProductOperands(loc, buf, operands, i+1, f) } return xs.Iter(func(x *ast.Term) error { @@ -77,7 +88,7 @@ func builtinPrintCrossProductOperands(bctx BuiltinContext, buf []string, operand default: buf[i] = v.String() } - return builtinPrintCrossProductOperands(bctx, buf, operands, i+1, f) + return builtinPrintCrossProductOperands(loc, buf, operands, i+1, f) }) } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/providers.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/providers.go index dd84026e4b33..29d721e4b2d5 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/providers.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/providers.go @@ -14,12 +14,7 @@ import ( "github.com/open-policy-agent/opa/v1/topdown/builtins" ) -var awsRequiredConfigKeyNames = ast.NewSet( - ast.StringTerm("aws_service"), - ast.StringTerm("aws_access_key"), - ast.StringTerm("aws_secret_access_key"), - ast.StringTerm("aws_region"), -) +var awsRequiredConfigKeyNames ast.Set func stringFromTerm(t *ast.Term) string { if v, ok := t.Value.(ast.String); ok { @@ -103,7 +98,7 @@ func builtinAWSSigV4SignReq(_ BuiltinContext, operands []*ast.Term, iter func(*a if err != nil { return err } - service := stringFromTerm(awsConfigObj.Get(ast.StringTerm("aws_service"))) + service := stringFromTerm(awsConfigObj.Get(ast.InternedTerm("aws_service"))) awsCreds := aws.CredentialsFromObject(awsConfigObj) // Timestamp for signing. @@ -130,11 +125,12 @@ func builtinAWSSigV4SignReq(_ BuiltinContext, operands []*ast.Term, iter func(*a // Prepare required fields from the HTTP request object. var theURL *url.URL var method string - reqURL := reqObj.Get(ast.StringTerm("url")) - reqMethod := reqObj.Get(ast.StringTerm("method")) + reqURL := reqObj.Get(ast.InternedTerm("url")) + keyMethod := ast.InternedTerm("method") + reqMethod := reqObj.Get(keyMethod) headers := ast.NewObject() - headersTerm := reqObj.Get(ast.StringTerm("headers")) + headersTerm := reqObj.Get(ast.InternedTerm("headers")) if headersTerm != nil { var ok bool headers, ok = headersTerm.Value.(ast.Object) @@ -146,10 +142,10 @@ func builtinAWSSigV4SignReq(_ BuiltinContext, operands []*ast.Term, iter func(*a // Check types on the request parameters. invalidParameters := ast.NewSet() if _, ok := reqURL.Value.(ast.String); !ok { - invalidParameters.Add(ast.StringTerm("url")) + invalidParameters.Add(ast.InternedTerm("url")) } if _, ok := reqMethod.Value.(ast.String); !ok { - invalidParameters.Add(ast.StringTerm("method")) + invalidParameters.Add(keyMethod) } if invalidParameters.Len() > 0 { return builtins.NewOperandErr(1, "invalid values for required request parameters(s): %v", invalidParameters) @@ -161,8 +157,8 @@ func builtinAWSSigV4SignReq(_ BuiltinContext, operands []*ast.Term, iter func(*a } method = stringFromTerm(reqMethod) - bodyTerm := reqObj.Get(ast.StringTerm("body")) - rawBodyTerm := reqObj.Get(ast.StringTerm("raw_body")) + bodyTerm := reqObj.Get(ast.InternedTerm("body")) + rawBodyTerm := reqObj.Get(ast.InternedTerm("raw_body")) body, err := getReqBodyBytes(bodyTerm, rawBodyTerm) if err != nil { return err @@ -173,7 +169,7 @@ func builtinAWSSigV4SignReq(_ BuiltinContext, operands []*ast.Term, iter func(*a // if payload signing config is set, pass it down to the signing method disablePayloadSigning := false - t := awsConfigObj.Get(ast.StringTerm("disable_payload_signing")) + t := awsConfigObj.Get(ast.InternedTerm("disable_payload_signing")) if t != nil { if v, ok := t.Value.(ast.Boolean); ok { disablePayloadSigning = bool(v) @@ -188,24 +184,37 @@ func builtinAWSSigV4SignReq(_ BuiltinContext, operands []*ast.Term, iter func(*a for k, v := range headersMap { // objectToMap doesn't support arrays if len(v) == 1 { - signedHeadersObj.Insert(ast.StringTerm(k), ast.StringTerm(v[0])) + signedHeadersObj.Insert(ast.InternedTerm(k), ast.StringTerm(v[0])) } } // Set authorization header - signedHeadersObj.Insert(ast.StringTerm("Authorization"), ast.StringTerm(authHeader)) + signedHeadersObj.Insert(ast.InternedTerm("Authorization"), ast.StringTerm(authHeader)) // set aws signature headers for k, v := range awsHeadersMap { - signedHeadersObj.Insert(ast.StringTerm(k), ast.StringTerm(v)) + signedHeadersObj.Insert(ast.InternedTerm(k), ast.StringTerm(v)) } // Create new request object with updated headers. out := reqObj.Copy() - out.Insert(ast.StringTerm("headers"), ast.NewTerm(signedHeadersObj)) + out.Insert(ast.InternedTerm("headers"), ast.NewTerm(signedHeadersObj)) return iter(ast.NewTerm(out)) } func init() { + for _, key := range []string{ + "aws_service", "aws_access_key", "aws_secret_access_key", "aws_region", "disable_payload_signing", + } { + ast.InternStringTerm(key) + } + + awsRequiredConfigKeyNames = ast.NewSet( + ast.InternedTerm("aws_service"), + ast.InternedTerm("aws_access_key"), + ast.InternedTerm("aws_secret_access_key"), + ast.InternedTerm("aws_region"), + ) + RegisterBuiltinFunc(ast.ProvidersAWSSignReqObj.Name, builtinAWSSigV4SignReq) } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/query.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/query.go index aadcc060cfd5..a65f8a312cf0 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/query.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/query.go @@ -121,6 +121,7 @@ func (q *Query) WithInput(input *ast.Term) *Query { } // WithTracer adds a query tracer to use during evaluation. This is optional. +// // Deprecated: Use WithQueryTracer instead. func (q *Query) WithTracer(tracer Tracer) *Query { qt, ok := tracer.(QueryTracer) @@ -133,7 +134,7 @@ func (q *Query) WithTracer(tracer Tracer) *Query { // WithQueryTracer adds a query tracer to use during evaluation. This is optional. // Disabled QueryTracers will be ignored. func (q *Query) WithQueryTracer(tracer QueryTracer) *Query { - if !tracer.Enabled() { + if tracer == nil || !tracer.Enabled() { return q } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/regex.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/regex.go index 1d2906ee2ee0..031345203334 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/regex.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/regex.go @@ -7,6 +7,7 @@ package topdown import ( "fmt" "regexp" + "regexp/syntax" "sync" gintersect "github.com/yashtewari/glob-intersection" @@ -15,25 +16,24 @@ import ( "github.com/open-policy-agent/opa/v1/topdown/builtins" ) -const regexCacheMaxSize = 100 -const regexInterQueryValueCacheHits = "rego_builtin_regex_interquery_value_cache_hits" +const ( + regexCacheMaxSize = 100 + regexInterQueryValueCacheHits = "rego_builtin_regex_interquery_value_cache_hits" +) -var regexpCacheLock = sync.Mutex{} -var regexpCache map[string]*regexp.Regexp +var ( + regexpCacheLock = sync.RWMutex{} + regexpCache = make(map[string]*regexp.Regexp) +) func builtinRegexIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - - s, err := builtins.StringOperand(operands[0].Value, 1) - if err != nil { - return iter(ast.InternedTerm(false)) - } - - _, err = regexp.Compile(string(s)) - if err != nil { - return iter(ast.InternedTerm(false)) + if s, err := builtins.StringOperand(operands[0].Value, 1); err == nil { + if _, err = syntax.Parse(string(s), syntax.Perl); err == nil { + return iter(ast.InternedTerm(true)) + } } - return iter(ast.InternedTerm(true)) + return iter(ast.InternedTerm(false)) } func builtinRegexMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -107,7 +107,8 @@ 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)) + var key ast.Value = ast.String(pat) + val, ok := bctx.InterQueryBuiltinValueCache.Get(key) if ok { res, valid := val.(*regexp.Regexp) if !valid { @@ -124,20 +125,23 @@ func getRegexp(bctx BuiltinContext, pat string) (*regexp.Regexp, error) { if err != nil { return nil, err } - bctx.InterQueryBuiltinValueCache.Insert(ast.String(pat), re) + bctx.InterQueryBuiltinValueCache.Insert(key, re) return re, nil } - regexpCacheLock.Lock() - defer regexpCacheLock.Unlock() + regexpCacheLock.RLock() re, ok := regexpCache[pat] + numCached := len(regexpCache) + regexpCacheLock.RUnlock() if !ok { var err error re, err = regexp.Compile(pat) if err != nil { return nil, err } - if len(regexpCache) >= regexCacheMaxSize { + + regexpCacheLock.Lock() + if numCached >= regexCacheMaxSize { // Delete a (semi-)random key to make room for the new one. for k := range regexpCache { delete(regexpCache, k) @@ -145,21 +149,24 @@ func getRegexp(bctx BuiltinContext, pat string) (*regexp.Regexp, error) { } } regexpCache[pat] = re + regexpCacheLock.Unlock() } return re, nil } func getRegexpTemplate(pat string, delimStart, delimEnd byte) (*regexp.Regexp, error) { - regexpCacheLock.Lock() - defer regexpCacheLock.Unlock() + regexpCacheLock.RLock() re, ok := regexpCache[pat] + regexpCacheLock.RUnlock() if !ok { var err error re, err = compileRegexTemplate(pat, delimStart, delimEnd) if err != nil { return nil, err } + regexpCacheLock.Lock() regexpCache[pat] = re + regexpCacheLock.Unlock() } return re, nil } @@ -259,7 +266,41 @@ func builtinRegexReplace(bctx BuiltinContext, operands []*ast.Term, iter func(*a return err } - res := re.ReplaceAllString(string(base), string(value)) + // If no cancellation context, use the fast path + if bctx.Cancel == nil { + res := re.ReplaceAllString(string(base), string(value)) + if res == string(base) { + return iter(operands[0]) + } + return iter(ast.InternedTerm(res)) + } + + // Use sink writer for cancellation-aware replacement + sink := newSink(ast.RegexReplace.Name, len(base), bctx.Cancel) + src := []byte(base) + repl := []byte(value) + + // Find all matches at once to preserve anchor behavior: replace("foo", "^[a-z]", "F") => "Foo" + allMatches := re.FindAllSubmatchIndex(src, -1) + + lastEnd := 0 + for _, match := range allMatches { + if _, err := sink.Write(src[lastEnd:match[0]]); err != nil { + return err + } + + if _, err := sink.Write(re.Expand(nil, repl, src, match)); err != nil { + return err + } + + lastEnd = match[1] + } + + if _, err := sink.Write(src[lastEnd:]); err != nil { + return err + } + + res := sink.String() if res == string(base) { return iter(operands[0]) } @@ -268,7 +309,6 @@ func builtinRegexReplace(bctx BuiltinContext, operands []*ast.Term, iter func(*a } func init() { - regexpCache = map[string]*regexp.Regexp{} RegisterBuiltinFunc(ast.RegexIsValid.Name, builtinRegexIsValid) RegisterBuiltinFunc(ast.RegexMatch.Name, builtinRegexMatch) RegisterBuiltinFunc(ast.RegexMatchDeprecated.Name, builtinRegexMatch) diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/resolver.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/resolver.go index 8fff22b1d3ef..6688c8306194 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/resolver.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/resolver.go @@ -99,7 +99,7 @@ func (t *resolverTrie) mktree(e *eval, in resolver.Input) (ast.Value, error) { } return result.Value, nil } - obj := ast.NewObject() + obj := ast.NewObjectWithCapacity(len(t.children)) for k, child := range t.children { v, err := child.mktree(e, resolver.Input{Ref: append(in.Ref, ast.NewTerm(k)), Input: in.Input, Metrics: in.Metrics}) if err != nil { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/semver.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/semver.go index 3b79ebd58643..1b2ac79038e4 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/semver.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/semver.go @@ -23,34 +23,25 @@ func builtinSemVerCompare(_ BuiltinContext, operands []*ast.Term, iter func(*ast return err } - versionA, err := semver.NewVersion(string(versionStringA)) + versionA, err := semver.Parse(string(versionStringA)) if err != nil { return fmt.Errorf("operand 1: string %s is not a valid SemVer", versionStringA) } - versionB, err := semver.NewVersion(string(versionStringB)) + versionB, err := semver.Parse(string(versionStringB)) if err != nil { return fmt.Errorf("operand 2: string %s is not a valid SemVer", versionStringB) } - result := versionA.Compare(*versionB) - - return iter(ast.InternedTerm(result)) + return iter(ast.InternedTerm(versionA.Compare(versionB))) } 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.InternedTerm(false)) - } - - result := true - - _, err = semver.NewVersion(string(versionString)) - if err != nil { - result = false + if err == nil { + _, err = semver.Parse(string(versionString)) } - return iter(ast.InternedTerm(result)) + return iter(ast.InternedTerm(err == nil)) } func init() { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/sets.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/sets.go index c50efe4a8018..6ee467efc863 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/sets.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/sets.go @@ -61,22 +61,34 @@ func builtinSetIntersection(_ BuiltinContext, operands []*ast.Term, iter func(*a // builtinSetUnion returns the union of the given input sets func builtinSetUnion(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { - // The set union logic here is duplicated and manually inlined on - // purpose. By lifting this logic up a level, and not doing pairwise - // set unions, we avoid a number of heap allocations. This improves - // performance dramatically over the naive approach. - result := ast.NewSet() - + // The set union logic here is manually inlined on purpose. By lifting + // this logic up a level and not doing pairwise set unions, we avoid + // many heap allocations. We also pre-allocate the result set by first + // counting total elements across all input sets. inputSet, err := builtins.SetOperand(operands[0].Value, 1) if err != nil { return err } + // First pass: count total elements for pre-allocation + totalSize := 0 err = inputSet.Iter(func(x *ast.Term) error { item, err := builtins.SetOperand(x.Value, 1) if err != nil { return err } + totalSize += item.Len() + return nil + }) + if err != nil { + return err + } + + // Pre-allocate result set with estimated capacity + result := ast.NewSetWithCapacity(totalSize) + + err = inputSet.Iter(func(x *ast.Term) error { + item, _ := builtins.SetOperand(x.Value, 1) // error checked above item.Foreach(result.Add) return nil }) diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/sink.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/sink.go new file mode 100644 index 000000000000..15208086b22d --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/sink.go @@ -0,0 +1,73 @@ +package topdown + +import ( + "bytes" + "io" +) + +var _ io.Writer = (*sinkW)(nil) + +type sinkWriter interface { + io.Writer + String() string + Grow(int) + WriteByte(byte) error + WriteString(string) (int, error) +} + +type sinkW struct { + buf *bytes.Buffer + cancel Cancel + err error +} + +func newSink(name string, hint int, c Cancel) sinkWriter { + b := &bytes.Buffer{} + if hint > 0 { + b.Grow(hint) + } + + if c == nil { + return b + } + + return &sinkW{ + cancel: c, + buf: b, + err: Halt{ + Err: &Error{ + Code: CancelErr, + Message: name + ": timed out before finishing", + }, + }, + } +} + +func (sw *sinkW) Grow(n int) { + sw.buf.Grow(n) +} + +func (sw *sinkW) Write(bs []byte) (int, error) { + if sw.cancel.Cancelled() { + return 0, sw.err + } + return sw.buf.Write(bs) +} + +func (sw *sinkW) WriteByte(b byte) error { + if sw.cancel.Cancelled() { + return sw.err + } + return sw.buf.WriteByte(b) +} + +func (sw *sinkW) WriteString(s string) (int, error) { + if sw.cancel.Cancelled() { + return 0, sw.err + } + return sw.buf.WriteString(s) +} + +func (sw *sinkW) String() string { + return sw.buf.String() +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/strings.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/strings.go index 13e9b81339c6..27c841102b99 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/strings.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/strings.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "math/big" - "sort" "strconv" "strings" "unicode" @@ -152,7 +151,7 @@ func builtinFormatInt(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter return iter(ast.InternedTerm(fmt.Sprintf(format, i))) } -func builtinConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { +func builtinConcat(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { join, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { return err @@ -163,11 +162,13 @@ func builtinConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return iter(term) } + sb := newSink(ast.Concat.Name, 0, bctx.Cancel) + // NOTE(anderseknert): // More or less Go's strings.Join implementation, but where we avoid // creating an intermediate []string slice to pass to that function, // as that's expensive (3.5x more space allocated). Instead we build - // the string directly using a strings.Builder to concatenate the string + // the string directly using the sink to concatenate the string // values from the array/set with the separator. n := 0 switch b := operands[1].Value.(type) { @@ -182,25 +183,36 @@ func builtinConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) } sep := string(join) n += len(sep) * (l - 1) - var sb strings.Builder sb.Grow(n) - sb.WriteString(string(b.Elem(0).Value.(ast.String))) + if _, err := sb.WriteString(string(b.Elem(0).Value.(ast.String))); err != nil { + return err + } if sep == "" { for i := 1; i < l; i++ { - sb.WriteString(string(b.Elem(i).Value.(ast.String))) + if _, err := sb.WriteString(string(b.Elem(i).Value.(ast.String))); err != nil { + return err + } } } else if len(sep) == 1 { // when the separator is a single byte, sb.WriteByte is substantially faster bsep := sep[0] for i := 1; i < l; i++ { - sb.WriteByte(bsep) - sb.WriteString(string(b.Elem(i).Value.(ast.String))) + if err := sb.WriteByte(bsep); err != nil { + return err + } + if _, err := sb.WriteString(string(b.Elem(i).Value.(ast.String))); err != nil { + return err + } } } else { // for longer separators, there is no such difference between WriteString and Write for i := 1; i < l; i++ { - sb.WriteString(sep) - sb.WriteString(string(b.Elem(i).Value.(ast.String))) + if _, err := sb.WriteString(sep); err != nil { + return err + } + if _, err := sb.WriteString(string(b.Elem(i).Value.(ast.String))); err != nil { + return err + } } } return iter(ast.InternedTerm(sb.String())) @@ -215,12 +227,15 @@ func builtinConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) sep := string(join) l := b.Len() n += len(sep) * (l - 1) - var sb strings.Builder sb.Grow(n) for i, v := range b.Slice() { - sb.WriteString(string(v.Value.(ast.String))) + if _, err := sb.WriteString(string(v.Value.(ast.String))); err != nil { + return err + } if i < l-1 { - sb.WriteString(sep) + if _, err := sb.WriteString(sep); err != nil { + return err + } } } return iter(ast.InternedTerm(sb.String())) @@ -523,7 +538,7 @@ func builtinSplit(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e return iter(ast.ArrayTerm(util.SplitMap(text, delim, ast.InternedTerm)...)) } -func builtinReplace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { +func builtinReplace(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { s, err := builtins.StringOperand(operands[0].Value, 1) if err != nil { return err @@ -539,7 +554,12 @@ func builtinReplace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return err } - replaced := strings.ReplaceAll(string(s), string(old), string(n)) + sink := newSink(ast.Replace.Name, len(s), bctx.Cancel) + replacer := strings.NewReplacer(string(old), string(n)) + if _, err := replacer.WriteString(sink, string(s)); err != nil { + return err + } + replaced := sink.String() if replaced == string(s) { return iter(operands[0]) } @@ -547,34 +567,38 @@ func builtinReplace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return iter(ast.InternedTerm(replaced)) } -func builtinReplaceN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { +func builtinReplaceN(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { patterns, err := builtins.ObjectOperand(operands[0].Value, 1) if err != nil { return err } - keys := patterns.Keys() - sort.Slice(keys, func(i, j int) bool { return ast.Compare(keys[i].Value, keys[j].Value) < 0 }) s, err := builtins.StringOperand(operands[1].Value, 2) if err != nil { return err } - oldnewArr := make([]string, 0, len(keys)*2) + keys := util.SortedFunc(patterns.Keys(), ast.TermValueCompare) + pairs := make([]string, 0, len(keys)*2) + for _, k := range keys { keyVal, ok := k.Value.(ast.String) if !ok { return builtins.NewOperandErr(1, "non-string key found in pattern object") } - val := patterns.Get(k) // cannot be nil - strVal, ok := val.Value.(ast.String) + strVal, ok := patterns.Get(k).Value.(ast.String) if !ok { return builtins.NewOperandErr(1, "non-string value found in pattern object") } - oldnewArr = append(oldnewArr, string(keyVal), string(strVal)) + pairs = append(pairs, string(keyVal), string(strVal)) } - return iter(ast.InternedTerm(strings.NewReplacer(oldnewArr...).Replace(string(s)))) + sink := newSink(ast.ReplaceN.Name, len(s), bctx.Cancel) + replacer := strings.NewReplacer(pairs...) + if _, err := replacer.WriteString(sink, string(s)); err != nil { + return err + } + return iter(ast.InternedTerm(sink.String())) } func builtinTrim(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { @@ -588,12 +612,13 @@ func builtinTrim(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er return err } - trimmed := strings.Trim(string(s), string(c)) - if trimmed == string(s) { + str := string(s) + trimmed := strings.Trim(str, string(c)) + if trimmed == str { return iter(operands[0]) } - return iter(ast.InternedTerm(strings.Trim(string(s), string(c)))) + return iter(ast.InternedTerm(trimmed)) } func builtinTrimLeft(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/template.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/template.go index 29038a6579ab..524c5bde0d48 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/template.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/template.go @@ -2,6 +2,7 @@ package topdown import ( "bytes" + "strings" "text/template" "github.com/open-policy-agent/opa/v1/ast" @@ -30,14 +31,13 @@ func renderTemplate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) return err } - // Do not attempt to render if template variable keys are missing - tmpl.Option("missingkey=error") var buf bytes.Buffer if err := tmpl.Execute(&buf, templateVariables); err != nil { return err } - return iter(ast.StringTerm(buf.String())) + res := strings.ReplaceAll(buf.String(), "", "") + return iter(ast.StringTerm(res)) } func init() { diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/template_string.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/template_string.go new file mode 100644 index 000000000000..0e705b81bf1d --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/template_string.go @@ -0,0 +1,45 @@ +// 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 ( + "strings" + + "github.com/open-policy-agent/opa/v1/ast" + "github.com/open-policy-agent/opa/v1/topdown/builtins" +) + +func builtinTemplateString(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error { + arr, err := builtins.ArrayOperand(operands[0].Value, 1) + if err != nil { + return err + } + + buf := make([]string, arr.Len()) + + var count int + err = builtinPrintCrossProductOperands(bctx.Location, buf, arr, 0, func(buf []string) error { + count += 1 + // Precautionary run-time assertion that template-strings can't produce multiple outputs; e.g. for custom relation type built-ins not known at compile-time. + if count > 1 { + return Halt{Err: &Error{ + Code: ConflictErr, + Location: bctx.Location, + Message: "template-strings must not produce multiple outputs", + }} + } + return nil + }) + + if err != nil { + return err + } + + return iter(ast.StringTerm(strings.Join(buf, ""))) +} + +func init() { + RegisterBuiltinFunc(ast.InternalTemplateString.Name, builtinTemplateString) +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/tokens.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/tokens.go index aea15dd26a47..bb2c9e1c1c88 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/tokens.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/tokens.go @@ -21,6 +21,7 @@ import ( "fmt" "hash" "math/big" + "strconv" "strings" "github.com/lestrrat-go/jwx/v3/jwk" @@ -428,7 +429,7 @@ func builtinJWTVerify(bctx BuiltinContext, jwt ast.Value, keyStr ast.Value, hash // If a match is found, verify using only that key. Only applicable when a JWKS was provided. if header.kid != "" { if key := getKeyByKid(header.kid, keys); key != nil { - err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), []byte(signature)) + err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), signature) return done(err == nil) } @@ -440,7 +441,7 @@ func builtinJWTVerify(bctx BuiltinContext, jwt ast.Value, keyStr ast.Value, hash if key.alg == "" { // No algorithm provided for the key - this is likely a certificate and not a JWKS, so // we'll need to verify to find out - err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), []byte(signature)) + err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), signature) if err == nil { return done(true) } @@ -448,7 +449,7 @@ func builtinJWTVerify(bctx BuiltinContext, jwt ast.Value, keyStr ast.Value, hash if header.alg != key.alg { continue } - err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), []byte(signature)) + err = verify(key.key, getInputSHA([]byte(token.header+"."+token.payload), hasher), signature) if err == nil { return done(true) } @@ -509,7 +510,7 @@ func builtinJWTVerifyHS(bctx BuiltinContext, operands []*ast.Term, hashF func() return err } - valid := hmac.Equal([]byte(signature), mac.Sum(nil)) + valid := hmac.Equal(signature, mac.Sum(nil)) putTokenInCache(bctx, jwt, astSecret, nil, nil, valid) @@ -662,7 +663,7 @@ func (constraints *tokenConstraints) validate() error { } // verify verifies a JWT using the constraints and the algorithm from the header -func (constraints *tokenConstraints) verify(kid, alg, header, payload, signature string) error { +func (constraints *tokenConstraints) verify(kid, alg, header, payload string, signature []byte) error { // Construct the payload plaintext := append(append([]byte(header), '.'), []byte(payload)...) @@ -670,7 +671,7 @@ func (constraints *tokenConstraints) verify(kid, alg, header, payload, signature if constraints.keys != nil { if kid != "" { if key := getKeyByKid(kid, constraints.keys); key != nil { - err := jwsbb.Verify(key.key, alg, plaintext, []byte(signature)) + err := jwsbb.Verify(key.key, alg, plaintext, signature) if err != nil { return errSignatureNotVerified } @@ -681,7 +682,7 @@ func (constraints *tokenConstraints) verify(kid, alg, header, payload, signature verified := false for _, key := range constraints.keys { if key.alg == "" { - err := jwsbb.Verify(key.key, alg, plaintext, []byte(signature)) + err := jwsbb.Verify(key.key, alg, plaintext, signature) if err == nil { verified = true break @@ -690,7 +691,7 @@ func (constraints *tokenConstraints) verify(kid, alg, header, payload, signature if alg != key.alg { continue } - err := jwsbb.Verify(key.key, alg, plaintext, []byte(signature)) + err := jwsbb.Verify(key.key, alg, plaintext, signature) if err == nil { verified = true break @@ -704,7 +705,7 @@ func (constraints *tokenConstraints) verify(kid, alg, header, payload, signature return nil } if constraints.secret != "" { - err := jwsbb.Verify([]byte(constraints.secret), alg, plaintext, []byte(signature)) + err := jwsbb.Verify([]byte(constraints.secret), alg, plaintext, signature) if err != nil { return errSignatureNotVerified } @@ -1131,8 +1132,8 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func 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, v) == -1 { + compareTime := ast.Number(strconv.FormatFloat(constraints.time/1000000000, 'g', -1, 64)) + if compareTime.Compare(v) == -1 { return iter(unverified) } default: @@ -1170,17 +1171,17 @@ func decodeJWT(a ast.Value) (*JSONWebToken, error) { return &JSONWebToken{header: parts[0], payload: parts[1], signature: parts[2]}, nil } -func (token *JSONWebToken) decodeSignature() (string, error) { +func (token *JSONWebToken) decodeSignature() ([]byte, error) { decodedSignature, err := getResult(builtinBase64UrlDecode, ast.StringTerm(token.signature)) if err != nil { - return "", err + return nil, err } - signatureAst, err := builtins.StringOperand(decodedSignature.Value, 1) + signatureBs, err := builtins.StringOperandByteSlice(decodedSignature.Value, 1) if err != nil { - return "", err + return nil, err } - return string(signatureAst), err + return signatureBs, nil } // Extract, validate and return the JWT header as an ast.Object. @@ -1289,7 +1290,11 @@ func createTokenCacheKey(serializedJwt ast.Value, publicKey ast.Value) ast.Value func init() { // By default, the JWT cache is disabled. - cache.RegisterDefaultInterQueryBuiltinValueCacheConfig(tokenCacheName, nil) + disabled := true + var tokenCache = cache.NamedValueCacheConfig{ + Disabled: &disabled, + } + cache.RegisterDefaultInterQueryBuiltinValueCacheConfig(tokenCacheName, &tokenCache) RegisterBuiltinFunc(ast.JWTDecode.Name, builtinJWTDecode) RegisterBuiltinFunc(ast.JWTVerifyRS256.Name, builtinJWTVerifyRS256) diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go index c9df12b4c547..49748dcace0e 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go @@ -170,6 +170,7 @@ func (evt *Event) equalNodes(other *Event) bool { } // Tracer defines the interface for tracing in the top-down evaluation engine. +// // Deprecated: Use QueryTracer instead. type Tracer interface { Enabled() bool @@ -230,6 +231,7 @@ func (b *BufferTracer) Enabled() bool { } // Trace adds the event to the buffer. +// // Deprecated: Use TraceEvent instead. func (b *BufferTracer) Trace(evt *Event) { *b = append(*b, evt) @@ -806,7 +808,7 @@ func printPrettyVars(w *bytes.Buffer, exprVars map[string]varInfo) { w.WriteString("\n\nWhere:\n") for _, info := range byName { - w.WriteString(fmt.Sprintf("\n%s: %s", info.Title(), iStrs.Truncate(info.Value(), maxPrettyExprVarWidth))) + fmt.Fprintf(w, "\n%s: %s", info.Title(), iStrs.Truncate(info.Value(), maxPrettyExprVarWidth)) } return @@ -878,7 +880,7 @@ func printArrows(w *bytes.Buffer, l []varInfo, printValueAt int) { valueStr := iStrs.Truncate(info.Value(), maxPrettyExprVarWidth) if (i > 0 && col == l[i-1].col) || (i < len(l)-1 && col == l[i+1].col) { // There is another var on this column, so we need to include the name to differentiate them. - w.WriteString(fmt.Sprintf("%s: %s", info.Title(), valueStr)) + fmt.Fprintf(w, "%s: %s", info.Title(), valueStr) } else { w.WriteString(valueStr) } diff --git a/vendor/github.com/open-policy-agent/opa/v1/topdown/walk.go b/vendor/github.com/open-policy-agent/opa/v1/topdown/walk.go index 1c8961e71f28..9f39f1256717 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/topdown/walk.go +++ b/vendor/github.com/open-policy-agent/opa/v1/topdown/walk.go @@ -25,21 +25,22 @@ 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 { - var pathCopy *ast.Array if path == nil { - pathCopy = ast.InternedEmptyArrayValue + if err := iter(ast.ArrayTerm(ast.NewTerm(ast.InternedEmptyArrayValue), input)); err != nil { + return err + } } else { // Shallow copy, as while the array is modified, the elements are not - pathCopy = copyShallow(path) - } - - // TODO(ae): I'd *really* like these terms to be retrieved from a sync.Pool, and - // returned after iter is called. However, all my atttempts to do this have failed - // as there seems to be something holding on to these references after the call, - // leading to modifications that entirely alter the results. Perhaps this is not - // possible to do, but if it is,it would be a huge performance win. - if err := iter(ast.ArrayTerm(ast.NewTerm(pathCopy), input)); err != nil { - return err + pathCopy := copyShallow(path) + + // TODO(ae): I'd *really* like these terms to be retrieved from a sync.Pool, and + // returned after iter is called. However, all my atttempts to do this have failed + // as there seems to be something holding on to these references after the call, + // leading to modifications that entirely alter the results. Perhaps this is not + // possible to do, but if it is,it would be a huge performance win. + if err := iter(ast.ArrayTerm(ast.NewTerm(pathCopy), input)); err != nil { + return err + } } } diff --git a/vendor/github.com/open-policy-agent/opa/v1/types/types.go b/vendor/github.com/open-policy-agent/opa/v1/types/types.go index 366903f0cb73..fc1db120a0e8 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/types/types.go +++ b/vendor/github.com/open-policy-agent/opa/v1/types/types.go @@ -219,7 +219,7 @@ func (t *Array) toMap() map[string]any { func (t *Array) String() string { prefix := "array" - buf := []string{} + buf := make([]string, 0, len(t.static)) for _, tpe := range t.static { buf = append(buf, Sprint(tpe)) } @@ -716,6 +716,7 @@ func (t *Function) NamedFuncArgs() FuncArgs { } // Args returns the function's arguments as a slice, ignoring variadic arguments. +// // Deprecated: Use FuncArgs instead. func (t *Function) Args() []Type { cpy := make([]Type, len(t.args)) diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/graph.go b/vendor/github.com/open-policy-agent/opa/v1/util/graph.go index f0e824245494..acb62590b6dd 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/util/graph.go +++ b/vendor/github.com/open-policy-agent/opa/v1/util/graph.go @@ -77,13 +77,10 @@ func dfsRecursive(t Traversal, eq Equals, u, z T, path []T) []T { } for _, v := range t.Edges(u) { if eq(v, z) { - path = append(path, z) - path = append(path, u) - return path + return append(path, z, u) } if p := dfsRecursive(t, eq, v, z, path); len(p) > 0 { - path = append(p, u) - return path + return append(p, u) } } return path 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 index c7bd57ea046c..3c852638e287 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/util/performance.go +++ b/vendor/github.com/open-policy-agent/opa/v1/util/performance.go @@ -1,13 +1,41 @@ package util import ( - "math" "slices" + "strconv" "strings" "sync" "unsafe" ) +// SyncPool is a generic sync.Pool for type T, providing some convenience +// over sync.Pool directly: [SyncPool.Put] ensures that nil values are not +// put into the pool, and [SyncPool.Get] returns a pointer to T without having +// to do a type assertion at the call site. +type SyncPool[T any] struct { + pool sync.Pool +} + +func NewSyncPool[T any]() *SyncPool[T] { + return &SyncPool[T]{ + pool: sync.Pool{ + New: func() any { + return new(T) + }, + }, + } +} + +func (p *SyncPool[T]) Get() *T { + return p.pool.Get().(*T) +} + +func (p *SyncPool[T]) Put(x *T) { + if x != nil { + p.pool.Put(x) + } +} + // NewPtrSlice returns a slice of pointers to T with length n, // with only 2 allocations performed no matter the size of n. // See: @@ -44,6 +72,12 @@ func StringToByteSlice[T ~string](s T) []byte { // NumDigitsInt returns the number of digits in n. // This is useful for pre-allocating buffers for string conversion. func NumDigitsInt(n int) int { + return NumDigitsInt64(int64(n)) +} + +// NumDigitsInt64 returns the number of digits in n. +// This is useful for pre-allocating buffers for string conversion. +func NumDigitsInt64(n int64) int { if n == 0 { return 1 } @@ -52,7 +86,12 @@ func NumDigitsInt(n int) int { n = -n } - return int(math.Log10(float64(n))) + 1 + count := 0 + for n > 0 { + n /= 10 + count++ + } + return count } // NumDigitsUint returns the number of digits in n. @@ -62,20 +101,19 @@ func NumDigitsUint(n uint64) int { return 1 } - return int(math.Log10(float64(n))) + 1 -} - -// KeysCount returns the number of keys in m that satisfy predicate p. -func KeysCount[K comparable, V any](m map[K]V, p func(K) bool) int { count := 0 - for k := range m { - if p(k) { - count++ - } + for n > 0 { + n /= 10 + count++ } return count } +// AppendInt is a less messy version of strconv.AppendInt for base 10 ints. +func AppendInt(buf []byte, n int) []byte { + return strconv.AppendInt(buf, int64(n), 10) +} + // SplitMap calls fn for each delim-separated part of text and returns a slice of the results. // Cheaper than calling fn on strings.Split(text, delim), as it avoids allocating an intermediate slice of strings. func SplitMap[T any](text string, delim string, fn func(string) T) []T { @@ -123,11 +161,18 @@ func (sp *SlicePool[T]) Get(length int) *[]T { clear(d) *s = d - return s } // Put returns a pointer to a slice of type T to the pool. func (sp *SlicePool[T]) Put(s *[]T) { - sp.pool.Put(s) + if s != nil { + sp.pool.Put(s) + } +} + +// SortedFunc is simply a shorthand for [slices.SortFunc] which also returns the sorted slice. +func SortedFunc[T any, S ~[]T](s S, cmp func(a, b T) int) S { + slices.SortFunc(s, cmp) + return s } diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/read_gzip_body.go b/vendor/github.com/open-policy-agent/opa/v1/util/read_gzip_body.go index 92c0df8b0851..97dacd0c9690 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/util/read_gzip_body.go +++ b/vendor/github.com/open-policy-agent/opa/v1/util/read_gzip_body.go @@ -3,29 +3,21 @@ package util import ( "bytes" "compress/gzip" - "encoding/binary" "errors" "io" "net/http" "strings" - "sync" "github.com/open-policy-agent/opa/v1/util/decoding" ) -var gzipReaderPool = sync.Pool{ - New: func() any { - reader := new(gzip.Reader) - return reader - }, -} +var gzipReaderPool = NewSyncPool[gzip.Reader]() // Note(philipc): Originally taken from server/server.go -// The DecodingLimitHandler handles validating that the gzip payload is within the -// allowed max size limit. Thus, in the event of a forged payload size trailer, -// the worst that can happen is that we waste memory up to the allowed max gzip -// payload size, but not an unbounded amount of memory, as was potentially -// possible before. +// The DecodingLimitHandler handles setting the max size limits in the context. +// This function enforces those limits. For gzip payloads, we use a LimitReader +// to ensure we don't decompress more than the allowed maximum, preventing +// memory exhaustion from forged gzip trailers. func ReadMaybeCompressedBody(r *http.Request) ([]byte, error) { length := r.ContentLength if maxLenConf, ok := decoding.GetServerDecodingMaxLen(r.Context()); ok { @@ -40,16 +32,7 @@ func ReadMaybeCompressedBody(r *http.Request) ([]byte, error) { if strings.Contains(r.Header.Get("Content-Encoding"), "gzip") { gzipMaxLength, _ := decoding.GetServerDecodingGzipMaxLen(r.Context()) - // Note(philipc): The last 4 bytes of a well-formed gzip blob will - // always be a little-endian uint32, representing the decompressed - // content size, modulo 2^32. We validate that the size is safe, - // earlier in DecodingLimitHandler. - sizeDecompressed := int64(binary.LittleEndian.Uint32(content[len(content)-4:])) - if sizeDecompressed > gzipMaxLength { - return nil, errors.New("gzip payload too large") - } - - gzReader := gzipReaderPool.Get().(*gzip.Reader) + gzReader := gzipReaderPool.Get() defer func() { gzReader.Close() gzipReaderPool.Put(gzReader) @@ -59,11 +42,16 @@ func ReadMaybeCompressedBody(r *http.Request) ([]byte, error) { return nil, err } - decompressed := bytes.NewBuffer(make([]byte, 0, sizeDecompressed)) - if _, err = io.CopyN(decompressed, gzReader, sizeDecompressed); err != nil { + decompressed := bytes.NewBuffer(make([]byte, 0, len(content))) + limitReader := io.LimitReader(gzReader, gzipMaxLength+1) + if _, err := decompressed.ReadFrom(limitReader); err != nil { return nil, err } + if int64(decompressed.Len()) > gzipMaxLength { + return nil, errors.New("gzip payload too large") + } + return decompressed.Bytes(), nil } diff --git a/vendor/github.com/open-policy-agent/opa/v1/util/strings.go b/vendor/github.com/open-policy-agent/opa/v1/util/strings.go new file mode 100644 index 000000000000..8ea0aedc355e --- /dev/null +++ b/vendor/github.com/open-policy-agent/opa/v1/util/strings.go @@ -0,0 +1,13 @@ +package util + +import "strings" + +// WithPrefix ensures that the string s starts with the given prefix. +// If s already starts with prefix, it is returned unchanged. +func WithPrefix(s, prefix string) string { + if strings.HasPrefix(s, prefix) { + return s + } + + return prefix + s +} diff --git a/vendor/github.com/open-policy-agent/opa/v1/version/version.go b/vendor/github.com/open-policy-agent/opa/v1/version/version.go index 2aef6b113f48..ea287687d97b 100644 --- a/vendor/github.com/open-policy-agent/opa/v1/version/version.go +++ b/vendor/github.com/open-policy-agent/opa/v1/version/version.go @@ -10,7 +10,7 @@ import ( "runtime/debug" ) -var Version = "1.10.1" +var Version = "1.14.1" // GoVersion is the version of Go this was built with var GoVersion = runtime.Version() diff --git a/vendor/github.com/prometheus/client_golang/LICENSE b/vendor/github.com/prometheus/client_golang/LICENSE deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/vendor/github.com/prometheus/client_golang/LICENSE +++ /dev/null @@ -1,201 +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. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/prometheus/client_golang/NOTICE b/vendor/github.com/prometheus/client_golang/NOTICE deleted file mode 100644 index b9cc55abbb0a..000000000000 --- a/vendor/github.com/prometheus/client_golang/NOTICE +++ /dev/null @@ -1,18 +0,0 @@ -Prometheus instrumentation library for Go applications -Copyright 2012-2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). - - -The following components are included in this product: - -perks - a fork of https://github.com/bmizerany/perks -https://github.com/beorn7/perks -Copyright 2013-2015 Blake Mizerany, Björn Rabenstein -See https://github.com/beorn7/perks/blob/master/README.md for license details. - -Go support for Protocol Buffers - Google's data interchange format -http://github.com/golang/protobuf/ -Copyright 2010 The Go Authors -See source code for license details. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/.gitignore b/vendor/github.com/prometheus/client_golang/prometheus/.gitignore deleted file mode 100644 index 3460f0346d95..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/.gitignore +++ /dev/null @@ -1 +0,0 @@ -command-line-arguments.test diff --git a/vendor/github.com/prometheus/client_golang/prometheus/README.md b/vendor/github.com/prometheus/client_golang/prometheus/README.md deleted file mode 100644 index c67ff1b7fa3c..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/README.md +++ /dev/null @@ -1 +0,0 @@ -See [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/client_golang/prometheus.svg)](https://pkg.go.dev/github.com/prometheus/client_golang/prometheus). diff --git a/vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go deleted file mode 100644 index 450189f35ec7..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import "runtime/debug" - -// NewBuildInfoCollector is the obsolete version of collectors.NewBuildInfoCollector. -// See there for documentation. -// -// Deprecated: Use collectors.NewBuildInfoCollector instead. -func NewBuildInfoCollector() Collector { - path, version, sum := "unknown", "unknown", "unknown" - if bi, ok := debug.ReadBuildInfo(); ok { - path = bi.Main.Path - version = bi.Main.Version - sum = bi.Main.Sum - } - c := &selfCollector{MustNewConstMetric( - NewDesc( - "go_build_info", - "Build information about the main Go module.", - nil, Labels{"path": path, "version": version, "checksum": sum}, - ), - GaugeValue, 1)} - c.init(c.self) - return c -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collector.go deleted file mode 100644 index cf05079fb822..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/collector.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -// Collector is the interface implemented by anything that can be used by -// Prometheus to collect metrics. A Collector has to be registered for -// collection. See Registerer.Register. -// -// The stock metrics provided by this package (Gauge, Counter, Summary, -// Histogram, Untyped) are also Collectors (which only ever collect one metric, -// namely itself). An implementer of Collector may, however, collect multiple -// metrics in a coordinated fashion and/or create metrics on the fly. Examples -// for collectors already implemented in this library are the metric vectors -// (i.e. collection of multiple instances of the same Metric but with different -// label values) like GaugeVec or SummaryVec, and the ExpvarCollector. -type Collector interface { - // Describe sends the super-set of all possible descriptors of metrics - // collected by this Collector to the provided channel and returns once - // the last descriptor has been sent. The sent descriptors fulfill the - // consistency and uniqueness requirements described in the Desc - // documentation. - // - // It is valid if one and the same Collector sends duplicate - // descriptors. Those duplicates are simply ignored. However, two - // different Collectors must not send duplicate descriptors. - // - // Sending no descriptor at all marks the Collector as “unchecked”, - // i.e. no checks will be performed at registration time, and the - // Collector may yield any Metric it sees fit in its Collect method. - // - // This method idempotently sends the same descriptors throughout the - // lifetime of the Collector. It may be called concurrently and - // therefore must be implemented in a concurrency safe way. - // - // If a Collector encounters an error while executing this method, it - // must send an invalid descriptor (created with NewInvalidDesc) to - // signal the error to the registry. - Describe(chan<- *Desc) - // Collect is called by the Prometheus registry when collecting - // metrics. The implementation sends each collected metric via the - // provided channel and returns once the last metric has been sent. The - // descriptor of each sent metric is one of those returned by Describe - // (unless the Collector is unchecked, see above). Returned metrics that - // share the same descriptor must differ in their variable label - // values. - // - // This method may be called concurrently and must therefore be - // implemented in a concurrency safe way. Blocking occurs at the expense - // of total performance of rendering all registered metrics. Ideally, - // Collector implementations support concurrent readers. - Collect(chan<- Metric) -} - -// DescribeByCollect is a helper to implement the Describe method of a custom -// Collector. It collects the metrics from the provided Collector and sends -// their descriptors to the provided channel. -// -// If a Collector collects the same metrics throughout its lifetime, its -// Describe method can simply be implemented as: -// -// func (c customCollector) Describe(ch chan<- *Desc) { -// DescribeByCollect(c, ch) -// } -// -// However, this will not work if the metrics collected change dynamically over -// the lifetime of the Collector in a way that their combined set of descriptors -// changes as well. The shortcut implementation will then violate the contract -// of the Describe method. If a Collector sometimes collects no metrics at all -// (for example vectors like CounterVec, GaugeVec, etc., which only collect -// metrics after a metric with a fully specified label set has been accessed), -// it might even get registered as an unchecked Collector (cf. the Register -// method of the Registerer interface). Hence, only use this shortcut -// implementation of Describe if you are certain to fulfill the contract. -// -// The Collector example demonstrates a use of DescribeByCollect. -func DescribeByCollect(c Collector, descs chan<- *Desc) { - metrics := make(chan Metric) - go func() { - c.Collect(metrics) - close(metrics) - }() - for m := range metrics { - descs <- m.Desc() - } -} - -// selfCollector implements Collector for a single Metric so that the Metric -// collects itself. Add it as an anonymous field to a struct that implements -// Metric, and call init with the Metric itself as an argument. -type selfCollector struct { - self Metric -} - -// init provides the selfCollector with a reference to the metric it is supposed -// to collect. It is usually called within the factory function to create a -// metric. See example. -func (c *selfCollector) init(self Metric) { - c.self = self -} - -// Describe implements Collector. -func (c *selfCollector) Describe(ch chan<- *Desc) { - ch <- c.self.Desc() -} - -// Collect implements Collector. -func (c *selfCollector) Collect(ch chan<- Metric) { - ch <- c.self -} - -// collectorMetric is a metric that is also a collector. -// Because of selfCollector, most (if not all) Metrics in -// this package are also collectors. -type collectorMetric interface { - Metric - Collector -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go b/vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go deleted file mode 100644 index 9a71a15db1d6..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2025 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -// CollectorFunc is a convenient way to implement a Prometheus Collector -// without interface boilerplate. -// This implementation is based on DescribeByCollect method. -// familiarize yourself to it before using. -type CollectorFunc func(chan<- Metric) - -// Collect calls the defined CollectorFunc function with the provided Metrics channel -func (f CollectorFunc) Collect(ch chan<- Metric) { - f(ch) -} - -// Describe sends the descriptor information using DescribeByCollect -func (f CollectorFunc) Describe(ch chan<- *Desc) { - DescribeByCollect(f, ch) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go deleted file mode 100644 index 4ce84e7a80e5..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "errors" - "math" - "sync/atomic" - "time" - - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/types/known/timestamppb" -) - -// Counter is a Metric that represents a single numerical value that only ever -// goes up. That implies that it cannot be used to count items whose number can -// also go down, e.g. the number of currently running goroutines. Those -// "counters" are represented by Gauges. -// -// A Counter is typically used to count requests served, tasks completed, errors -// occurred, etc. -// -// To create Counter instances, use NewCounter. -type Counter interface { - Metric - Collector - - // Inc increments the counter by 1. Use Add to increment it by arbitrary - // non-negative values. - Inc() - // Add adds the given value to the counter. It panics if the value is < - // 0. - Add(float64) -} - -// ExemplarAdder is implemented by Counters that offer the option of adding a -// value to the Counter together with an exemplar. Its AddWithExemplar method -// works like the Add method of the Counter interface but also replaces the -// currently saved exemplar (if any) with a new one, created from the provided -// value, the current time as timestamp, and the provided labels. Empty Labels -// will lead to a valid (label-less) exemplar. But if Labels is nil, the current -// exemplar is left in place. AddWithExemplar panics if the value is < 0, if any -// of the provided labels are invalid, or if the provided labels contain more -// than 128 runes in total. -type ExemplarAdder interface { - AddWithExemplar(value float64, exemplar Labels) -} - -// CounterOpts is an alias for Opts. See there for doc comments. -type CounterOpts Opts - -// CounterVecOpts bundles the options to create a CounterVec metric. -// It is mandatory to set CounterOpts, see there for mandatory fields. VariableLabels -// is optional and can safely be left to its default value. -type CounterVecOpts struct { - CounterOpts - - // VariableLabels are used to partition the metric vector by the given set - // of labels. Each label value will be constrained with the optional Constraint - // function, if provided. - VariableLabels ConstrainableLabels -} - -// NewCounter creates a new Counter based on the provided CounterOpts. -// -// The returned implementation also implements ExemplarAdder. It is safe to -// perform the corresponding type assertion. -// -// The returned implementation tracks the counter value in two separate -// variables, a float64 and a uint64. The latter is used to track calls of the -// Inc method and calls of the Add method with a value that can be represented -// as a uint64. This allows atomic increments of the counter with optimal -// performance. (It is common to have an Inc call in very hot execution paths.) -// Both internal tracking values are added up in the Write method. This has to -// be taken into account when it comes to precision and overflow behavior. -func NewCounter(opts CounterOpts) Counter { - desc := NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - nil, - opts.ConstLabels, - ) - if opts.now == nil { - opts.now = time.Now - } - result := &counter{desc: desc, labelPairs: desc.constLabelPairs, now: opts.now} - result.init(result) // Init self-collection. - result.createdTs = timestamppb.New(opts.now()) - return result -} - -type counter struct { - // valBits contains the bits of the represented float64 value, while - // valInt stores values that are exact integers. Both have to go first - // in the struct to guarantee alignment for atomic operations. - // http://golang.org/pkg/sync/atomic/#pkg-note-BUG - valBits uint64 - valInt uint64 - - selfCollector - desc *Desc - - createdTs *timestamppb.Timestamp - labelPairs []*dto.LabelPair - exemplar atomic.Value // Containing nil or a *dto.Exemplar. - - // now is for testing purposes, by default it's time.Now. - now func() time.Time -} - -func (c *counter) Desc() *Desc { - return c.desc -} - -func (c *counter) Add(v float64) { - if v < 0 { - panic(errors.New("counter cannot decrease in value")) - } - - ival := uint64(v) - if float64(ival) == v { - atomic.AddUint64(&c.valInt, ival) - return - } - - for { - oldBits := atomic.LoadUint64(&c.valBits) - newBits := math.Float64bits(math.Float64frombits(oldBits) + v) - if atomic.CompareAndSwapUint64(&c.valBits, oldBits, newBits) { - return - } - } -} - -func (c *counter) AddWithExemplar(v float64, e Labels) { - c.Add(v) - c.updateExemplar(v, e) -} - -func (c *counter) Inc() { - atomic.AddUint64(&c.valInt, 1) -} - -func (c *counter) get() float64 { - fval := math.Float64frombits(atomic.LoadUint64(&c.valBits)) - ival := atomic.LoadUint64(&c.valInt) - return fval + float64(ival) -} - -func (c *counter) Write(out *dto.Metric) error { - // Read the Exemplar first and the value second. This is to avoid a race condition - // where users see an exemplar for a not-yet-existing observation. - var exemplar *dto.Exemplar - if e := c.exemplar.Load(); e != nil { - exemplar = e.(*dto.Exemplar) - } - val := c.get() - return populateMetric(CounterValue, val, c.labelPairs, exemplar, out, c.createdTs) -} - -func (c *counter) updateExemplar(v float64, l Labels) { - if l == nil { - return - } - e, err := newExemplar(v, c.now(), l) - if err != nil { - panic(err) - } - c.exemplar.Store(e) -} - -// CounterVec is a Collector that bundles a set of Counters that all share the -// same Desc, but have different values for their variable labels. This is used -// if you want to count the same thing partitioned by various dimensions -// (e.g. number of HTTP requests, partitioned by response code and -// method). Create instances with NewCounterVec. -type CounterVec struct { - *MetricVec -} - -// NewCounterVec creates a new CounterVec based on the provided CounterOpts and -// partitioned by the given label names. -func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { - return V2.NewCounterVec(CounterVecOpts{ - CounterOpts: opts, - VariableLabels: UnconstrainedLabels(labelNames), - }) -} - -// NewCounterVec creates a new CounterVec based on the provided CounterVecOpts. -func (v2) NewCounterVec(opts CounterVecOpts) *CounterVec { - desc := V2.NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - opts.VariableLabels, - opts.ConstLabels, - ) - if opts.now == nil { - opts.now = time.Now - } - return &CounterVec{ - MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { - if len(lvs) != len(desc.variableLabels.names) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs)) - } - result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: opts.now} - result.init(result) // Init self-collection. - result.createdTs = timestamppb.New(opts.now()) - return result - }), - } -} - -// GetMetricWithLabelValues returns the Counter for the given slice of label -// values (same order as the variable labels in Desc). If that combination of -// label values is accessed for the first time, a new Counter is created. -// -// It is possible to call this method without using the returned Counter to only -// create the new Counter but leave it at its starting value 0. See also the -// SummaryVec example. -// -// Keeping the Counter for later use is possible (and should be considered if -// performance is critical), but keep in mind that Reset, DeleteLabelValues and -// Delete can be used to delete the Counter from the CounterVec. In that case, -// the Counter will still exist, but it will not be exported anymore, even if a -// Counter with the same label values is created later. -// -// An error is returned if the number of label values is not the same as the -// number of variable labels in Desc (minus any curried labels). -// -// Note that for more than one label value, this method is prone to mistakes -// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as -// an alternative to avoid that type of mistake. For higher label numbers, the -// latter has a much more readable (albeit more verbose) syntax, but it comes -// with a performance overhead (for creating and processing the Labels map). -// See also the GaugeVec example. -func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) { - metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) - if metric != nil { - return metric.(Counter), err - } - return nil, err -} - -// GetMetricWith returns the Counter for the given Labels map (the label names -// must match those of the variable labels in Desc). If that label map is -// accessed for the first time, a new Counter is created. Implications of -// creating a Counter without using it and keeping the Counter for later use are -// the same as for GetMetricWithLabelValues. -// -// An error is returned if the number and names of the Labels are inconsistent -// with those of the variable labels in Desc (minus any curried labels). -// -// This method is used for the same purpose as -// GetMetricWithLabelValues(...string). See there for pros and cons of the two -// methods. -func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) { - metric, err := v.MetricVec.GetMetricWith(labels) - if metric != nil { - return metric.(Counter), err - } - return nil, err -} - -// WithLabelValues works as GetMetricWithLabelValues, but panics where -// GetMetricWithLabelValues would have returned an error. Not returning an -// error allows shortcuts like -// -// myVec.WithLabelValues("404", "GET").Add(42) -func (v *CounterVec) WithLabelValues(lvs ...string) Counter { - c, err := v.GetMetricWithLabelValues(lvs...) - if err != nil { - panic(err) - } - return c -} - -// With works as GetMetricWith, but panics where GetMetricWithLabels would have -// returned an error. Not returning an error allows shortcuts like -// -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) -func (v *CounterVec) With(labels Labels) Counter { - c, err := v.GetMetricWith(labels) - if err != nil { - panic(err) - } - return c -} - -// CurryWith returns a vector curried with the provided labels, i.e. the -// returned vector has those labels pre-set for all labeled operations performed -// on it. The cardinality of the curried vector is reduced accordingly. The -// order of the remaining labels stays the same (just with the curried labels -// taken out of the sequence – which is relevant for the -// (GetMetric)WithLabelValues methods). It is possible to curry a curried -// vector, but only with labels not yet used for currying before. -// -// The metrics contained in the CounterVec are shared between the curried and -// uncurried vectors. They are just accessed differently. Curried and uncurried -// vectors behave identically in terms of collection. Only one must be -// registered with a given registry (usually the uncurried version). The Reset -// method deletes all metrics, even if called on a curried vector. -func (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error) { - vec, err := v.MetricVec.CurryWith(labels) - if vec != nil { - return &CounterVec{vec}, err - } - return nil, err -} - -// MustCurryWith works as CurryWith but panics where CurryWith would have -// returned an error. -func (v *CounterVec) MustCurryWith(labels Labels) *CounterVec { - vec, err := v.CurryWith(labels) - if err != nil { - panic(err) - } - return vec -} - -// CounterFunc is a Counter whose value is determined at collect time by calling a -// provided function. -// -// To create CounterFunc instances, use NewCounterFunc. -type CounterFunc interface { - Metric - Collector -} - -// NewCounterFunc creates a new CounterFunc based on the provided -// CounterOpts. The value reported is determined by calling the given function -// from within the Write method. Take into account that metric collection may -// happen concurrently. If that results in concurrent calls to Write, like in -// the case where a CounterFunc is directly registered with Prometheus, the -// provided function must be concurrency-safe. The function should also honor -// the contract for a Counter (values only go up, not down), but compliance will -// not be checked. -// -// Check out the ExampleGaugeFunc examples for the similar GaugeFunc. -func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc { - return newValueFunc(NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - nil, - opts.ConstLabels, - ), CounterValue, function) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go deleted file mode 100644 index 2331b8b4f3b4..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2016 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "fmt" - "sort" - "strings" - - "github.com/cespare/xxhash/v2" - dto "github.com/prometheus/client_model/go" - "github.com/prometheus/common/model" - "google.golang.org/protobuf/proto" - - "github.com/prometheus/client_golang/prometheus/internal" -) - -// Desc is the descriptor used by every Prometheus Metric. It is essentially -// the immutable meta-data of a Metric. The normal Metric implementations -// included in this package manage their Desc under the hood. Users only have to -// deal with Desc if they use advanced features like the ExpvarCollector or -// custom Collectors and Metrics. -// -// Descriptors registered with the same registry have to fulfill certain -// consistency and uniqueness criteria if they share the same fully-qualified -// name: They must have the same help string and the same label names (aka label -// dimensions) in each, constLabels and variableLabels, but they must differ in -// the values of the constLabels. -// -// Descriptors that share the same fully-qualified names and the same label -// values of their constLabels are considered equal. -// -// Use NewDesc to create new Desc instances. -type Desc struct { - // fqName has been built from Namespace, Subsystem, and Name. - fqName string - // help provides some helpful information about this metric. - help string - // constLabelPairs contains precalculated DTO label pairs based on - // the constant labels. - constLabelPairs []*dto.LabelPair - // variableLabels contains names of labels and normalization function for - // which the metric maintains variable values. - variableLabels *compiledLabels - // id is a hash of the values of the ConstLabels and fqName. This - // must be unique among all registered descriptors and can therefore be - // used as an identifier of the descriptor. - id uint64 - // dimHash is a hash of the label names (preset and variable) and the - // Help string. Each Desc with the same fqName must have the same - // dimHash. - dimHash uint64 - // err is an error that occurred during construction. It is reported on - // registration time. - err error -} - -// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc -// and will be reported on registration time. variableLabels and constLabels can -// be nil if no such labels should be set. fqName must not be empty. -// -// variableLabels only contain the label names. Their label values are variable -// and therefore not part of the Desc. (They are managed within the Metric.) -// -// For constLabels, the label values are constant. Therefore, they are fully -// specified in the Desc. See the Collector example for a usage pattern. -func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc { - return V2.NewDesc(fqName, help, UnconstrainedLabels(variableLabels), constLabels) -} - -// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc -// and will be reported on registration time. variableLabels and constLabels can -// be nil if no such labels should be set. fqName must not be empty. -// -// variableLabels only contain the label names and normalization functions. Their -// label values are variable and therefore not part of the Desc. (They are managed -// within the Metric.) -// -// For constLabels, the label values are constant. Therefore, they are fully -// specified in the Desc. See the Collector example for a usage pattern. -func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels) *Desc { - d := &Desc{ - fqName: fqName, - help: help, - variableLabels: variableLabels.compile(), - } - //nolint:staticcheck // TODO: Don't use deprecated model.NameValidationScheme. - if !model.NameValidationScheme.IsValidMetricName(fqName) { - d.err = fmt.Errorf("%q is not a valid metric name", fqName) - return d - } - // labelValues contains the label values of const labels (in order of - // their sorted label names) plus the fqName (at position 0). - labelValues := make([]string, 1, len(constLabels)+1) - labelValues[0] = fqName - labelNames := make([]string, 0, len(constLabels)+len(d.variableLabels.names)) - labelNameSet := map[string]struct{}{} - // First add only the const label names and sort them... - for labelName := range constLabels { - if !checkLabelName(labelName) { - d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName) - return d - } - labelNames = append(labelNames, labelName) - labelNameSet[labelName] = struct{}{} - } - sort.Strings(labelNames) - // ... so that we can now add const label values in the order of their names. - for _, labelName := range labelNames { - labelValues = append(labelValues, constLabels[labelName]) - } - // Validate the const label values. They can't have a wrong cardinality, so - // use in len(labelValues) as expectedNumberOfValues. - if err := validateLabelValues(labelValues, len(labelValues)); err != nil { - d.err = err - return d - } - // Now add the variable label names, but prefix them with something that - // cannot be in a regular label name. That prevents matching the label - // dimension with a different mix between preset and variable labels. - for _, label := range d.variableLabels.names { - if !checkLabelName(label) { - d.err = fmt.Errorf("%q is not a valid label name for metric %q", label, fqName) - return d - } - labelNames = append(labelNames, "$"+label) - labelNameSet[label] = struct{}{} - } - if len(labelNames) != len(labelNameSet) { - d.err = fmt.Errorf("duplicate label names in constant and variable labels for metric %q", fqName) - return d - } - - xxh := xxhash.New() - for _, val := range labelValues { - xxh.WriteString(val) - xxh.Write(separatorByteSlice) - } - d.id = xxh.Sum64() - // Sort labelNames so that order doesn't matter for the hash. - sort.Strings(labelNames) - // Now hash together (in this order) the help string and the sorted - // label names. - xxh.Reset() - xxh.WriteString(help) - xxh.Write(separatorByteSlice) - for _, labelName := range labelNames { - xxh.WriteString(labelName) - xxh.Write(separatorByteSlice) - } - d.dimHash = xxh.Sum64() - - d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels)) - for n, v := range constLabels { - d.constLabelPairs = append(d.constLabelPairs, &dto.LabelPair{ - Name: proto.String(n), - Value: proto.String(v), - }) - } - sort.Sort(internal.LabelPairSorter(d.constLabelPairs)) - return d -} - -// NewInvalidDesc returns an invalid descriptor, i.e. a descriptor with the -// provided error set. If a collector returning such a descriptor is registered, -// registration will fail with the provided error. NewInvalidDesc can be used by -// a Collector to signal inability to describe itself. -func NewInvalidDesc(err error) *Desc { - return &Desc{ - err: err, - } -} - -func (d *Desc) String() string { - lpStrings := make([]string, 0, len(d.constLabelPairs)) - for _, lp := range d.constLabelPairs { - lpStrings = append( - lpStrings, - fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()), - ) - } - vlStrings := []string{} - if d.variableLabels != nil { - vlStrings = make([]string, 0, len(d.variableLabels.names)) - for _, vl := range d.variableLabels.names { - if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil { - vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl)) - } else { - vlStrings = append(vlStrings, vl) - } - } - } - return fmt.Sprintf( - "Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: {%s}}", - d.fqName, - d.help, - strings.Join(lpStrings, ","), - strings.Join(vlStrings, ","), - ) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/doc.go b/vendor/github.com/prometheus/client_golang/prometheus/doc.go deleted file mode 100644 index 962608f02c65..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/doc.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package prometheus is the core instrumentation package. It provides metrics -// primitives to instrument code for monitoring. It also offers a registry for -// metrics. Sub-packages allow to expose the registered metrics via HTTP -// (package promhttp) or push them to a Pushgateway (package push). There is -// also a sub-package promauto, which provides metrics constructors with -// automatic registration. -// -// All exported functions and methods are safe to be used concurrently unless -// specified otherwise. -// -// # A Basic Example -// -// As a starting point, a very basic usage example: -// -// package main -// -// import ( -// "log" -// "net/http" -// -// "github.com/prometheus/client_golang/prometheus" -// "github.com/prometheus/client_golang/prometheus/promhttp" -// ) -// -// type metrics struct { -// cpuTemp prometheus.Gauge -// hdFailures *prometheus.CounterVec -// } -// -// func NewMetrics(reg prometheus.Registerer) *metrics { -// m := &metrics{ -// cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{ -// Name: "cpu_temperature_celsius", -// Help: "Current temperature of the CPU.", -// }), -// hdFailures: prometheus.NewCounterVec( -// prometheus.CounterOpts{ -// Name: "hd_errors_total", -// Help: "Number of hard-disk errors.", -// }, -// []string{"device"}, -// ), -// } -// reg.MustRegister(m.cpuTemp) -// reg.MustRegister(m.hdFailures) -// return m -// } -// -// func main() { -// // Create a non-global registry. -// reg := prometheus.NewRegistry() -// -// // Create new metrics and register them using the custom registry. -// m := NewMetrics(reg) -// // Set values for the new created metrics. -// m.cpuTemp.Set(65.3) -// m.hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() -// -// // Expose metrics and custom registry via an HTTP server -// // using the HandleFor function. "/metrics" is the usual endpoint for that. -// http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg})) -// log.Fatal(http.ListenAndServe(":8080", nil)) -// } -// -// This is a complete program that exports two metrics, a Gauge and a Counter, -// the latter with a label attached to turn it into a (one-dimensional) vector. -// It register the metrics using a custom registry and exposes them via an HTTP server -// on the /metrics endpoint. -// -// # Metrics -// -// The number of exported identifiers in this package might appear a bit -// overwhelming. However, in addition to the basic plumbing shown in the example -// above, you only need to understand the different metric types and their -// vector versions for basic usage. Furthermore, if you are not concerned with -// fine-grained control of when and how to register metrics with the registry, -// have a look at the promauto package, which will effectively allow you to -// ignore registration altogether in simple cases. -// -// Above, you have already touched the Counter and the Gauge. There are two more -// advanced metric types: the Summary and Histogram. A more thorough description -// of those four metric types can be found in the Prometheus docs: -// https://prometheus.io/docs/concepts/metric_types/ -// -// In addition to the fundamental metric types Gauge, Counter, Summary, and -// Histogram, a very important part of the Prometheus data model is the -// partitioning of samples along dimensions called labels, which results in -// metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec, -// and HistogramVec. -// -// While only the fundamental metric types implement the Metric interface, both -// the metrics and their vector versions implement the Collector interface. A -// Collector manages the collection of a number of Metrics, but for convenience, -// a Metric can also “collect itself”. Note that Gauge, Counter, Summary, and -// Histogram are interfaces themselves while GaugeVec, CounterVec, SummaryVec, -// and HistogramVec are not. -// -// To create instances of Metrics and their vector versions, you need a suitable -// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts. -// -// # Custom Collectors and constant Metrics -// -// While you could create your own implementations of Metric, most likely you -// will only ever implement the Collector interface on your own. At a first -// glance, a custom Collector seems handy to bundle Metrics for common -// registration (with the prime example of the different metric vectors above, -// which bundle all the metrics of the same name but with different labels). -// -// There is a more involved use case, too: If you already have metrics -// available, created outside of the Prometheus context, you don't need the -// interface of the various Metric types. You essentially want to mirror the -// existing numbers into Prometheus Metrics during collection. An own -// implementation of the Collector interface is perfect for that. You can create -// Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and -// NewConstSummary (and their respective Must… versions). NewConstMetric is used -// for all metric types with just a float64 as their value: Counter, Gauge, and -// a special “type” called Untyped. Use the latter if you are not sure if the -// mirrored metric is a Counter or a Gauge. Creation of the Metric instance -// happens in the Collect method. The Describe method has to return separate -// Desc instances, representative of the “throw-away” metrics to be created -// later. NewDesc comes in handy to create those Desc instances. Alternatively, -// you could return no Desc at all, which will mark the Collector “unchecked”. -// No checks are performed at registration time, but metric consistency will -// still be ensured at scrape time, i.e. any inconsistencies will lead to scrape -// errors. Thus, with unchecked Collectors, the responsibility to not collect -// metrics that lead to inconsistencies in the total scrape result lies with the -// implementer of the Collector. While this is not a desirable state, it is -// sometimes necessary. The typical use case is a situation where the exact -// metrics to be returned by a Collector cannot be predicted at registration -// time, but the implementer has sufficient knowledge of the whole system to -// guarantee metric consistency. -// -// The Collector example illustrates the use case. You can also look at the -// source code of the processCollector (mirroring process metrics), the -// goCollector (mirroring Go metrics), or the expvarCollector (mirroring expvar -// metrics) as examples that are used in this package itself. -// -// If you just need to call a function to get a single float value to collect as -// a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting -// shortcuts. -// -// # Advanced Uses of the Registry -// -// While MustRegister is the by far most common way of registering a Collector, -// sometimes you might want to handle the errors the registration might cause. -// As suggested by the name, MustRegister panics if an error occurs. With the -// Register function, the error is returned and can be handled. -// -// An error is returned if the registered Collector is incompatible or -// inconsistent with already registered metrics. The registry aims for -// consistency of the collected metrics according to the Prometheus data model. -// Inconsistencies are ideally detected at registration time, not at collect -// time. The former will usually be detected at start-up time of a program, -// while the latter will only happen at scrape time, possibly not even on the -// first scrape if the inconsistency only becomes relevant later. That is the -// main reason why a Collector and a Metric have to describe themselves to the -// registry. -// -// So far, everything we did operated on the so-called default registry, as it -// can be found in the global DefaultRegisterer variable. With NewRegistry, you -// can create a custom registry, or you can even implement the Registerer or -// Gatherer interfaces yourself. The methods Register and Unregister work in the -// same way on a custom registry as the global functions Register and Unregister -// on the default registry. -// -// There are a number of uses for custom registries: You can use registries with -// special properties, see NewPedanticRegistry. You can avoid global state, as -// it is imposed by the DefaultRegisterer. You can use multiple registries at -// the same time to expose different metrics in different ways. You can use -// separate registries for testing purposes. -// -// Also note that the DefaultRegisterer comes registered with a Collector for Go -// runtime metrics (via NewGoCollector) and a Collector for process metrics (via -// NewProcessCollector). With a custom registry, you are in control and decide -// yourself about the Collectors to register. -// -// # HTTP Exposition -// -// The Registry implements the Gatherer interface. The caller of the Gather -// method can then expose the gathered metrics in some way. Usually, the metrics -// are served via HTTP on the /metrics endpoint. That's happening in the example -// above. The tools to expose metrics via HTTP are in the promhttp sub-package. -// -// # Pushing to the Pushgateway -// -// Function for pushing to the Pushgateway can be found in the push sub-package. -// -// # Graphite Bridge -// -// Functions and examples to push metrics from a Gatherer to Graphite can be -// found in the graphite sub-package. -// -// # Other Means of Exposition -// -// More ways of exposing metrics can easily be added by following the approaches -// of the existing implementations. -package prometheus diff --git a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go deleted file mode 100644 index de5a85629318..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "encoding/json" - "expvar" -) - -type expvarCollector struct { - exports map[string]*Desc -} - -// NewExpvarCollector is the obsolete version of collectors.NewExpvarCollector. -// See there for documentation. -// -// Deprecated: Use collectors.NewExpvarCollector instead. -func NewExpvarCollector(exports map[string]*Desc) Collector { - return &expvarCollector{ - exports: exports, - } -} - -// Describe implements Collector. -func (e *expvarCollector) Describe(ch chan<- *Desc) { - for _, desc := range e.exports { - ch <- desc - } -} - -// Collect implements Collector. -func (e *expvarCollector) Collect(ch chan<- Metric) { - for name, desc := range e.exports { - var m Metric - expVar := expvar.Get(name) - if expVar == nil { - continue - } - var v interface{} - labels := make([]string, len(desc.variableLabels.names)) - if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil { - ch <- NewInvalidMetric(desc, err) - continue - } - var processValue func(v interface{}, i int) - processValue = func(v interface{}, i int) { - if i >= len(labels) { - copiedLabels := append(make([]string, 0, len(labels)), labels...) - switch v := v.(type) { - case float64: - m = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...) - case bool: - if v { - m = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...) - } else { - m = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...) - } - default: - return - } - ch <- m - return - } - vm, ok := v.(map[string]interface{}) - if !ok { - return - } - for lv, val := range vm { - labels[i] = lv - processValue(val, i+1) - } - } - processValue(v, 0) - } -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/fnv.go b/vendor/github.com/prometheus/client_golang/prometheus/fnv.go deleted file mode 100644 index 3d383a735c38..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/fnv.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -// Inline and byte-free variant of hash/fnv's fnv64a. - -const ( - offset64 = 14695981039346656037 - prime64 = 1099511628211 -) - -// hashNew initializies a new fnv64a hash value. -func hashNew() uint64 { - return offset64 -} - -// hashAdd adds a string to a fnv64a hash value, returning the updated hash. -func hashAdd(h uint64, s string) uint64 { - for i := 0; i < len(s); i++ { - h ^= uint64(s[i]) - h *= prime64 - } - return h -} - -// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. -func hashAddByte(h uint64, b byte) uint64 { - h ^= uint64(b) - h *= prime64 - return h -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go deleted file mode 100644 index dd2eac940675..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "math" - "sync/atomic" - "time" - - dto "github.com/prometheus/client_model/go" -) - -// Gauge is a Metric that represents a single numerical value that can -// arbitrarily go up and down. -// -// A Gauge is typically used for measured values like temperatures or current -// memory usage, but also "counts" that can go up and down, like the number of -// running goroutines. -// -// To create Gauge instances, use NewGauge. -type Gauge interface { - Metric - Collector - - // Set sets the Gauge to an arbitrary value. - Set(float64) - // Inc increments the Gauge by 1. Use Add to increment it by arbitrary - // values. - Inc() - // Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary - // values. - Dec() - // Add adds the given value to the Gauge. (The value can be negative, - // resulting in a decrease of the Gauge.) - Add(float64) - // Sub subtracts the given value from the Gauge. (The value can be - // negative, resulting in an increase of the Gauge.) - Sub(float64) - - // SetToCurrentTime sets the Gauge to the current Unix time in seconds. - SetToCurrentTime() -} - -// GaugeOpts is an alias for Opts. See there for doc comments. -type GaugeOpts Opts - -// GaugeVecOpts bundles the options to create a GaugeVec metric. -// It is mandatory to set GaugeOpts, see there for mandatory fields. VariableLabels -// is optional and can safely be left to its default value. -type GaugeVecOpts struct { - GaugeOpts - - // VariableLabels are used to partition the metric vector by the given set - // of labels. Each label value will be constrained with the optional Constraint - // function, if provided. - VariableLabels ConstrainableLabels -} - -// NewGauge creates a new Gauge based on the provided GaugeOpts. -// -// The returned implementation is optimized for a fast Set method. If you have a -// choice for managing the value of a Gauge via Set vs. Inc/Dec/Add/Sub, pick -// the former. For example, the Inc method of the returned Gauge is slower than -// the Inc method of a Counter returned by NewCounter. This matches the typical -// scenarios for Gauges and Counters, where the former tends to be Set-heavy and -// the latter Inc-heavy. -func NewGauge(opts GaugeOpts) Gauge { - desc := NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - nil, - opts.ConstLabels, - ) - result := &gauge{desc: desc, labelPairs: desc.constLabelPairs} - result.init(result) // Init self-collection. - return result -} - -type gauge struct { - // valBits contains the bits of the represented float64 value. It has - // to go first in the struct to guarantee alignment for atomic - // operations. http://golang.org/pkg/sync/atomic/#pkg-note-BUG - valBits uint64 - - selfCollector - - desc *Desc - labelPairs []*dto.LabelPair -} - -func (g *gauge) Desc() *Desc { - return g.desc -} - -func (g *gauge) Set(val float64) { - atomic.StoreUint64(&g.valBits, math.Float64bits(val)) -} - -func (g *gauge) SetToCurrentTime() { - g.Set(float64(time.Now().UnixNano()) / 1e9) -} - -func (g *gauge) Inc() { - g.Add(1) -} - -func (g *gauge) Dec() { - g.Add(-1) -} - -func (g *gauge) Add(val float64) { - for { - oldBits := atomic.LoadUint64(&g.valBits) - newBits := math.Float64bits(math.Float64frombits(oldBits) + val) - if atomic.CompareAndSwapUint64(&g.valBits, oldBits, newBits) { - return - } - } -} - -func (g *gauge) Sub(val float64) { - g.Add(val * -1) -} - -func (g *gauge) Write(out *dto.Metric) error { - val := math.Float64frombits(atomic.LoadUint64(&g.valBits)) - return populateMetric(GaugeValue, val, g.labelPairs, nil, out, nil) -} - -// GaugeVec is a Collector that bundles a set of Gauges that all share the same -// Desc, but have different values for their variable labels. This is used if -// you want to count the same thing partitioned by various dimensions -// (e.g. number of operations queued, partitioned by user and operation -// type). Create instances with NewGaugeVec. -type GaugeVec struct { - *MetricVec -} - -// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and -// partitioned by the given label names. -func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { - return V2.NewGaugeVec(GaugeVecOpts{ - GaugeOpts: opts, - VariableLabels: UnconstrainedLabels(labelNames), - }) -} - -// NewGaugeVec creates a new GaugeVec based on the provided GaugeVecOpts. -func (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec { - desc := V2.NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - opts.VariableLabels, - opts.ConstLabels, - ) - return &GaugeVec{ - MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { - if len(lvs) != len(desc.variableLabels.names) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs)) - } - result := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)} - result.init(result) // Init self-collection. - return result - }), - } -} - -// GetMetricWithLabelValues returns the Gauge for the given slice of label -// values (same order as the variable labels in Desc). If that combination of -// label values is accessed for the first time, a new Gauge is created. -// -// It is possible to call this method without using the returned Gauge to only -// create the new Gauge but leave it at its starting value 0. See also the -// SummaryVec example. -// -// Keeping the Gauge for later use is possible (and should be considered if -// performance is critical), but keep in mind that Reset, DeleteLabelValues and -// Delete can be used to delete the Gauge from the GaugeVec. In that case, the -// Gauge will still exist, but it will not be exported anymore, even if a -// Gauge with the same label values is created later. See also the CounterVec -// example. -// -// An error is returned if the number of label values is not the same as the -// number of variable labels in Desc (minus any curried labels). -// -// Note that for more than one label value, this method is prone to mistakes -// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as -// an alternative to avoid that type of mistake. For higher label numbers, the -// latter has a much more readable (albeit more verbose) syntax, but it comes -// with a performance overhead (for creating and processing the Labels map). -func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) { - metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) - if metric != nil { - return metric.(Gauge), err - } - return nil, err -} - -// GetMetricWith returns the Gauge for the given Labels map (the label names -// must match those of the variable labels in Desc). If that label map is -// accessed for the first time, a new Gauge is created. Implications of -// creating a Gauge without using it and keeping the Gauge for later use are -// the same as for GetMetricWithLabelValues. -// -// An error is returned if the number and names of the Labels are inconsistent -// with those of the variable labels in Desc (minus any curried labels). -// -// This method is used for the same purpose as -// GetMetricWithLabelValues(...string). See there for pros and cons of the two -// methods. -func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { - metric, err := v.MetricVec.GetMetricWith(labels) - if metric != nil { - return metric.(Gauge), err - } - return nil, err -} - -// WithLabelValues works as GetMetricWithLabelValues, but panics where -// GetMetricWithLabelValues would have returned an error. Not returning an -// error allows shortcuts like -// -// myVec.WithLabelValues("404", "GET").Add(42) -func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { - g, err := v.GetMetricWithLabelValues(lvs...) - if err != nil { - panic(err) - } - return g -} - -// With works as GetMetricWith, but panics where GetMetricWithLabels would have -// returned an error. Not returning an error allows shortcuts like -// -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) -func (v *GaugeVec) With(labels Labels) Gauge { - g, err := v.GetMetricWith(labels) - if err != nil { - panic(err) - } - return g -} - -// CurryWith returns a vector curried with the provided labels, i.e. the -// returned vector has those labels pre-set for all labeled operations performed -// on it. The cardinality of the curried vector is reduced accordingly. The -// order of the remaining labels stays the same (just with the curried labels -// taken out of the sequence – which is relevant for the -// (GetMetric)WithLabelValues methods). It is possible to curry a curried -// vector, but only with labels not yet used for currying before. -// -// The metrics contained in the GaugeVec are shared between the curried and -// uncurried vectors. They are just accessed differently. Curried and uncurried -// vectors behave identically in terms of collection. Only one must be -// registered with a given registry (usually the uncurried version). The Reset -// method deletes all metrics, even if called on a curried vector. -func (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error) { - vec, err := v.MetricVec.CurryWith(labels) - if vec != nil { - return &GaugeVec{vec}, err - } - return nil, err -} - -// MustCurryWith works as CurryWith but panics where CurryWith would have -// returned an error. -func (v *GaugeVec) MustCurryWith(labels Labels) *GaugeVec { - vec, err := v.CurryWith(labels) - if err != nil { - panic(err) - } - return vec -} - -// GaugeFunc is a Gauge whose value is determined at collect time by calling a -// provided function. -// -// To create GaugeFunc instances, use NewGaugeFunc. -type GaugeFunc interface { - Metric - Collector -} - -// NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The -// value reported is determined by calling the given function from within the -// Write method. Take into account that metric collection may happen -// concurrently. Therefore, it must be safe to call the provided function -// concurrently. -// -// NewGaugeFunc is a good way to create an “info” style metric with a constant -// value of 1. Example: -// https://github.com/prometheus/common/blob/8558a5b7db3c84fa38b4766966059a7bd5bfa2ee/version/info.go#L36-L56 -func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc { - return newValueFunc(NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - nil, - opts.ConstLabels, - ), GaugeValue, function) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go deleted file mode 100644 index 614fd61be95a..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !js || wasm -// +build !js wasm - -package prometheus - -import "os" - -func getPIDFn() func() (int, error) { - pid := os.Getpid() - return func() (int, error) { - return pid, nil - } -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go deleted file mode 100644 index eaf8059ee15d..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build js && !wasm -// +build js,!wasm - -package prometheus - -func getPIDFn() func() (int, error) { - return func() (int, error) { - return 1, nil - } -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go deleted file mode 100644 index 520cbd7d418f..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2018 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "runtime" - "runtime/debug" - "time" -) - -// goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats. -// From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so -// while eval closure works on runtime.MemStats, the struct from Go 1.17+ is -// populated using runtime/metrics. Those are the defaults we can't alter. -func goRuntimeMemStats() memStatsMetrics { - return memStatsMetrics{ - { - desc: NewDesc( - memstatNamespace("alloc_bytes"), - "Number of bytes allocated in heap and currently in use. Equals to /memory/classes/heap/objects:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("alloc_bytes_total"), - "Total number of bytes allocated in heap until now, even if released already. Equals to /gc/heap/allocs:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) }, - valType: CounterValue, - }, { - desc: NewDesc( - memstatNamespace("sys_bytes"), - "Number of bytes obtained from system. Equals to /memory/classes/total:byte.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("mallocs_total"), - // TODO(bwplotka): We could add go_memstats_heap_objects, probably useful for discovery. Let's gather more feedback, kind of a waste of bytes for everybody for compatibility reasons to keep both, and we can't really rename/remove useful metric. - "Total number of heap objects allocated, both live and gc-ed. Semantically a counter version for go_memstats_heap_objects gauge. Equals to /gc/heap/allocs:objects + /gc/heap/tiny/allocs:objects.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) }, - valType: CounterValue, - }, { - desc: NewDesc( - memstatNamespace("frees_total"), - "Total number of heap objects frees. Equals to /gc/heap/frees:objects + /gc/heap/tiny/allocs:objects.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) }, - valType: CounterValue, - }, { - desc: NewDesc( - memstatNamespace("heap_alloc_bytes"), - "Number of heap bytes allocated and currently in use, same as go_memstats_alloc_bytes. Equals to /memory/classes/heap/objects:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("heap_sys_bytes"), - "Number of heap bytes obtained from system. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes + /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("heap_idle_bytes"), - "Number of heap bytes waiting to be used. Equals to /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("heap_inuse_bytes"), - "Number of heap bytes that are in use. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("heap_released_bytes"), - "Number of heap bytes released to OS. Equals to /memory/classes/heap/released:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("heap_objects"), - "Number of currently allocated objects. Equals to /gc/heap/objects:objects.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("stack_inuse_bytes"), - "Number of bytes obtained from system for stack allocator in non-CGO environments. Equals to /memory/classes/heap/stacks:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("stack_sys_bytes"), - "Number of bytes obtained from system for stack allocator. Equals to /memory/classes/heap/stacks:bytes + /memory/classes/os-stacks:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("mspan_inuse_bytes"), - "Number of bytes in use by mspan structures. Equals to /memory/classes/metadata/mspan/inuse:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("mspan_sys_bytes"), - "Number of bytes used for mspan structures obtained from system. Equals to /memory/classes/metadata/mspan/inuse:bytes + /memory/classes/metadata/mspan/free:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("mcache_inuse_bytes"), - "Number of bytes in use by mcache structures. Equals to /memory/classes/metadata/mcache/inuse:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("mcache_sys_bytes"), - "Number of bytes used for mcache structures obtained from system. Equals to /memory/classes/metadata/mcache/inuse:bytes + /memory/classes/metadata/mcache/free:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("buck_hash_sys_bytes"), - "Number of bytes used by the profiling bucket hash table. Equals to /memory/classes/profiling/buckets:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("gc_sys_bytes"), - "Number of bytes used for garbage collection system metadata. Equals to /memory/classes/metadata/other:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("other_sys_bytes"), - "Number of bytes used for other system allocations. Equals to /memory/classes/other:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) }, - valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("next_gc_bytes"), - "Number of heap bytes when next garbage collection will take place. Equals to /gc/heap/goal:bytes.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, - valType: GaugeValue, - }, - } -} - -type baseGoCollector struct { - goroutinesDesc *Desc - threadsDesc *Desc - gcDesc *Desc - gcLastTimeDesc *Desc - goInfoDesc *Desc -} - -func newBaseGoCollector() baseGoCollector { - return baseGoCollector{ - goroutinesDesc: NewDesc( - "go_goroutines", - "Number of goroutines that currently exist.", - nil, nil), - threadsDesc: NewDesc( - "go_threads", - "Number of OS threads created.", - nil, nil), - gcDesc: NewDesc( - "go_gc_duration_seconds", - "A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.", - nil, nil), - gcLastTimeDesc: NewDesc( - "go_memstats_last_gc_time_seconds", - "Number of seconds since 1970 of last garbage collection.", - nil, nil), - goInfoDesc: NewDesc( - "go_info", - "Information about the Go environment.", - nil, Labels{"version": runtime.Version()}), - } -} - -// Describe returns all descriptions of the collector. -func (c *baseGoCollector) Describe(ch chan<- *Desc) { - ch <- c.goroutinesDesc - ch <- c.threadsDesc - ch <- c.gcDesc - ch <- c.gcLastTimeDesc - ch <- c.goInfoDesc -} - -// Collect returns the current state of all metrics of the collector. -func (c *baseGoCollector) Collect(ch chan<- Metric) { - ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine())) - - n := getRuntimeNumThreads() - ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, n) - - var stats debug.GCStats - stats.PauseQuantiles = make([]time.Duration, 5) - debug.ReadGCStats(&stats) - - quantiles := make(map[float64]float64) - for idx, pq := range stats.PauseQuantiles[1:] { - quantiles[float64(idx+1)/float64(len(stats.PauseQuantiles)-1)] = pq.Seconds() - } - quantiles[0.0] = stats.PauseQuantiles[0].Seconds() - ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles) - ch <- MustNewConstMetric(c.gcLastTimeDesc, GaugeValue, float64(stats.LastGC.UnixNano())/1e9) - ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1) -} - -func memstatNamespace(s string) string { - return "go_memstats_" + s -} - -// memStatsMetrics provide description, evaluator, runtime/metrics name, and -// value type for memstat metrics. -type memStatsMetrics []struct { - desc *Desc - eval func(*runtime.MemStats) float64 - valType ValueType -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go deleted file mode 100644 index 897a6e906b3a..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !go1.17 -// +build !go1.17 - -package prometheus - -import ( - "runtime" - "sync" - "time" -) - -type goCollector struct { - base baseGoCollector - - // ms... are memstats related. - msLast *runtime.MemStats // Previously collected memstats. - msLastTimestamp time.Time - msMtx sync.Mutex // Protects msLast and msLastTimestamp. - msMetrics memStatsMetrics - msRead func(*runtime.MemStats) // For mocking in tests. - msMaxWait time.Duration // Wait time for fresh memstats. - msMaxAge time.Duration // Maximum allowed age of old memstats. -} - -// NewGoCollector is the obsolete version of collectors.NewGoCollector. -// See there for documentation. -// -// Deprecated: Use collectors.NewGoCollector instead. -func NewGoCollector() Collector { - msMetrics := goRuntimeMemStats() - msMetrics = append(msMetrics, struct { - desc *Desc - eval func(*runtime.MemStats) float64 - valType ValueType - }{ - // This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 - desc: NewDesc( - memstatNamespace("gc_cpu_fraction"), - "The fraction of this program's available CPU time used by the GC since the program started.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction }, - valType: GaugeValue, - }) - return &goCollector{ - base: newBaseGoCollector(), - msLast: &runtime.MemStats{}, - msRead: runtime.ReadMemStats, - msMaxWait: time.Second, - msMaxAge: 5 * time.Minute, - msMetrics: msMetrics, - } -} - -// Describe returns all descriptions of the collector. -func (c *goCollector) Describe(ch chan<- *Desc) { - c.base.Describe(ch) - for _, i := range c.msMetrics { - ch <- i.desc - } -} - -// Collect returns the current state of all metrics of the collector. -func (c *goCollector) Collect(ch chan<- Metric) { - var ( - ms = &runtime.MemStats{} - done = make(chan struct{}) - ) - // Start reading memstats first as it might take a while. - go func() { - c.msRead(ms) - c.msMtx.Lock() - c.msLast = ms - c.msLastTimestamp = time.Now() - c.msMtx.Unlock() - close(done) - }() - - // Collect base non-memory metrics. - c.base.Collect(ch) - - timer := time.NewTimer(c.msMaxWait) - select { - case <-done: // Our own ReadMemStats succeeded in time. Use it. - timer.Stop() // Important for high collection frequencies to not pile up timers. - c.msCollect(ch, ms) - return - case <-timer.C: // Time out, use last memstats if possible. Continue below. - } - c.msMtx.Lock() - if time.Since(c.msLastTimestamp) < c.msMaxAge { - // Last memstats are recent enough. Collect from them under the lock. - c.msCollect(ch, c.msLast) - c.msMtx.Unlock() - return - } - // If we are here, the last memstats are too old or don't exist. We have - // to wait until our own ReadMemStats finally completes. For that to - // happen, we have to release the lock. - c.msMtx.Unlock() - <-done - c.msCollect(ch, ms) -} - -func (c *goCollector) msCollect(ch chan<- Metric, ms *runtime.MemStats) { - for _, i := range c.msMetrics { - ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms)) - } -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go deleted file mode 100644 index 6b8684731c94..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go +++ /dev/null @@ -1,574 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build go1.17 -// +build go1.17 - -package prometheus - -import ( - "fmt" - "math" - "runtime" - "runtime/metrics" - "strings" - "sync" - - "github.com/prometheus/client_golang/prometheus/internal" - - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/proto" -) - -const ( - // constants for strings referenced more than once. - goGCHeapTinyAllocsObjects = "/gc/heap/tiny/allocs:objects" - goGCHeapAllocsObjects = "/gc/heap/allocs:objects" - goGCHeapFreesObjects = "/gc/heap/frees:objects" - goGCHeapFreesBytes = "/gc/heap/frees:bytes" - goGCHeapAllocsBytes = "/gc/heap/allocs:bytes" - goGCHeapObjects = "/gc/heap/objects:objects" - goGCHeapGoalBytes = "/gc/heap/goal:bytes" - goMemoryClassesTotalBytes = "/memory/classes/total:bytes" - goMemoryClassesHeapObjectsBytes = "/memory/classes/heap/objects:bytes" - goMemoryClassesHeapUnusedBytes = "/memory/classes/heap/unused:bytes" - goMemoryClassesHeapReleasedBytes = "/memory/classes/heap/released:bytes" - goMemoryClassesHeapFreeBytes = "/memory/classes/heap/free:bytes" - goMemoryClassesHeapStacksBytes = "/memory/classes/heap/stacks:bytes" - goMemoryClassesOSStacksBytes = "/memory/classes/os-stacks:bytes" - goMemoryClassesMetadataMSpanInuseBytes = "/memory/classes/metadata/mspan/inuse:bytes" - goMemoryClassesMetadataMSPanFreeBytes = "/memory/classes/metadata/mspan/free:bytes" - goMemoryClassesMetadataMCacheInuseBytes = "/memory/classes/metadata/mcache/inuse:bytes" - goMemoryClassesMetadataMCacheFreeBytes = "/memory/classes/metadata/mcache/free:bytes" - goMemoryClassesProfilingBucketsBytes = "/memory/classes/profiling/buckets:bytes" - goMemoryClassesMetadataOtherBytes = "/memory/classes/metadata/other:bytes" - goMemoryClassesOtherBytes = "/memory/classes/other:bytes" -) - -// rmNamesForMemStatsMetrics represents runtime/metrics names required to populate goRuntimeMemStats from like logic. -var rmNamesForMemStatsMetrics = []string{ - goGCHeapTinyAllocsObjects, - goGCHeapAllocsObjects, - goGCHeapFreesObjects, - goGCHeapAllocsBytes, - goGCHeapObjects, - goGCHeapGoalBytes, - goMemoryClassesTotalBytes, - goMemoryClassesHeapObjectsBytes, - goMemoryClassesHeapUnusedBytes, - goMemoryClassesHeapReleasedBytes, - goMemoryClassesHeapFreeBytes, - goMemoryClassesHeapStacksBytes, - goMemoryClassesOSStacksBytes, - goMemoryClassesMetadataMSpanInuseBytes, - goMemoryClassesMetadataMSPanFreeBytes, - goMemoryClassesMetadataMCacheInuseBytes, - goMemoryClassesMetadataMCacheFreeBytes, - goMemoryClassesProfilingBucketsBytes, - goMemoryClassesMetadataOtherBytes, - goMemoryClassesOtherBytes, -} - -func bestEffortLookupRM(lookup []string) []metrics.Description { - ret := make([]metrics.Description, 0, len(lookup)) - for _, rm := range metrics.All() { - for _, m := range lookup { - if m == rm.Name { - ret = append(ret, rm) - } - } - } - return ret -} - -type goCollector struct { - base baseGoCollector - - // mu protects updates to all fields ensuring a consistent - // snapshot is always produced by Collect. - mu sync.Mutex - - // Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed). - sampleBuf []metrics.Sample - // sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums. - sampleMap map[string]*metrics.Sample - - // rmExposedMetrics represents all runtime/metrics package metrics - // that were configured to be exposed. - rmExposedMetrics []collectorMetric - rmExactSumMapForHist map[string]string - - // With Go 1.17, the runtime/metrics package was introduced. - // From that point on, metric names produced by the runtime/metrics - // package could be generated from runtime/metrics names. However, - // these differ from the old names for the same values. - // - // This field exists to export the same values under the old names - // as well. - msMetrics memStatsMetrics - msMetricsEnabled bool -} - -type rmMetricDesc struct { - metrics.Description -} - -func matchRuntimeMetricsRules(rules []internal.GoCollectorRule) []rmMetricDesc { - var descs []rmMetricDesc - for _, d := range metrics.All() { - var ( - deny = true - desc rmMetricDesc - ) - - for _, r := range rules { - if !r.Matcher.MatchString(d.Name) { - continue - } - deny = r.Deny - } - if deny { - continue - } - - desc.Description = d - descs = append(descs, desc) - } - return descs -} - -func defaultGoCollectorOptions() internal.GoCollectorOptions { - return internal.GoCollectorOptions{ - RuntimeMetricSumForHist: map[string]string{ - "/gc/heap/allocs-by-size:bytes": goGCHeapAllocsBytes, - "/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes, - }, - RuntimeMetricRules: []internal.GoCollectorRule{ - // Recommended metrics we want by default from runtime/metrics. - {Matcher: internal.GoCollectorDefaultRuntimeMetrics}, - }, - } -} - -// NewGoCollector is the obsolete version of collectors.NewGoCollector. -// See there for documentation. -// -// Deprecated: Use collectors.NewGoCollector instead. -func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { - opt := defaultGoCollectorOptions() - for _, o := range opts { - o(&opt) - } - - exposedDescriptions := matchRuntimeMetricsRules(opt.RuntimeMetricRules) - - // Collect all histogram samples so that we can get their buckets. - // The API guarantees that the buckets are always fixed for the lifetime - // of the process. - var histograms []metrics.Sample - for _, d := range exposedDescriptions { - if d.Kind == metrics.KindFloat64Histogram { - histograms = append(histograms, metrics.Sample{Name: d.Name}) - } - } - - if len(histograms) > 0 { - metrics.Read(histograms) - } - - bucketsMap := make(map[string][]float64) - for i := range histograms { - bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets - } - - // Generate a collector for each exposed runtime/metrics metric. - metricSet := make([]collectorMetric, 0, len(exposedDescriptions)) - // SampleBuf is used for reading from runtime/metrics. - // We are assuming the largest case to have stable pointers for sampleMap purposes. - sampleBuf := make([]metrics.Sample, 0, len(exposedDescriptions)+len(opt.RuntimeMetricSumForHist)+len(rmNamesForMemStatsMetrics)) - sampleMap := make(map[string]*metrics.Sample, len(exposedDescriptions)) - for _, d := range exposedDescriptions { - namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(&d.Description) - if !ok { - // Just ignore this metric; we can't do anything with it here. - // If a user decides to use the latest version of Go, we don't want - // to fail here. This condition is tested in TestExpectedRuntimeMetrics. - continue - } - help := attachOriginalName(d.Description.Description, d.Name) - - sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name}) - sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1] - - var m collectorMetric - if d.Kind == metrics.KindFloat64Histogram { - _, hasSum := opt.RuntimeMetricSumForHist[d.Name] - unit := d.Name[strings.IndexRune(d.Name, ':')+1:] - m = newBatchHistogram( - NewDesc( - BuildFQName(namespace, subsystem, name), - help, - nil, - nil, - ), - internal.RuntimeMetricsBucketsForUnit(bucketsMap[d.Name], unit), - hasSum, - ) - } else if d.Cumulative { - m = NewCounter(CounterOpts{ - Namespace: namespace, - Subsystem: subsystem, - Name: name, - Help: help, - }, - ) - } else { - m = NewGauge(GaugeOpts{ - Namespace: namespace, - Subsystem: subsystem, - Name: name, - Help: help, - }) - } - metricSet = append(metricSet, m) - } - - // Add exact sum metrics to sampleBuf if not added before. - for _, h := range histograms { - sumMetric, ok := opt.RuntimeMetricSumForHist[h.Name] - if !ok { - continue - } - - if _, ok := sampleMap[sumMetric]; ok { - continue - } - sampleBuf = append(sampleBuf, metrics.Sample{Name: sumMetric}) - sampleMap[sumMetric] = &sampleBuf[len(sampleBuf)-1] - } - - var ( - msMetrics memStatsMetrics - msDescriptions []metrics.Description - ) - - if !opt.DisableMemStatsLikeMetrics { - msMetrics = goRuntimeMemStats() - msDescriptions = bestEffortLookupRM(rmNamesForMemStatsMetrics) - - // Check if metric was not exposed before and if not, add to sampleBuf. - for _, mdDesc := range msDescriptions { - if _, ok := sampleMap[mdDesc.Name]; ok { - continue - } - sampleBuf = append(sampleBuf, metrics.Sample{Name: mdDesc.Name}) - sampleMap[mdDesc.Name] = &sampleBuf[len(sampleBuf)-1] - } - } - - return &goCollector{ - base: newBaseGoCollector(), - sampleBuf: sampleBuf, - sampleMap: sampleMap, - rmExposedMetrics: metricSet, - rmExactSumMapForHist: opt.RuntimeMetricSumForHist, - msMetrics: msMetrics, - msMetricsEnabled: !opt.DisableMemStatsLikeMetrics, - } -} - -func attachOriginalName(desc, origName string) string { - return fmt.Sprintf("%s Sourced from %s.", desc, origName) -} - -// Describe returns all descriptions of the collector. -func (c *goCollector) Describe(ch chan<- *Desc) { - c.base.Describe(ch) - for _, i := range c.msMetrics { - ch <- i.desc - } - for _, m := range c.rmExposedMetrics { - ch <- m.Desc() - } -} - -// Collect returns the current state of all metrics of the collector. -func (c *goCollector) Collect(ch chan<- Metric) { - // Collect base non-memory metrics. - c.base.Collect(ch) - - if len(c.sampleBuf) == 0 { - return - } - - // Collect must be thread-safe, so prevent concurrent use of - // sampleBuf elements. Just read into sampleBuf but write all the data - // we get into our Metrics or MemStats. - // - // This lock also ensures that the Metrics we send out are all from - // the same updates, ensuring their mutual consistency insofar as - // is guaranteed by the runtime/metrics package. - // - // N.B. This locking is heavy-handed, but Collect is expected to be called - // relatively infrequently. Also the core operation here, metrics.Read, - // is fast (O(tens of microseconds)) so contention should certainly be - // low, though channel operations and any allocations may add to that. - c.mu.Lock() - defer c.mu.Unlock() - - // Populate runtime/metrics sample buffer. - metrics.Read(c.sampleBuf) - - // Collect all our runtime/metrics user chose to expose from sampleBuf (if any). - for i, metric := range c.rmExposedMetrics { - // We created samples for exposed metrics first in order, so indexes match. - sample := c.sampleBuf[i] - - // N.B. switch on concrete type because it's significantly more efficient - // than checking for the Counter and Gauge interface implementations. In - // this case, we control all the types here. - switch m := metric.(type) { - case *counter: - // Guard against decreases. This should never happen, but a failure - // to do so will result in a panic, which is a harsh consequence for - // a metrics collection bug. - v0, v1 := m.get(), unwrapScalarRMValue(sample.Value) - if v1 > v0 { - m.Add(unwrapScalarRMValue(sample.Value) - m.get()) - } - m.Collect(ch) - case *gauge: - m.Set(unwrapScalarRMValue(sample.Value)) - m.Collect(ch) - case *batchHistogram: - m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name)) - m.Collect(ch) - default: - panic("unexpected metric type") - } - } - - if c.msMetricsEnabled { - // ms is a dummy MemStats that we populate ourselves so that we can - // populate the old metrics from it if goMemStatsCollection is enabled. - var ms runtime.MemStats - memStatsFromRM(&ms, c.sampleMap) - for _, i := range c.msMetrics { - ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms)) - } - } -} - -// unwrapScalarRMValue unwraps a runtime/metrics value that is assumed -// to be scalar and returns the equivalent float64 value. Panics if the -// value is not scalar. -func unwrapScalarRMValue(v metrics.Value) float64 { - switch v.Kind() { - case metrics.KindUint64: - return float64(v.Uint64()) - case metrics.KindFloat64: - return v.Float64() - case metrics.KindBad: - // Unsupported metric. - // - // This should never happen because we always populate our metric - // set from the runtime/metrics package. - panic("unexpected bad kind metric") - default: - // Unsupported metric kind. - // - // This should never happen because we check for this during initialization - // and flag and filter metrics whose kinds we don't understand. - panic(fmt.Sprintf("unexpected unsupported metric: %v", v.Kind())) - } -} - -// exactSumFor takes a runtime/metrics metric name (that is assumed to -// be of kind KindFloat64Histogram) and returns its exact sum and whether -// its exact sum exists. -// -// The runtime/metrics API for histograms doesn't currently expose exact -// sums, but some of the other metrics are in fact exact sums of histograms. -func (c *goCollector) exactSumFor(rmName string) float64 { - sumName, ok := c.rmExactSumMapForHist[rmName] - if !ok { - return 0 - } - s, ok := c.sampleMap[sumName] - if !ok { - return 0 - } - return unwrapScalarRMValue(s.Value) -} - -func memStatsFromRM(ms *runtime.MemStats, rm map[string]*metrics.Sample) { - lookupOrZero := func(name string) uint64 { - if s, ok := rm[name]; ok { - return s.Value.Uint64() - } - return 0 - } - - // Currently, MemStats adds tiny alloc count to both Mallocs AND Frees. - // The reason for this is because MemStats couldn't be extended at the time - // but there was a desire to have Mallocs at least be a little more representative, - // while having Mallocs - Frees still represent a live object count. - // Unfortunately, MemStats doesn't actually export a large allocation count, - // so it's impossible to pull this number out directly. - tinyAllocs := lookupOrZero(goGCHeapTinyAllocsObjects) - ms.Mallocs = lookupOrZero(goGCHeapAllocsObjects) + tinyAllocs - ms.Frees = lookupOrZero(goGCHeapFreesObjects) + tinyAllocs - - ms.TotalAlloc = lookupOrZero(goGCHeapAllocsBytes) - ms.Sys = lookupOrZero(goMemoryClassesTotalBytes) - ms.Lookups = 0 // Already always zero. - ms.HeapAlloc = lookupOrZero(goMemoryClassesHeapObjectsBytes) - ms.Alloc = ms.HeapAlloc - ms.HeapInuse = ms.HeapAlloc + lookupOrZero(goMemoryClassesHeapUnusedBytes) - ms.HeapReleased = lookupOrZero(goMemoryClassesHeapReleasedBytes) - ms.HeapIdle = ms.HeapReleased + lookupOrZero(goMemoryClassesHeapFreeBytes) - ms.HeapSys = ms.HeapInuse + ms.HeapIdle - ms.HeapObjects = lookupOrZero(goGCHeapObjects) - ms.StackInuse = lookupOrZero(goMemoryClassesHeapStacksBytes) - ms.StackSys = ms.StackInuse + lookupOrZero(goMemoryClassesOSStacksBytes) - ms.MSpanInuse = lookupOrZero(goMemoryClassesMetadataMSpanInuseBytes) - ms.MSpanSys = ms.MSpanInuse + lookupOrZero(goMemoryClassesMetadataMSPanFreeBytes) - ms.MCacheInuse = lookupOrZero(goMemoryClassesMetadataMCacheInuseBytes) - ms.MCacheSys = ms.MCacheInuse + lookupOrZero(goMemoryClassesMetadataMCacheFreeBytes) - ms.BuckHashSys = lookupOrZero(goMemoryClassesProfilingBucketsBytes) - ms.GCSys = lookupOrZero(goMemoryClassesMetadataOtherBytes) - ms.OtherSys = lookupOrZero(goMemoryClassesOtherBytes) - ms.NextGC = lookupOrZero(goGCHeapGoalBytes) - - // N.B. GCCPUFraction is intentionally omitted. This metric is not useful, - // and often misleading due to the fact that it's an average over the lifetime - // of the process. - // See https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 - // for more details. - ms.GCCPUFraction = 0 -} - -// batchHistogram is a mutable histogram that is updated -// in batches. -type batchHistogram struct { - selfCollector - - // Static fields updated only once. - desc *Desc - hasSum bool - - // Because this histogram operates in batches, it just uses a - // single mutex for everything. updates are always serialized - // but Write calls may operate concurrently with updates. - // Contention between these two sources should be rare. - mu sync.Mutex - buckets []float64 // Inclusive lower bounds, like runtime/metrics. - counts []uint64 - sum float64 // Used if hasSum is true. -} - -// newBatchHistogram creates a new batch histogram value with the given -// Desc, buckets, and whether or not it has an exact sum available. -// -// buckets must always be from the runtime/metrics package, following -// the same conventions. -func newBatchHistogram(desc *Desc, buckets []float64, hasSum bool) *batchHistogram { - // We need to remove -Inf values. runtime/metrics keeps them around. - // But -Inf bucket should not be allowed for prometheus histograms. - if buckets[0] == math.Inf(-1) { - buckets = buckets[1:] - } - h := &batchHistogram{ - desc: desc, - buckets: buckets, - // Because buckets follows runtime/metrics conventions, there's - // 1 more value in the buckets list than there are buckets represented, - // because in runtime/metrics, the bucket values represent *boundaries*, - // and non-Inf boundaries are inclusive lower bounds for that bucket. - counts: make([]uint64, len(buckets)-1), - hasSum: hasSum, - } - h.init(h) - return h -} - -// update updates the batchHistogram from a runtime/metrics histogram. -// -// sum must be provided if the batchHistogram was created to have an exact sum. -// h.buckets must be a strict subset of his.Buckets. -func (h *batchHistogram) update(his *metrics.Float64Histogram, sum float64) { - counts, buckets := his.Counts, his.Buckets - - h.mu.Lock() - defer h.mu.Unlock() - - // Clear buckets. - for i := range h.counts { - h.counts[i] = 0 - } - // Copy and reduce buckets. - var j int - for i, count := range counts { - h.counts[j] += count - if buckets[i+1] == h.buckets[j+1] { - j++ - } - } - if h.hasSum { - h.sum = sum - } -} - -func (h *batchHistogram) Desc() *Desc { - return h.desc -} - -func (h *batchHistogram) Write(out *dto.Metric) error { - h.mu.Lock() - defer h.mu.Unlock() - - sum := float64(0) - if h.hasSum { - sum = h.sum - } - dtoBuckets := make([]*dto.Bucket, 0, len(h.counts)) - totalCount := uint64(0) - for i, count := range h.counts { - totalCount += count - if !h.hasSum { - if count != 0 { - // N.B. This computed sum is an underestimate. - sum += h.buckets[i] * float64(count) - } - } - - // Skip the +Inf bucket, but only for the bucket list. - // It must still count for sum and totalCount. - if math.IsInf(h.buckets[i+1], 1) { - break - } - // Float64Histogram's upper bound is exclusive, so make it inclusive - // by obtaining the next float64 value down, in order. - upperBound := math.Nextafter(h.buckets[i+1], h.buckets[i]) - dtoBuckets = append(dtoBuckets, &dto.Bucket{ - CumulativeCount: proto.Uint64(totalCount), - UpperBound: proto.Float64(upperBound), - }) - } - out.Histogram = &dto.Histogram{ - Bucket: dtoBuckets, - SampleCount: proto.Uint64(totalCount), - SampleSum: proto.Float64(sum), - } - return nil -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go deleted file mode 100644 index c453b754a7f6..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go +++ /dev/null @@ -1,2056 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "errors" - "fmt" - "math" - "runtime" - "sort" - "sync" - "sync/atomic" - "time" - - dto "github.com/prometheus/client_model/go" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -const ( - nativeHistogramSchemaMaximum = 8 - nativeHistogramSchemaMinimum = -4 -) - -// nativeHistogramBounds for the frac of observed values. Only relevant for -// schema > 0. The position in the slice is the schema. (0 is never used, just -// here for convenience of using the schema directly as the index.) -// -// TODO(beorn7): Currently, we do a binary search into these slices. There are -// ways to turn it into a small number of simple array lookups. It probably only -// matters for schema 5 and beyond, but should be investigated. See this comment -// as a starting point: -// https://github.com/open-telemetry/opentelemetry-specification/issues/1776#issuecomment-870164310 -var nativeHistogramBounds = [][]float64{ - // Schema "0": - {0.5}, - // Schema 1: - {0.5, 0.7071067811865475}, - // Schema 2: - {0.5, 0.5946035575013605, 0.7071067811865475, 0.8408964152537144}, - // Schema 3: - { - 0.5, 0.5452538663326288, 0.5946035575013605, 0.6484197773255048, - 0.7071067811865475, 0.7711054127039704, 0.8408964152537144, 0.9170040432046711, - }, - // Schema 4: - { - 0.5, 0.5221368912137069, 0.5452538663326288, 0.5693943173783458, - 0.5946035575013605, 0.620928906036742, 0.6484197773255048, 0.6771277734684463, - 0.7071067811865475, 0.7384130729697496, 0.7711054127039704, 0.805245165974627, - 0.8408964152537144, 0.8781260801866495, 0.9170040432046711, 0.9576032806985735, - }, - // Schema 5: - { - 0.5, 0.5109485743270583, 0.5221368912137069, 0.5335702003384117, - 0.5452538663326288, 0.5571933712979462, 0.5693943173783458, 0.5818624293887887, - 0.5946035575013605, 0.6076236799902344, 0.620928906036742, 0.6345254785958666, - 0.6484197773255048, 0.6626183215798706, 0.6771277734684463, 0.6919549409819159, - 0.7071067811865475, 0.7225904034885232, 0.7384130729697496, 0.7545822137967112, - 0.7711054127039704, 0.7879904225539431, 0.805245165974627, 0.8228777390769823, - 0.8408964152537144, 0.8593096490612387, 0.8781260801866495, 0.8973545375015533, - 0.9170040432046711, 0.9370838170551498, 0.9576032806985735, 0.9785720620876999, - }, - // Schema 6: - { - 0.5, 0.5054446430258502, 0.5109485743270583, 0.5165124395106142, - 0.5221368912137069, 0.5278225891802786, 0.5335702003384117, 0.5393803988785598, - 0.5452538663326288, 0.5511912916539204, 0.5571933712979462, 0.5632608093041209, - 0.5693943173783458, 0.5755946149764913, 0.5818624293887887, 0.5881984958251406, - 0.5946035575013605, 0.6010783657263515, 0.6076236799902344, 0.6142402680534349, - 0.620928906036742, 0.6276903785123455, 0.6345254785958666, 0.6414350080393891, - 0.6484197773255048, 0.6554806057623822, 0.6626183215798706, 0.6698337620266515, - 0.6771277734684463, 0.6845012114872953, 0.6919549409819159, 0.6994898362691555, - 0.7071067811865475, 0.7148066691959849, 0.7225904034885232, 0.7304588970903234, - 0.7384130729697496, 0.7464538641456323, 0.7545822137967112, 0.762799075372269, - 0.7711054127039704, 0.7795022001189185, 0.7879904225539431, 0.7965710756711334, - 0.805245165974627, 0.8140137109286738, 0.8228777390769823, 0.8318382901633681, - 0.8408964152537144, 0.8500531768592616, 0.8593096490612387, 0.8686669176368529, - 0.8781260801866495, 0.8876882462632604, 0.8973545375015533, 0.9071260877501991, - 0.9170040432046711, 0.9269895625416926, 0.9370838170551498, 0.9472879907934827, - 0.9576032806985735, 0.9680308967461471, 0.9785720620876999, 0.9892280131939752, - }, - // Schema 7: - { - 0.5, 0.5027149505564014, 0.5054446430258502, 0.5081891574554764, - 0.5109485743270583, 0.5137229745593818, 0.5165124395106142, 0.5193170509806894, - 0.5221368912137069, 0.5249720429003435, 0.5278225891802786, 0.5306886136446309, - 0.5335702003384117, 0.5364674337629877, 0.5393803988785598, 0.5423091811066545, - 0.5452538663326288, 0.5482145409081883, 0.5511912916539204, 0.5541842058618393, - 0.5571933712979462, 0.5602188762048033, 0.5632608093041209, 0.5663192597993595, - 0.5693943173783458, 0.572486072215902, 0.5755946149764913, 0.5787200368168754, - 0.5818624293887887, 0.585021884841625, 0.5881984958251406, 0.5913923554921704, - 0.5946035575013605, 0.5978321960199137, 0.6010783657263515, 0.6043421618132907, - 0.6076236799902344, 0.6109230164863786, 0.6142402680534349, 0.6175755319684665, - 0.620928906036742, 0.6243004885946023, 0.6276903785123455, 0.6310986751971253, - 0.6345254785958666, 0.637970889198196, 0.6414350080393891, 0.6449179367033329, - 0.6484197773255048, 0.6519406325959679, 0.6554806057623822, 0.659039800633032, - 0.6626183215798706, 0.6662162735415805, 0.6698337620266515, 0.6734708931164728, - 0.6771277734684463, 0.6808045103191123, 0.6845012114872953, 0.688217985377265, - 0.6919549409819159, 0.6957121878859629, 0.6994898362691555, 0.7032879969095076, - 0.7071067811865475, 0.7109463010845827, 0.7148066691959849, 0.718687998724491, - 0.7225904034885232, 0.7265139979245261, 0.7304588970903234, 0.7344252166684908, - 0.7384130729697496, 0.7424225829363761, 0.7464538641456323, 0.7505070348132126, - 0.7545822137967112, 0.7586795205991071, 0.762799075372269, 0.7669409989204777, - 0.7711054127039704, 0.7752924388424999, 0.7795022001189185, 0.7837348199827764, - 0.7879904225539431, 0.7922691326262467, 0.7965710756711334, 0.8008963778413465, - 0.805245165974627, 0.8096175675974316, 0.8140137109286738, 0.8184337248834821, - 0.8228777390769823, 0.8273458838280969, 0.8318382901633681, 0.8363550898207981, - 0.8408964152537144, 0.8454623996346523, 0.8500531768592616, 0.8546688815502312, - 0.8593096490612387, 0.8639756154809185, 0.8686669176368529, 0.8733836930995842, - 0.8781260801866495, 0.8828942179666361, 0.8876882462632604, 0.8925083056594671, - 0.8973545375015533, 0.9022270839033115, 0.9071260877501991, 0.9120516927035263, - 0.9170040432046711, 0.9219832844793128, 0.9269895625416926, 0.9320230241988943, - 0.9370838170551498, 0.9421720895161669, 0.9472879907934827, 0.9524316709088368, - 0.9576032806985735, 0.9628029718180622, 0.9680308967461471, 0.9732872087896164, - 0.9785720620876999, 0.9838856116165875, 0.9892280131939752, 0.9945994234836328, - }, - // Schema 8: - { - 0.5, 0.5013556375251013, 0.5027149505564014, 0.5040779490592088, - 0.5054446430258502, 0.5068150424757447, 0.5081891574554764, 0.509566998038869, - 0.5109485743270583, 0.5123338964485679, 0.5137229745593818, 0.5151158188430205, - 0.5165124395106142, 0.5179128468009786, 0.5193170509806894, 0.520725062344158, - 0.5221368912137069, 0.5235525479396449, 0.5249720429003435, 0.526395386502313, - 0.5278225891802786, 0.5292536613972564, 0.5306886136446309, 0.5321274564422321, - 0.5335702003384117, 0.5350168559101208, 0.5364674337629877, 0.5379219445313954, - 0.5393803988785598, 0.5408428074966075, 0.5423091811066545, 0.5437795304588847, - 0.5452538663326288, 0.5467321995364429, 0.5482145409081883, 0.549700901315111, - 0.5511912916539204, 0.5526857228508706, 0.5541842058618393, 0.5556867516724088, - 0.5571933712979462, 0.5587040757836845, 0.5602188762048033, 0.5617377836665098, - 0.5632608093041209, 0.564787964283144, 0.5663192597993595, 0.5678547070789026, - 0.5693943173783458, 0.5709381019847808, 0.572486072215902, 0.5740382394200894, - 0.5755946149764913, 0.5771552102951081, 0.5787200368168754, 0.5802891060137493, - 0.5818624293887887, 0.5834400184762408, 0.585021884841625, 0.5866080400818185, - 0.5881984958251406, 0.5897932637314379, 0.5913923554921704, 0.5929957828304968, - 0.5946035575013605, 0.5962156912915756, 0.5978321960199137, 0.5994530835371903, - 0.6010783657263515, 0.6027080545025619, 0.6043421618132907, 0.6059806996384005, - 0.6076236799902344, 0.6092711149137041, 0.6109230164863786, 0.6125793968185725, - 0.6142402680534349, 0.6159056423670379, 0.6175755319684665, 0.6192499490999082, - 0.620928906036742, 0.622612415087629, 0.6243004885946023, 0.6259931389331581, - 0.6276903785123455, 0.6293922197748583, 0.6310986751971253, 0.6328097572894031, - 0.6345254785958666, 0.6362458516947014, 0.637970889198196, 0.6397006037528346, - 0.6414350080393891, 0.6431741147730128, 0.6449179367033329, 0.6466664866145447, - 0.6484197773255048, 0.6501778216898253, 0.6519406325959679, 0.6537082229673385, - 0.6554806057623822, 0.6572577939746774, 0.659039800633032, 0.6608266388015788, - 0.6626183215798706, 0.6644148621029772, 0.6662162735415805, 0.6680225691020727, - 0.6698337620266515, 0.6716498655934177, 0.6734708931164728, 0.6752968579460171, - 0.6771277734684463, 0.6789636531064505, 0.6808045103191123, 0.6826503586020058, - 0.6845012114872953, 0.6863570825438342, 0.688217985377265, 0.690083933630119, - 0.6919549409819159, 0.6938310211492645, 0.6957121878859629, 0.6975984549830999, - 0.6994898362691555, 0.7013863456101023, 0.7032879969095076, 0.7051948041086352, - 0.7071067811865475, 0.7090239421602076, 0.7109463010845827, 0.7128738720527471, - 0.7148066691959849, 0.7167447066838943, 0.718687998724491, 0.7206365595643126, - 0.7225904034885232, 0.7245495448210174, 0.7265139979245261, 0.7284837772007218, - 0.7304588970903234, 0.7324393720732029, 0.7344252166684908, 0.7364164454346837, - 0.7384130729697496, 0.7404151139112358, 0.7424225829363761, 0.7444354947621984, - 0.7464538641456323, 0.7484777058836176, 0.7505070348132126, 0.7525418658117031, - 0.7545822137967112, 0.7566280937263048, 0.7586795205991071, 0.7607365094544071, - 0.762799075372269, 0.7648672334736434, 0.7669409989204777, 0.7690203869158282, - 0.7711054127039704, 0.7731960915705107, 0.7752924388424999, 0.7773944698885442, - 0.7795022001189185, 0.7816156449856788, 0.7837348199827764, 0.7858597406461707, - 0.7879904225539431, 0.7901268813264122, 0.7922691326262467, 0.7944171921585818, - 0.7965710756711334, 0.7987307989543135, 0.8008963778413465, 0.8030678282083853, - 0.805245165974627, 0.8074284071024302, 0.8096175675974316, 0.8118126635086642, - 0.8140137109286738, 0.8162207259936375, 0.8184337248834821, 0.820652723822003, - 0.8228777390769823, 0.8251087869603088, 0.8273458838280969, 0.8295890460808079, - 0.8318382901633681, 0.8340936325652911, 0.8363550898207981, 0.8386226785089391, - 0.8408964152537144, 0.8431763167241966, 0.8454623996346523, 0.8477546807446661, - 0.8500531768592616, 0.8523579048290255, 0.8546688815502312, 0.8569861239649629, - 0.8593096490612387, 0.8616394738731368, 0.8639756154809185, 0.8663180910111553, - 0.8686669176368529, 0.871022112577578, 0.8733836930995842, 0.8757516765159389, - 0.8781260801866495, 0.8805069215187917, 0.8828942179666361, 0.8852879870317771, - 0.8876882462632604, 0.890095013257712, 0.8925083056594671, 0.8949281411607002, - 0.8973545375015533, 0.8997875124702672, 0.9022270839033115, 0.9046732696855155, - 0.9071260877501991, 0.909585556079304, 0.9120516927035263, 0.9145245157024483, - 0.9170040432046711, 0.9194902933879467, 0.9219832844793128, 0.9244830347552253, - 0.9269895625416926, 0.92950288621441, 0.9320230241988943, 0.9345499949706191, - 0.9370838170551498, 0.93962450902828, 0.9421720895161669, 0.9447265771954693, - 0.9472879907934827, 0.9498563490882775, 0.9524316709088368, 0.9550139751351947, - 0.9576032806985735, 0.9601996065815236, 0.9628029718180622, 0.9654133954938133, - 0.9680308967461471, 0.9706554947643201, 0.9732872087896164, 0.9759260581154889, - 0.9785720620876999, 0.9812252401044634, 0.9838856116165875, 0.9865531961276168, - 0.9892280131939752, 0.9919100824251095, 0.9945994234836328, 0.9972960560854698, - }, -} - -// The nativeHistogramBounds above can be generated with the code below. -// -// TODO(beorn7): It's tempting to actually use `go generate` to generate the -// code above. However, this could lead to slightly different numbers on -// different architectures. We still need to come to terms if we are fine with -// that, or if we might prefer to specify precise numbers in the standard. -// -// var nativeHistogramBounds [][]float64 = make([][]float64, 9) -// -// func init() { -// // Populate nativeHistogramBounds. -// numBuckets := 1 -// for i := range nativeHistogramBounds { -// bounds := []float64{0.5} -// factor := math.Exp2(math.Exp2(float64(-i))) -// for j := 0; j < numBuckets-1; j++ { -// var bound float64 -// if (j+1)%2 == 0 { -// // Use previously calculated value for increased precision. -// bound = nativeHistogramBounds[i-1][j/2+1] -// } else { -// bound = bounds[j] * factor -// } -// bounds = append(bounds, bound) -// } -// numBuckets *= 2 -// nativeHistogramBounds[i] = bounds -// } -// } - -// A Histogram counts individual observations from an event or sample stream in -// configurable static buckets (or in dynamic sparse buckets as part of the -// experimental Native Histograms, see below for more details). Similar to a -// Summary, it also provides a sum of observations and an observation count. -// -// On the Prometheus server, quantiles can be calculated from a Histogram using -// the histogram_quantile PromQL function. -// -// Note that Histograms, in contrast to Summaries, can be aggregated in PromQL -// (see the documentation for detailed procedures). However, Histograms require -// the user to pre-define suitable buckets, and they are in general less -// accurate. (Both problems are addressed by the experimental Native -// Histograms. To use them, configure a NativeHistogramBucketFactor in the -// HistogramOpts. They also require a Prometheus server v2.40+ with the -// corresponding feature flag enabled.) -// -// The Observe method of a Histogram has a very low performance overhead in -// comparison with the Observe method of a Summary. -// -// To create Histogram instances, use NewHistogram. -type Histogram interface { - Metric - Collector - - // Observe adds a single observation to the histogram. Observations are - // usually positive or zero. Negative observations are accepted but - // prevent current versions of Prometheus from properly detecting - // counter resets in the sum of observations. (The experimental Native - // Histograms handle negative observations properly.) See - // https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations - // for details. - Observe(float64) -} - -// bucketLabel is used for the label that defines the upper bound of a -// bucket of a histogram ("le" -> "less or equal"). -const bucketLabel = "le" - -// DefBuckets are the default Histogram buckets. The default buckets are -// tailored to broadly measure the response time (in seconds) of a network -// service. Most likely, however, you will be required to define buckets -// customized to your use case. -var DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} - -// DefNativeHistogramZeroThreshold is the default value for -// NativeHistogramZeroThreshold in the HistogramOpts. -// -// The value is 2^-128 (or 0.5*2^-127 in the actual IEEE 754 representation), -// which is a bucket boundary at all possible resolutions. -const DefNativeHistogramZeroThreshold = 2.938735877055719e-39 - -// NativeHistogramZeroThresholdZero can be used as NativeHistogramZeroThreshold -// in the HistogramOpts to create a zero bucket of width zero, i.e. a zero -// bucket that only receives observations of precisely zero. -const NativeHistogramZeroThresholdZero = -1 - -var errBucketLabelNotAllowed = fmt.Errorf( - "%q is not allowed as label name in histograms", bucketLabel, -) - -// LinearBuckets creates 'count' regular buckets, each 'width' wide, where the -// lowest bucket has an upper bound of 'start'. The final +Inf bucket is not -// counted and not included in the returned slice. The returned slice is meant -// to be used for the Buckets field of HistogramOpts. -// -// The function panics if 'count' is zero or negative. -func LinearBuckets(start, width float64, count int) []float64 { - if count < 1 { - panic("LinearBuckets needs a positive count") - } - buckets := make([]float64, count) - for i := range buckets { - buckets[i] = start - start += width - } - return buckets -} - -// ExponentialBuckets creates 'count' regular buckets, where the lowest bucket -// has an upper bound of 'start' and each following bucket's upper bound is -// 'factor' times the previous bucket's upper bound. The final +Inf bucket is -// not counted and not included in the returned slice. The returned slice is -// meant to be used for the Buckets field of HistogramOpts. -// -// The function panics if 'count' is 0 or negative, if 'start' is 0 or negative, -// or if 'factor' is less than or equal 1. -func ExponentialBuckets(start, factor float64, count int) []float64 { - if count < 1 { - panic("ExponentialBuckets needs a positive count") - } - if start <= 0 { - panic("ExponentialBuckets needs a positive start value") - } - if factor <= 1 { - panic("ExponentialBuckets needs a factor greater than 1") - } - buckets := make([]float64, count) - for i := range buckets { - buckets[i] = start - start *= factor - } - return buckets -} - -// ExponentialBucketsRange creates 'count' buckets, where the lowest bucket is -// 'min' and the highest bucket is 'max'. The final +Inf bucket is not counted -// and not included in the returned slice. The returned slice is meant to be -// used for the Buckets field of HistogramOpts. -// -// The function panics if 'count' is 0 or negative, if 'min' is 0 or negative. -func ExponentialBucketsRange(minBucket, maxBucket float64, count int) []float64 { - if count < 1 { - panic("ExponentialBucketsRange count needs a positive count") - } - if minBucket <= 0 { - panic("ExponentialBucketsRange min needs to be greater than 0") - } - - // Formula for exponential buckets. - // max = min*growthFactor^(bucketCount-1) - - // We know max/min and highest bucket. Solve for growthFactor. - growthFactor := math.Pow(maxBucket/minBucket, 1.0/float64(count-1)) - - // Now that we know growthFactor, solve for each bucket. - buckets := make([]float64, count) - for i := 1; i <= count; i++ { - buckets[i-1] = minBucket * math.Pow(growthFactor, float64(i-1)) - } - return buckets -} - -// HistogramOpts bundles the options for creating a Histogram metric. It is -// mandatory to set Name to a non-empty string. All other fields are optional -// and can safely be left at their zero value, although it is strongly -// encouraged to set a Help string. -type HistogramOpts struct { - // Namespace, Subsystem, and Name are components of the fully-qualified - // name of the Histogram (created by joining these components with - // "_"). Only Name is mandatory, the others merely help structuring the - // name. Note that the fully-qualified name of the Histogram must be a - // valid Prometheus metric name. - Namespace string - Subsystem string - Name string - - // Help provides information about this Histogram. - // - // Metrics with the same fully-qualified name must have the same Help - // string. - Help string - - // ConstLabels are used to attach fixed labels to this metric. Metrics - // with the same fully-qualified name must have the same label names in - // their ConstLabels. - // - // ConstLabels are only used rarely. In particular, do not use them to - // attach the same labels to all your metrics. Those use cases are - // better covered by target labels set by the scraping Prometheus - // server, or by one specific metric (e.g. a build_info or a - // machine_role metric). See also - // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels - ConstLabels Labels - - // Buckets defines the buckets into which observations are counted. Each - // element in the slice is the upper inclusive bound of a bucket. The - // values must be sorted in strictly increasing order. There is no need - // to add a highest bucket with +Inf bound, it will be added - // implicitly. If Buckets is left as nil or set to a slice of length - // zero, it is replaced by default buckets. The default buckets are - // DefBuckets if no buckets for a native histogram (see below) are used, - // otherwise the default is no buckets. (In other words, if you want to - // use both regular buckets and buckets for a native histogram, you have - // to define the regular buckets here explicitly.) - Buckets []float64 - - // If NativeHistogramBucketFactor is greater than one, so-called sparse - // buckets are used (in addition to the regular buckets, if defined - // above). A Histogram with sparse buckets will be ingested as a Native - // Histogram by a Prometheus server with that feature enabled (requires - // Prometheus v2.40+). Sparse buckets are exponential buckets covering - // the whole float64 range (with the exception of the “zero” bucket, see - // NativeHistogramZeroThreshold below). From any one bucket to the next, - // the width of the bucket grows by a constant - // factor. NativeHistogramBucketFactor provides an upper bound for this - // factor (exception see below). The smaller - // NativeHistogramBucketFactor, the more buckets will be used and thus - // the more costly the histogram will become. A generally good trade-off - // between cost and accuracy is a value of 1.1 (each bucket is at most - // 10% wider than the previous one), which will result in each power of - // two divided into 8 buckets (e.g. there will be 8 buckets between 1 - // and 2, same as between 2 and 4, and 4 and 8, etc.). - // - // Details about the actually used factor: The factor is calculated as - // 2^(2^-n), where n is an integer number between (and including) -4 and - // 8. n is chosen so that the resulting factor is the largest that is - // still smaller or equal to NativeHistogramBucketFactor. Note that the - // smallest possible factor is therefore approx. 1.00271 (i.e. 2^(2^-8) - // ). If NativeHistogramBucketFactor is greater than 1 but smaller than - // 2^(2^-8), then the actually used factor is still 2^(2^-8) even though - // it is larger than the provided NativeHistogramBucketFactor. - // - // NOTE: Native Histograms are still an experimental feature. Their - // behavior might still change without a major version - // bump. Subsequently, all NativeHistogram... options here might still - // change their behavior or name (or might completely disappear) without - // a major version bump. - NativeHistogramBucketFactor float64 - // All observations with an absolute value of less or equal - // NativeHistogramZeroThreshold are accumulated into a “zero” bucket. - // For best results, this should be close to a bucket boundary. This is - // usually the case if picking a power of two. If - // NativeHistogramZeroThreshold is left at zero, - // DefNativeHistogramZeroThreshold is used as the threshold. To - // configure a zero bucket with an actual threshold of zero (i.e. only - // observations of precisely zero will go into the zero bucket), set - // NativeHistogramZeroThreshold to the NativeHistogramZeroThresholdZero - // constant (or any negative float value). - NativeHistogramZeroThreshold float64 - - // The next three fields define a strategy to limit the number of - // populated sparse buckets. If NativeHistogramMaxBucketNumber is left - // at zero, the number of buckets is not limited. (Note that this might - // lead to unbounded memory consumption if the values observed by the - // Histogram are sufficiently wide-spread. In particular, this could be - // used as a DoS attack vector. Where the observed values depend on - // external inputs, it is highly recommended to set a - // NativeHistogramMaxBucketNumber.) Once the set - // NativeHistogramMaxBucketNumber is exceeded, the following strategy is - // enacted: - // - First, if the last reset (or the creation) of the histogram is at - // least NativeHistogramMinResetDuration ago, then the whole - // histogram is reset to its initial state (including regular - // buckets). - // - If less time has passed, or if NativeHistogramMinResetDuration is - // zero, no reset is performed. Instead, the zero threshold is - // increased sufficiently to reduce the number of buckets to or below - // NativeHistogramMaxBucketNumber, but not to more than - // NativeHistogramMaxZeroThreshold. Thus, if - // NativeHistogramMaxZeroThreshold is already at or below the current - // zero threshold, nothing happens at this step. - // - After that, if the number of buckets still exceeds - // NativeHistogramMaxBucketNumber, the resolution of the histogram is - // reduced by doubling the width of the sparse buckets (up to a - // growth factor between one bucket to the next of 2^(2^4) = 65536, - // see above). - // - Any increased zero threshold or reduced resolution is reset back - // to their original values once NativeHistogramMinResetDuration has - // passed (since the last reset or the creation of the histogram). - NativeHistogramMaxBucketNumber uint32 - NativeHistogramMinResetDuration time.Duration - NativeHistogramMaxZeroThreshold float64 - - // NativeHistogramMaxExemplars limits the number of exemplars - // that are kept in memory for each native histogram. If you leave it at - // zero, a default value of 10 is used. If no exemplars should be kept specifically - // for native histograms, set it to a negative value. (Scrapers can - // still use the exemplars exposed for classic buckets, which are managed - // independently.) - NativeHistogramMaxExemplars int - // NativeHistogramExemplarTTL is only checked once - // NativeHistogramMaxExemplars is exceeded. In that case, the - // oldest exemplar is removed if it is older than NativeHistogramExemplarTTL. - // Otherwise, the older exemplar in the pair of exemplars that are closest - // together (on an exponential scale) is removed. - // If NativeHistogramExemplarTTL is left at its zero value, a default value of - // 5m is used. To always delete the oldest exemplar, set it to a negative value. - NativeHistogramExemplarTTL time.Duration - - // now is for testing purposes, by default it's time.Now. - now func() time.Time - - // afterFunc is for testing purposes, by default it's time.AfterFunc. - afterFunc func(time.Duration, func()) *time.Timer -} - -// HistogramVecOpts bundles the options to create a HistogramVec metric. -// It is mandatory to set HistogramOpts, see there for mandatory fields. VariableLabels -// is optional and can safely be left to its default value. -type HistogramVecOpts struct { - HistogramOpts - - // VariableLabels are used to partition the metric vector by the given set - // of labels. Each label value will be constrained with the optional Constraint - // function, if provided. - VariableLabels ConstrainableLabels -} - -// NewHistogram creates a new Histogram based on the provided HistogramOpts. It -// panics if the buckets in HistogramOpts are not in strictly increasing order. -// -// The returned implementation also implements ExemplarObserver. It is safe to -// perform the corresponding type assertion. Exemplars are tracked separately -// for each bucket. -func NewHistogram(opts HistogramOpts) Histogram { - return newHistogram( - NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - nil, - opts.ConstLabels, - ), - opts, - ) -} - -func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogram { - if len(desc.variableLabels.names) != len(labelValues) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues)) - } - - for _, n := range desc.variableLabels.names { - if n == bucketLabel { - panic(errBucketLabelNotAllowed) - } - } - for _, lp := range desc.constLabelPairs { - if lp.GetName() == bucketLabel { - panic(errBucketLabelNotAllowed) - } - } - - if opts.now == nil { - opts.now = time.Now - } - if opts.afterFunc == nil { - opts.afterFunc = time.AfterFunc - } - - h := &histogram{ - desc: desc, - upperBounds: opts.Buckets, - labelPairs: MakeLabelPairs(desc, labelValues), - nativeHistogramMaxBuckets: opts.NativeHistogramMaxBucketNumber, - nativeHistogramMaxZeroThreshold: opts.NativeHistogramMaxZeroThreshold, - nativeHistogramMinResetDuration: opts.NativeHistogramMinResetDuration, - lastResetTime: opts.now(), - now: opts.now, - afterFunc: opts.afterFunc, - } - if len(h.upperBounds) == 0 && opts.NativeHistogramBucketFactor <= 1 { - h.upperBounds = DefBuckets - } - if opts.NativeHistogramBucketFactor <= 1 { - h.nativeHistogramSchema = math.MinInt32 // To mark that there are no sparse buckets. - } else { - switch { - case opts.NativeHistogramZeroThreshold > 0: - h.nativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold - case opts.NativeHistogramZeroThreshold == 0: - h.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold - } // Leave h.nativeHistogramZeroThreshold at 0 otherwise. - h.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor) - h.nativeExemplars = makeNativeExemplars(opts.NativeHistogramExemplarTTL, opts.NativeHistogramMaxExemplars) - } - for i, upperBound := range h.upperBounds { - if i < len(h.upperBounds)-1 { - if upperBound >= h.upperBounds[i+1] { - panic(fmt.Errorf( - "histogram buckets must be in increasing order: %f >= %f", - upperBound, h.upperBounds[i+1], - )) - } - } else { - if math.IsInf(upperBound, +1) { - // The +Inf bucket is implicit. Remove it here. - h.upperBounds = h.upperBounds[:i] - } - } - } - // Finally we know the final length of h.upperBounds and can make buckets - // for both counts as well as exemplars: - h.counts[0] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))} - atomic.StoreUint64(&h.counts[0].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) - atomic.StoreInt32(&h.counts[0].nativeHistogramSchema, h.nativeHistogramSchema) - h.counts[1] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))} - atomic.StoreUint64(&h.counts[1].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) - atomic.StoreInt32(&h.counts[1].nativeHistogramSchema, h.nativeHistogramSchema) - h.exemplars = make([]atomic.Value, len(h.upperBounds)+1) - - h.init(h) // Init self-collection. - return h -} - -type histogramCounts struct { - // Order in this struct matters for the alignment required by atomic - // operations, see http://golang.org/pkg/sync/atomic/#pkg-note-BUG - - // sumBits contains the bits of the float64 representing the sum of all - // observations. - sumBits uint64 - count uint64 - - // nativeHistogramZeroBucket counts all (positive and negative) - // observations in the zero bucket (with an absolute value less or equal - // the current threshold, see next field. - nativeHistogramZeroBucket uint64 - // nativeHistogramZeroThresholdBits is the bit pattern of the current - // threshold for the zero bucket. It's initially equal to - // nativeHistogramZeroThreshold but may change according to the bucket - // count limitation strategy. - nativeHistogramZeroThresholdBits uint64 - // nativeHistogramSchema may change over time according to the bucket - // count limitation strategy and therefore has to be saved here. - nativeHistogramSchema int32 - // Number of (positive and negative) sparse buckets. - nativeHistogramBucketsNumber uint32 - - // Regular buckets. - buckets []uint64 - - // The sparse buckets for native histograms are implemented with a - // sync.Map for now. A dedicated data structure will likely be more - // efficient. There are separate maps for negative and positive - // observations. The map's value is an *int64, counting observations in - // that bucket. (Note that we don't use uint64 as an int64 won't - // overflow in practice, and working with signed numbers from the - // beginning simplifies the handling of deltas.) The map's key is the - // index of the bucket according to the used - // nativeHistogramSchema. Index 0 is for an upper bound of 1. - nativeHistogramBucketsPositive, nativeHistogramBucketsNegative sync.Map -} - -// observe manages the parts of observe that only affects -// histogramCounts. doSparse is true if sparse buckets should be done, -// too. -func (hc *histogramCounts) observe(v float64, bucket int, doSparse bool) { - if bucket < len(hc.buckets) { - atomic.AddUint64(&hc.buckets[bucket], 1) - } - atomicAddFloat(&hc.sumBits, v) - if doSparse && !math.IsNaN(v) { - var ( - key int - schema = atomic.LoadInt32(&hc.nativeHistogramSchema) - zeroThreshold = math.Float64frombits(atomic.LoadUint64(&hc.nativeHistogramZeroThresholdBits)) - bucketCreated, isInf bool - ) - if math.IsInf(v, 0) { - // Pretend v is MaxFloat64 but later increment key by one. - if math.IsInf(v, +1) { - v = math.MaxFloat64 - } else { - v = -math.MaxFloat64 - } - isInf = true - } - frac, exp := math.Frexp(math.Abs(v)) - if schema > 0 { - bounds := nativeHistogramBounds[schema] - key = sort.SearchFloat64s(bounds, frac) + (exp-1)*len(bounds) - } else { - key = exp - if frac == 0.5 { - key-- - } - offset := (1 << -schema) - 1 - key = (key + offset) >> -schema - } - if isInf { - key++ - } - switch { - case v > zeroThreshold: - bucketCreated = addToBucket(&hc.nativeHistogramBucketsPositive, key, 1) - case v < -zeroThreshold: - bucketCreated = addToBucket(&hc.nativeHistogramBucketsNegative, key, 1) - default: - atomic.AddUint64(&hc.nativeHistogramZeroBucket, 1) - } - if bucketCreated { - atomic.AddUint32(&hc.nativeHistogramBucketsNumber, 1) - } - } - // Increment count last as we take it as a signal that the observation - // is complete. - atomic.AddUint64(&hc.count, 1) -} - -type histogram struct { - // countAndHotIdx enables lock-free writes with use of atomic updates. - // The most significant bit is the hot index [0 or 1] of the count field - // below. Observe calls update the hot one. All remaining bits count the - // number of Observe calls. Observe starts by incrementing this counter, - // and finish by incrementing the count field in the respective - // histogramCounts, as a marker for completion. - // - // Calls of the Write method (which are non-mutating reads from the - // perspective of the histogram) swap the hot–cold under the writeMtx - // lock. A cooldown is awaited (while locked) by comparing the number of - // observations with the initiation count. Once they match, then the - // last observation on the now cool one has completed. All cold fields must - // be merged into the new hot before releasing writeMtx. - // - // Fields with atomic access first! See alignment constraint: - // http://golang.org/pkg/sync/atomic/#pkg-note-BUG - countAndHotIdx uint64 - - selfCollector - desc *Desc - - // Only used in the Write method and for sparse bucket management. - mtx sync.Mutex - - // Two counts, one is "hot" for lock-free observations, the other is - // "cold" for writing out a dto.Metric. It has to be an array of - // pointers to guarantee 64bit alignment of the histogramCounts, see - // http://golang.org/pkg/sync/atomic/#pkg-note-BUG. - counts [2]*histogramCounts - - upperBounds []float64 - labelPairs []*dto.LabelPair - exemplars []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar. - nativeHistogramSchema int32 // The initial schema. Set to math.MinInt32 if no sparse buckets are used. - nativeHistogramZeroThreshold float64 // The initial zero threshold. - nativeHistogramMaxZeroThreshold float64 - nativeHistogramMaxBuckets uint32 - nativeHistogramMinResetDuration time.Duration - // lastResetTime is protected by mtx. It is also used as created timestamp. - lastResetTime time.Time - // resetScheduled is protected by mtx. It is true if a reset is - // scheduled for a later time (when nativeHistogramMinResetDuration has - // passed). - resetScheduled bool - nativeExemplars nativeExemplars - - // now is for testing purposes, by default it's time.Now. - now func() time.Time - - // afterFunc is for testing purposes, by default it's time.AfterFunc. - afterFunc func(time.Duration, func()) *time.Timer -} - -func (h *histogram) Desc() *Desc { - return h.desc -} - -func (h *histogram) Observe(v float64) { - h.observe(v, h.findBucket(v)) -} - -// ObserveWithExemplar should not be called in a high-frequency setting -// for a native histogram with configured exemplars. For this case, -// the implementation isn't lock-free and might suffer from lock contention. -func (h *histogram) ObserveWithExemplar(v float64, e Labels) { - i := h.findBucket(v) - h.observe(v, i) - h.updateExemplar(v, i, e) -} - -func (h *histogram) Write(out *dto.Metric) error { - // For simplicity, we protect this whole method by a mutex. It is not in - // the hot path, i.e. Observe is called much more often than Write. The - // complication of making Write lock-free isn't worth it, if possible at - // all. - h.mtx.Lock() - defer h.mtx.Unlock() - - // Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0) - // without touching the count bits. See the struct comments for a full - // description of the algorithm. - n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) - // count is contained unchanged in the lower 63 bits. - count := n & ((1 << 63) - 1) - // The most significant bit tells us which counts is hot. The complement - // is thus the cold one. - hotCounts := h.counts[n>>63] - coldCounts := h.counts[(^n)>>63] - - waitForCooldown(count, coldCounts) - - his := &dto.Histogram{ - Bucket: make([]*dto.Bucket, len(h.upperBounds)), - SampleCount: proto.Uint64(count), - SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))), - CreatedTimestamp: timestamppb.New(h.lastResetTime), - } - out.Histogram = his - out.Label = h.labelPairs - - var cumCount uint64 - for i, upperBound := range h.upperBounds { - cumCount += atomic.LoadUint64(&coldCounts.buckets[i]) - his.Bucket[i] = &dto.Bucket{ - CumulativeCount: proto.Uint64(cumCount), - UpperBound: proto.Float64(upperBound), - } - if e := h.exemplars[i].Load(); e != nil { - his.Bucket[i].Exemplar = e.(*dto.Exemplar) - } - } - // If there is an exemplar for the +Inf bucket, we have to add that bucket explicitly. - if e := h.exemplars[len(h.upperBounds)].Load(); e != nil { - b := &dto.Bucket{ - CumulativeCount: proto.Uint64(count), - UpperBound: proto.Float64(math.Inf(1)), - Exemplar: e.(*dto.Exemplar), - } - his.Bucket = append(his.Bucket, b) - } - if h.nativeHistogramSchema > math.MinInt32 { - his.ZeroThreshold = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.nativeHistogramZeroThresholdBits))) - his.Schema = proto.Int32(atomic.LoadInt32(&coldCounts.nativeHistogramSchema)) - zeroBucket := atomic.LoadUint64(&coldCounts.nativeHistogramZeroBucket) - - defer func() { - coldCounts.nativeHistogramBucketsPositive.Range(addAndReset(&hotCounts.nativeHistogramBucketsPositive, &hotCounts.nativeHistogramBucketsNumber)) - coldCounts.nativeHistogramBucketsNegative.Range(addAndReset(&hotCounts.nativeHistogramBucketsNegative, &hotCounts.nativeHistogramBucketsNumber)) - }() - - his.ZeroCount = proto.Uint64(zeroBucket) - his.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative) - his.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive) - - // Add a no-op span to a histogram without observations and with - // a zero threshold of zero. Otherwise, a native histogram would - // look like a classic histogram to scrapers. - if *his.ZeroThreshold == 0 && *his.ZeroCount == 0 && len(his.PositiveSpan) == 0 && len(his.NegativeSpan) == 0 { - his.PositiveSpan = []*dto.BucketSpan{{ - Offset: proto.Int32(0), - Length: proto.Uint32(0), - }} - } - - if h.nativeExemplars.isEnabled() { - h.nativeExemplars.Lock() - his.Exemplars = append(his.Exemplars, h.nativeExemplars.exemplars...) - h.nativeExemplars.Unlock() - } - - } - addAndResetCounts(hotCounts, coldCounts) - return nil -} - -// findBucket returns the index of the bucket for the provided value, or -// len(h.upperBounds) for the +Inf bucket. -func (h *histogram) findBucket(v float64) int { - n := len(h.upperBounds) - if n == 0 { - return 0 - } - - // Early exit: if v is less than or equal to the first upper bound, return 0 - if v <= h.upperBounds[0] { - return 0 - } - - // Early exit: if v is greater than the last upper bound, return len(h.upperBounds) - if v > h.upperBounds[n-1] { - return n - } - - // For small arrays, use simple linear search - // "magic number" 35 is result of tests on couple different (AWS and baremetal) servers - // see more details here: https://github.com/prometheus/client_golang/pull/1662 - if n < 35 { - for i, bound := range h.upperBounds { - if v <= bound { - return i - } - } - // If v is greater than all upper bounds, return len(h.upperBounds) - return n - } - - // For larger arrays, use stdlib's binary search - return sort.SearchFloat64s(h.upperBounds, v) -} - -// observe is the implementation for Observe without the findBucket part. -func (h *histogram) observe(v float64, bucket int) { - // Do not add to sparse buckets for NaN observations. - doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v) - // We increment h.countAndHotIdx so that the counter in the lower - // 63 bits gets incremented. At the same time, we get the new value - // back, which we can use to find the currently-hot counts. - n := atomic.AddUint64(&h.countAndHotIdx, 1) - hotCounts := h.counts[n>>63] - hotCounts.observe(v, bucket, doSparse) - if doSparse { - h.limitBuckets(hotCounts, v, bucket) - } -} - -// limitBuckets applies a strategy to limit the number of populated sparse -// buckets. It's generally best effort, and there are situations where the -// number can go higher (if even the lowest resolution isn't enough to reduce -// the number sufficiently, or if the provided counts aren't fully updated yet -// by a concurrently happening Write call). -func (h *histogram) limitBuckets(counts *histogramCounts, value float64, bucket int) { - if h.nativeHistogramMaxBuckets == 0 { - return // No limit configured. - } - if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&counts.nativeHistogramBucketsNumber) { - return // Bucket limit not exceeded yet. - } - - h.mtx.Lock() - defer h.mtx.Unlock() - - // The hot counts might have been swapped just before we acquired the - // lock. Re-fetch the hot counts first... - n := atomic.LoadUint64(&h.countAndHotIdx) - hotIdx := n >> 63 - coldIdx := (^n) >> 63 - hotCounts := h.counts[hotIdx] - coldCounts := h.counts[coldIdx] - // ...and then check again if we really have to reduce the bucket count. - if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&hotCounts.nativeHistogramBucketsNumber) { - return // Bucket limit not exceeded after all. - } - // Try the various strategies in order. - if h.maybeReset(hotCounts, coldCounts, coldIdx, value, bucket) { - return - } - // One of the other strategies will happen. To undo what they will do as - // soon as enough time has passed to satisfy - // h.nativeHistogramMinResetDuration, schedule a reset at the right time - // if we haven't done so already. - if h.nativeHistogramMinResetDuration > 0 && !h.resetScheduled { - h.resetScheduled = true - h.afterFunc(h.nativeHistogramMinResetDuration-h.now().Sub(h.lastResetTime), h.reset) - } - - if h.maybeWidenZeroBucket(hotCounts, coldCounts) { - return - } - h.doubleBucketWidth(hotCounts, coldCounts) -} - -// maybeReset resets the whole histogram if at least -// h.nativeHistogramMinResetDuration has been passed. It returns true if the -// histogram has been reset. The caller must have locked h.mtx. -func (h *histogram) maybeReset( - hot, cold *histogramCounts, coldIdx uint64, value float64, bucket int, -) bool { - // We are using the possibly mocked h.now() rather than - // time.Since(h.lastResetTime) to enable testing. - if h.nativeHistogramMinResetDuration == 0 || // No reset configured. - h.resetScheduled || // Do not interefere if a reset is already scheduled. - h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration { - return false - } - // Completely reset coldCounts. - h.resetCounts(cold) - // Repeat the latest observation to not lose it completely. - cold.observe(value, bucket, true) - // Make coldCounts the new hot counts while resetting countAndHotIdx. - n := atomic.SwapUint64(&h.countAndHotIdx, (coldIdx<<63)+1) - count := n & ((1 << 63) - 1) - waitForCooldown(count, hot) - // Finally, reset the formerly hot counts, too. - h.resetCounts(hot) - h.lastResetTime = h.now() - return true -} - -// reset resets the whole histogram. It locks h.mtx itself, i.e. it has to be -// called without having locked h.mtx. -func (h *histogram) reset() { - h.mtx.Lock() - defer h.mtx.Unlock() - - n := atomic.LoadUint64(&h.countAndHotIdx) - hotIdx := n >> 63 - coldIdx := (^n) >> 63 - hot := h.counts[hotIdx] - cold := h.counts[coldIdx] - // Completely reset coldCounts. - h.resetCounts(cold) - // Make coldCounts the new hot counts while resetting countAndHotIdx. - n = atomic.SwapUint64(&h.countAndHotIdx, coldIdx<<63) - count := n & ((1 << 63) - 1) - waitForCooldown(count, hot) - // Finally, reset the formerly hot counts, too. - h.resetCounts(hot) - h.lastResetTime = h.now() - h.resetScheduled = false -} - -// maybeWidenZeroBucket widens the zero bucket until it includes the existing -// buckets closest to the zero bucket (which could be two, if an equidistant -// negative and a positive bucket exists, but usually it's only one bucket to be -// merged into the new wider zero bucket). h.nativeHistogramMaxZeroThreshold -// limits how far the zero bucket can be extended, and if that's not enough to -// include an existing bucket, the method returns false. The caller must have -// locked h.mtx. -func (h *histogram) maybeWidenZeroBucket(hot, cold *histogramCounts) bool { - currentZeroThreshold := math.Float64frombits(atomic.LoadUint64(&hot.nativeHistogramZeroThresholdBits)) - if currentZeroThreshold >= h.nativeHistogramMaxZeroThreshold { - return false - } - // Find the key of the bucket closest to zero. - smallestKey := findSmallestKey(&hot.nativeHistogramBucketsPositive) - smallestNegativeKey := findSmallestKey(&hot.nativeHistogramBucketsNegative) - if smallestNegativeKey < smallestKey { - smallestKey = smallestNegativeKey - } - if smallestKey == math.MaxInt32 { - return false - } - newZeroThreshold := getLe(smallestKey, atomic.LoadInt32(&hot.nativeHistogramSchema)) - if newZeroThreshold > h.nativeHistogramMaxZeroThreshold { - return false // New threshold would exceed the max threshold. - } - atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold)) - // Remove applicable buckets. - if _, loaded := cold.nativeHistogramBucketsNegative.LoadAndDelete(smallestKey); loaded { - atomicDecUint32(&cold.nativeHistogramBucketsNumber) - } - if _, loaded := cold.nativeHistogramBucketsPositive.LoadAndDelete(smallestKey); loaded { - atomicDecUint32(&cold.nativeHistogramBucketsNumber) - } - // Make cold counts the new hot counts. - n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) - count := n & ((1 << 63) - 1) - // Swap the pointer names to represent the new roles and make - // the rest less confusing. - hot, cold = cold, hot - waitForCooldown(count, cold) - // Add all the now cold counts to the new hot counts... - addAndResetCounts(hot, cold) - // ...adjust the new zero threshold in the cold counts, too... - atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold)) - // ...and then merge the newly deleted buckets into the wider zero - // bucket. - mergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v interface{}) bool { - return func(k, v interface{}) bool { - key := k.(int) - bucket := v.(*int64) - if key == smallestKey { - // Merge into hot zero bucket... - atomic.AddUint64(&hot.nativeHistogramZeroBucket, uint64(atomic.LoadInt64(bucket))) - // ...and delete from cold counts. - coldBuckets.Delete(key) - atomicDecUint32(&cold.nativeHistogramBucketsNumber) - } else { - // Add to corresponding hot bucket... - if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) { - atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1) - } - // ...and reset cold bucket. - atomic.StoreInt64(bucket, 0) - } - return true - } - } - - cold.nativeHistogramBucketsPositive.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsPositive, &cold.nativeHistogramBucketsPositive)) - cold.nativeHistogramBucketsNegative.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsNegative, &cold.nativeHistogramBucketsNegative)) - return true -} - -// doubleBucketWidth doubles the bucket width (by decrementing the schema -// number). Note that very sparse buckets could lead to a low reduction of the -// bucket count (or even no reduction at all). The method does nothing if the -// schema is already -4. -func (h *histogram) doubleBucketWidth(hot, cold *histogramCounts) { - coldSchema := atomic.LoadInt32(&cold.nativeHistogramSchema) - if coldSchema == -4 { - return // Already at lowest resolution. - } - coldSchema-- - atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema) - // Play it simple and just delete all cold buckets. - atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0) - deleteSyncMap(&cold.nativeHistogramBucketsNegative) - deleteSyncMap(&cold.nativeHistogramBucketsPositive) - // Make coldCounts the new hot counts. - n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) - count := n & ((1 << 63) - 1) - // Swap the pointer names to represent the new roles and make - // the rest less confusing. - hot, cold = cold, hot - waitForCooldown(count, cold) - // Add all the now cold counts to the new hot counts... - addAndResetCounts(hot, cold) - // ...adjust the schema in the cold counts, too... - atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema) - // ...and then merge the cold buckets into the wider hot buckets. - merge := func(hotBuckets *sync.Map) func(k, v interface{}) bool { - return func(k, v interface{}) bool { - key := k.(int) - bucket := v.(*int64) - // Adjust key to match the bucket to merge into. - if key > 0 { - key++ - } - key /= 2 - // Add to corresponding hot bucket. - if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) { - atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1) - } - return true - } - } - - cold.nativeHistogramBucketsPositive.Range(merge(&hot.nativeHistogramBucketsPositive)) - cold.nativeHistogramBucketsNegative.Range(merge(&hot.nativeHistogramBucketsNegative)) - // Play it simple again and just delete all cold buckets. - atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0) - deleteSyncMap(&cold.nativeHistogramBucketsNegative) - deleteSyncMap(&cold.nativeHistogramBucketsPositive) -} - -func (h *histogram) resetCounts(counts *histogramCounts) { - atomic.StoreUint64(&counts.sumBits, 0) - atomic.StoreUint64(&counts.count, 0) - atomic.StoreUint64(&counts.nativeHistogramZeroBucket, 0) - atomic.StoreUint64(&counts.nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) - atomic.StoreInt32(&counts.nativeHistogramSchema, h.nativeHistogramSchema) - atomic.StoreUint32(&counts.nativeHistogramBucketsNumber, 0) - for i := range h.upperBounds { - atomic.StoreUint64(&counts.buckets[i], 0) - } - deleteSyncMap(&counts.nativeHistogramBucketsNegative) - deleteSyncMap(&counts.nativeHistogramBucketsPositive) -} - -// updateExemplar replaces the exemplar for the provided classic bucket. -// With empty labels, it's a no-op. It panics if any of the labels is invalid. -// If histogram is native, the exemplar will be cached into nativeExemplars, -// which has a limit, and will remove one exemplar when limit is reached. -func (h *histogram) updateExemplar(v float64, bucket int, l Labels) { - if l == nil { - return - } - e, err := newExemplar(v, h.now(), l) - if err != nil { - panic(err) - } - h.exemplars[bucket].Store(e) - doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v) - if doSparse { - h.nativeExemplars.addExemplar(e) - } -} - -// HistogramVec is a Collector that bundles a set of Histograms that all share the -// same Desc, but have different values for their variable labels. This is used -// if you want to count the same thing partitioned by various dimensions -// (e.g. HTTP request latencies, partitioned by status code and method). Create -// instances with NewHistogramVec. -type HistogramVec struct { - *MetricVec -} - -// NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and -// partitioned by the given label names. -func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { - return V2.NewHistogramVec(HistogramVecOpts{ - HistogramOpts: opts, - VariableLabels: UnconstrainedLabels(labelNames), - }) -} - -// NewHistogramVec creates a new HistogramVec based on the provided HistogramVecOpts. -func (v2) NewHistogramVec(opts HistogramVecOpts) *HistogramVec { - desc := V2.NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - opts.VariableLabels, - opts.ConstLabels, - ) - return &HistogramVec{ - MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { - return newHistogram(desc, opts.HistogramOpts, lvs...) - }), - } -} - -// GetMetricWithLabelValues returns the Histogram for the given slice of label -// values (same order as the variable labels in Desc). If that combination of -// label values is accessed for the first time, a new Histogram is created. -// -// It is possible to call this method without using the returned Histogram to only -// create the new Histogram but leave it at its starting value, a Histogram without -// any observations. -// -// Keeping the Histogram for later use is possible (and should be considered if -// performance is critical), but keep in mind that Reset, DeleteLabelValues and -// Delete can be used to delete the Histogram from the HistogramVec. In that case, the -// Histogram will still exist, but it will not be exported anymore, even if a -// Histogram with the same label values is created later. See also the CounterVec -// example. -// -// An error is returned if the number of label values is not the same as the -// number of variable labels in Desc (minus any curried labels). -// -// Note that for more than one label value, this method is prone to mistakes -// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as -// an alternative to avoid that type of mistake. For higher label numbers, the -// latter has a much more readable (albeit more verbose) syntax, but it comes -// with a performance overhead (for creating and processing the Labels map). -// See also the GaugeVec example. -func (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { - metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) - if metric != nil { - return metric.(Observer), err - } - return nil, err -} - -// GetMetricWith returns the Histogram for the given Labels map (the label names -// must match those of the variable labels in Desc). If that label map is -// accessed for the first time, a new Histogram is created. Implications of -// creating a Histogram without using it and keeping the Histogram for later use -// are the same as for GetMetricWithLabelValues. -// -// An error is returned if the number and names of the Labels are inconsistent -// with those of the variable labels in Desc (minus any curried labels). -// -// This method is used for the same purpose as -// GetMetricWithLabelValues(...string). See there for pros and cons of the two -// methods. -func (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error) { - metric, err := v.MetricVec.GetMetricWith(labels) - if metric != nil { - return metric.(Observer), err - } - return nil, err -} - -// WithLabelValues works as GetMetricWithLabelValues, but panics where -// GetMetricWithLabelValues would have returned an error. Not returning an -// error allows shortcuts like -// -// myVec.WithLabelValues("404", "GET").Observe(42.21) -func (v *HistogramVec) WithLabelValues(lvs ...string) Observer { - h, err := v.GetMetricWithLabelValues(lvs...) - if err != nil { - panic(err) - } - return h -} - -// With works as GetMetricWith but panics where GetMetricWithLabels would have -// returned an error. Not returning an error allows shortcuts like -// -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) -func (v *HistogramVec) With(labels Labels) Observer { - h, err := v.GetMetricWith(labels) - if err != nil { - panic(err) - } - return h -} - -// CurryWith returns a vector curried with the provided labels, i.e. the -// returned vector has those labels pre-set for all labeled operations performed -// on it. The cardinality of the curried vector is reduced accordingly. The -// order of the remaining labels stays the same (just with the curried labels -// taken out of the sequence – which is relevant for the -// (GetMetric)WithLabelValues methods). It is possible to curry a curried -// vector, but only with labels not yet used for currying before. -// -// The metrics contained in the HistogramVec are shared between the curried and -// uncurried vectors. They are just accessed differently. Curried and uncurried -// vectors behave identically in terms of collection. Only one must be -// registered with a given registry (usually the uncurried version). The Reset -// method deletes all metrics, even if called on a curried vector. -func (v *HistogramVec) CurryWith(labels Labels) (ObserverVec, error) { - vec, err := v.MetricVec.CurryWith(labels) - if vec != nil { - return &HistogramVec{vec}, err - } - return nil, err -} - -// MustCurryWith works as CurryWith but panics where CurryWith would have -// returned an error. -func (v *HistogramVec) MustCurryWith(labels Labels) ObserverVec { - vec, err := v.CurryWith(labels) - if err != nil { - panic(err) - } - return vec -} - -type constHistogram struct { - desc *Desc - count uint64 - sum float64 - buckets map[float64]uint64 - labelPairs []*dto.LabelPair - createdTs *timestamppb.Timestamp -} - -func (h *constHistogram) Desc() *Desc { - return h.desc -} - -func (h *constHistogram) Write(out *dto.Metric) error { - his := &dto.Histogram{ - CreatedTimestamp: h.createdTs, - } - - buckets := make([]*dto.Bucket, 0, len(h.buckets)) - - his.SampleCount = proto.Uint64(h.count) - his.SampleSum = proto.Float64(h.sum) - for upperBound, count := range h.buckets { - buckets = append(buckets, &dto.Bucket{ - CumulativeCount: proto.Uint64(count), - UpperBound: proto.Float64(upperBound), - }) - } - - if len(buckets) > 0 { - sort.Sort(buckSort(buckets)) - } - his.Bucket = buckets - - out.Histogram = his - out.Label = h.labelPairs - - return nil -} - -// NewConstHistogram returns a metric representing a Prometheus histogram with -// fixed values for the count, sum, and bucket counts. As those parameters -// cannot be changed, the returned value does not implement the Histogram -// interface (but only the Metric interface). Users of this package will not -// have much use for it in regular operations. However, when implementing custom -// Collectors, it is useful as a throw-away metric that is generated on the fly -// to send it to Prometheus in the Collect method. -// -// buckets is a map of upper bounds to cumulative counts, excluding the +Inf -// bucket. The +Inf bucket is implicit, and its value is equal to the provided count. -// -// NewConstHistogram returns an error if the length of labelValues is not -// consistent with the variable labels in Desc or if Desc is invalid. -func NewConstHistogram( - desc *Desc, - count uint64, - sum float64, - buckets map[float64]uint64, - labelValues ...string, -) (Metric, error) { - if desc.err != nil { - return nil, desc.err - } - if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { - return nil, err - } - return &constHistogram{ - desc: desc, - count: count, - sum: sum, - buckets: buckets, - labelPairs: MakeLabelPairs(desc, labelValues), - }, nil -} - -// MustNewConstHistogram is a version of NewConstHistogram that panics where -// NewConstHistogram would have returned an error. -func MustNewConstHistogram( - desc *Desc, - count uint64, - sum float64, - buckets map[float64]uint64, - labelValues ...string, -) Metric { - m, err := NewConstHistogram(desc, count, sum, buckets, labelValues...) - if err != nil { - panic(err) - } - return m -} - -// NewConstHistogramWithCreatedTimestamp does the same thing as NewConstHistogram but sets the created timestamp. -func NewConstHistogramWithCreatedTimestamp( - desc *Desc, - count uint64, - sum float64, - buckets map[float64]uint64, - ct time.Time, - labelValues ...string, -) (Metric, error) { - if desc.err != nil { - return nil, desc.err - } - if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { - return nil, err - } - return &constHistogram{ - desc: desc, - count: count, - sum: sum, - buckets: buckets, - labelPairs: MakeLabelPairs(desc, labelValues), - createdTs: timestamppb.New(ct), - }, nil -} - -// MustNewConstHistogramWithCreatedTimestamp is a version of NewConstHistogramWithCreatedTimestamp that panics where -// NewConstHistogramWithCreatedTimestamp would have returned an error. -func MustNewConstHistogramWithCreatedTimestamp( - desc *Desc, - count uint64, - sum float64, - buckets map[float64]uint64, - ct time.Time, - labelValues ...string, -) Metric { - m, err := NewConstHistogramWithCreatedTimestamp(desc, count, sum, buckets, ct, labelValues...) - if err != nil { - panic(err) - } - return m -} - -type buckSort []*dto.Bucket - -func (s buckSort) Len() int { - return len(s) -} - -func (s buckSort) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s buckSort) Less(i, j int) bool { - return s[i].GetUpperBound() < s[j].GetUpperBound() -} - -// pickSchema returns the largest number n between -4 and 8 such that -// 2^(2^-n) is less or equal the provided bucketFactor. -// -// Special cases: -// - bucketFactor <= 1: panics. -// - bucketFactor < 2^(2^-8) (but > 1): still returns 8. -func pickSchema(bucketFactor float64) int32 { - if bucketFactor <= 1 { - panic(fmt.Errorf("bucketFactor %f is <=1", bucketFactor)) - } - floor := math.Floor(math.Log2(math.Log2(bucketFactor))) - switch { - case floor <= -8: - return nativeHistogramSchemaMaximum - case floor >= 4: - return nativeHistogramSchemaMinimum - default: - return -int32(floor) - } -} - -func makeBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) { - var ii []int - buckets.Range(func(k, v interface{}) bool { - ii = append(ii, k.(int)) - return true - }) - sort.Ints(ii) - - if len(ii) == 0 { - return nil, nil - } - - var ( - spans []*dto.BucketSpan - deltas []int64 - prevCount int64 - nextI int - ) - - appendDelta := func(count int64) { - *spans[len(spans)-1].Length++ - deltas = append(deltas, count-prevCount) - prevCount = count - } - - for n, i := range ii { - v, _ := buckets.Load(i) - count := atomic.LoadInt64(v.(*int64)) - // Multiple spans with only small gaps in between are probably - // encoded more efficiently as one larger span with a few empty - // buckets. Needs some research to find the sweet spot. For now, - // we assume that gaps of one or two buckets should not create - // a new span. - iDelta := int32(i - nextI) - if n == 0 || iDelta > 2 { - // We have to create a new span, either because we are - // at the very beginning, or because we have found a gap - // of more than two buckets. - spans = append(spans, &dto.BucketSpan{ - Offset: proto.Int32(iDelta), - Length: proto.Uint32(0), - }) - } else { - // We have found a small gap (or no gap at all). - // Insert empty buckets as needed. - for j := int32(0); j < iDelta; j++ { - appendDelta(0) - } - } - appendDelta(count) - nextI = i + 1 - } - return spans, deltas -} - -// addToBucket increments the sparse bucket at key by the provided amount. It -// returns true if a new sparse bucket had to be created for that. -func addToBucket(buckets *sync.Map, key int, increment int64) bool { - if existingBucket, ok := buckets.Load(key); ok { - // Fast path without allocation. - atomic.AddInt64(existingBucket.(*int64), increment) - return false - } - // Bucket doesn't exist yet. Slow path allocating new counter. - newBucket := increment // TODO(beorn7): Check if this is sufficient to not let increment escape. - if actualBucket, loaded := buckets.LoadOrStore(key, &newBucket); loaded { - // The bucket was created concurrently in another goroutine. - // Have to increment after all. - atomic.AddInt64(actualBucket.(*int64), increment) - return false - } - return true -} - -// addAndReset returns a function to be used with sync.Map.Range of spare -// buckets in coldCounts. It increments the buckets in the provided hotBuckets -// according to the buckets ranged through. It then resets all buckets ranged -// through to 0 (but leaves them in place so that they don't need to get -// recreated on the next scrape). -func addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v interface{}) bool { - return func(k, v interface{}) bool { - bucket := v.(*int64) - if addToBucket(hotBuckets, k.(int), atomic.LoadInt64(bucket)) { - atomic.AddUint32(bucketNumber, 1) - } - atomic.StoreInt64(bucket, 0) - return true - } -} - -func deleteSyncMap(m *sync.Map) { - m.Range(func(k, v interface{}) bool { - m.Delete(k) - return true - }) -} - -func findSmallestKey(m *sync.Map) int { - result := math.MaxInt32 - m.Range(func(k, v interface{}) bool { - key := k.(int) - if key < result { - result = key - } - return true - }) - return result -} - -func getLe(key int, schema int32) float64 { - // Here a bit of context about the behavior for the last bucket counting - // regular numbers (called simply "last bucket" below) and the bucket - // counting observations of ±Inf (called "inf bucket" below, with a key - // one higher than that of the "last bucket"): - // - // If we apply the usual formula to the last bucket, its upper bound - // would be calculated as +Inf. The reason is that the max possible - // regular float64 number (math.MaxFloat64) doesn't coincide with one of - // the calculated bucket boundaries. So the calculated boundary has to - // be larger than math.MaxFloat64, and the only float64 larger than - // math.MaxFloat64 is +Inf. However, we want to count actual - // observations of ±Inf in the inf bucket. Therefore, we have to treat - // the upper bound of the last bucket specially and set it to - // math.MaxFloat64. (The upper bound of the inf bucket, with its key - // being one higher than that of the last bucket, naturally comes out as - // +Inf by the usual formula. So that's fine.) - // - // math.MaxFloat64 has a frac of 0.9999999999999999 and an exp of - // 1024. If there were a float64 number following math.MaxFloat64, it - // would have a frac of 1.0 and an exp of 1024, or equivalently a frac - // of 0.5 and an exp of 1025. However, since frac must be smaller than - // 1, and exp must be smaller than 1025, either representation overflows - // a float64. (Which, in turn, is the reason that math.MaxFloat64 is the - // largest possible float64. Q.E.D.) However, the formula for - // calculating the upper bound from the idx and schema of the last - // bucket results in precisely that. It is either frac=1.0 & exp=1024 - // (for schema < 0) or frac=0.5 & exp=1025 (for schema >=0). (This is, - // by the way, a power of two where the exponent itself is a power of - // two, 2¹⁰ in fact, which coinicides with a bucket boundary in all - // schemas.) So these are the special cases we have to catch below. - if schema < 0 { - exp := key << -schema - if exp == 1024 { - // This is the last bucket before the overflow bucket - // (for ±Inf observations). Return math.MaxFloat64 as - // explained above. - return math.MaxFloat64 - } - return math.Ldexp(1, exp) - } - - fracIdx := key & ((1 << schema) - 1) - frac := nativeHistogramBounds[schema][fracIdx] - exp := (key >> schema) + 1 - if frac == 0.5 && exp == 1025 { - // This is the last bucket before the overflow bucket (for ±Inf - // observations). Return math.MaxFloat64 as explained above. - return math.MaxFloat64 - } - return math.Ldexp(frac, exp) -} - -// waitForCooldown returns after the count field in the provided histogramCounts -// has reached the provided count value. -func waitForCooldown(count uint64, counts *histogramCounts) { - for count != atomic.LoadUint64(&counts.count) { - runtime.Gosched() // Let observations get work done. - } -} - -// atomicAddFloat adds the provided float atomically to another float -// represented by the bit pattern the bits pointer is pointing to. -func atomicAddFloat(bits *uint64, v float64) { - for { - loadedBits := atomic.LoadUint64(bits) - newBits := math.Float64bits(math.Float64frombits(loadedBits) + v) - if atomic.CompareAndSwapUint64(bits, loadedBits, newBits) { - break - } - } -} - -// atomicDecUint32 atomically decrements the uint32 p points to. See -// https://pkg.go.dev/sync/atomic#AddUint32 to understand how this is done. -func atomicDecUint32(p *uint32) { - atomic.AddUint32(p, ^uint32(0)) -} - -// addAndResetCounts adds certain fields (count, sum, conventional buckets, zero -// bucket) from the cold counts to the corresponding fields in the hot -// counts. Those fields are then reset to 0 in the cold counts. -func addAndResetCounts(hot, cold *histogramCounts) { - atomic.AddUint64(&hot.count, atomic.LoadUint64(&cold.count)) - atomic.StoreUint64(&cold.count, 0) - coldSum := math.Float64frombits(atomic.LoadUint64(&cold.sumBits)) - atomicAddFloat(&hot.sumBits, coldSum) - atomic.StoreUint64(&cold.sumBits, 0) - for i := range hot.buckets { - atomic.AddUint64(&hot.buckets[i], atomic.LoadUint64(&cold.buckets[i])) - atomic.StoreUint64(&cold.buckets[i], 0) - } - atomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket)) - atomic.StoreUint64(&cold.nativeHistogramZeroBucket, 0) -} - -type nativeExemplars struct { - sync.Mutex - - // Time-to-live for exemplars, it is set to -1 if exemplars are disabled, that is NativeHistogramMaxExemplars is below 0. - // The ttl is used on insertion to remove an exemplar that is older than ttl, if present. - ttl time.Duration - - exemplars []*dto.Exemplar -} - -func (n *nativeExemplars) isEnabled() bool { - return n.ttl != -1 -} - -func makeNativeExemplars(ttl time.Duration, maxCount int) nativeExemplars { - if ttl == 0 { - ttl = 5 * time.Minute - } - - if maxCount == 0 { - maxCount = 10 - } - - if maxCount < 0 { - maxCount = 0 - ttl = -1 - } - - return nativeExemplars{ - ttl: ttl, - exemplars: make([]*dto.Exemplar, 0, maxCount), - } -} - -func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { - if !n.isEnabled() { - return - } - - n.Lock() - defer n.Unlock() - - // When the number of exemplars has not yet exceeded or - // is equal to cap(n.exemplars), then - // insert the new exemplar directly. - if len(n.exemplars) < cap(n.exemplars) { - var nIdx int - for nIdx = 0; nIdx < len(n.exemplars); nIdx++ { - if *e.Value < *n.exemplars[nIdx].Value { - break - } - } - n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...) - return - } - - if len(n.exemplars) == 1 { - // When the number of exemplars is 1, then - // replace the existing exemplar with the new exemplar. - n.exemplars[0] = e - return - } - // From this point on, the number of exemplars is greater than 1. - - // When the number of exemplars exceeds the limit, remove one exemplar. - var ( - ot = time.Time{} // Oldest timestamp seen. Initial value doesn't matter as we replace it due to otIdx == -1 in the loop. - otIdx = -1 // Index of the exemplar with the oldest timestamp. - - md = -1.0 // Logarithm of the delta of the closest pair of exemplars. - - // The insertion point of the new exemplar in the exemplars slice after insertion. - // This is calculated purely based on the order of the exemplars by value. - // nIdx == len(n.exemplars) means the new exemplar is to be inserted after the end. - nIdx = -1 - - // rIdx is ultimately the index for the exemplar that we are replacing with the new exemplar. - // The aim is to keep a good spread of exemplars by value and not let them bunch up too much. - // It is calculated in 3 steps: - // 1. First we set rIdx to the index of the older exemplar within the closest pair by value. - // That is the following will be true (on log scale): - // either the exemplar pair on index (rIdx-1, rIdx) or (rIdx, rIdx+1) will have - // the closest values to each other from all pairs. - // For example, suppose the values are distributed like this: - // |-----------x-------------x----------------x----x-----| - // ^--rIdx as this is older. - // Or like this: - // |-----------x-------------x----------------x----x-----| - // ^--rIdx as this is older. - // 2. If there is an exemplar that expired, then we simple reset rIdx to that index. - // 3. We check if by inserting the new exemplar we would create a closer pair at - // (nIdx-1, nIdx) or (nIdx, nIdx+1) and set rIdx to nIdx-1 or nIdx accordingly to - // keep the spread of exemplars by value; otherwise we keep rIdx as it is. - rIdx = -1 - cLog float64 // Logarithm of the current exemplar. - pLog float64 // Logarithm of the previous exemplar. - ) - - for i, exemplar := range n.exemplars { - // Find the exemplar with the oldest timestamp. - if otIdx == -1 || exemplar.Timestamp.AsTime().Before(ot) { - ot = exemplar.Timestamp.AsTime() - otIdx = i - } - - // Find the index at which to insert new the exemplar. - if nIdx == -1 && *e.Value <= *exemplar.Value { - nIdx = i - } - - // Find the two closest exemplars and pick the one the with older timestamp. - pLog = cLog - cLog = math.Log(exemplar.GetValue()) - if i == 0 { - continue - } - diff := math.Abs(cLog - pLog) - if md == -1 || diff < md { - // The closest exemplar pair is at index: i-1, i. - // Choose the exemplar with the older timestamp for replacement. - md = diff - if n.exemplars[i].Timestamp.AsTime().Before(n.exemplars[i-1].Timestamp.AsTime()) { - rIdx = i - } else { - rIdx = i - 1 - } - } - - } - - // If all existing exemplar are smaller than new exemplar, - // then the exemplar should be inserted at the end. - if nIdx == -1 { - nIdx = len(n.exemplars) - } - // Here, we have the following relationships: - // n.exemplars[nIdx-1].Value < e.Value (if nIdx > 0) - // e.Value <= n.exemplars[nIdx].Value (if nIdx < len(n.exemplars)) - - if otIdx != -1 && e.Timestamp.AsTime().Sub(ot) > n.ttl { - // If the oldest exemplar has expired, then replace it with the new exemplar. - rIdx = otIdx - } else { - // In the previous for loop, when calculating the closest pair of exemplars, - // we did not take into account the newly inserted exemplar. - // So we need to calculate with the newly inserted exemplar again. - elog := math.Log(e.GetValue()) - if nIdx > 0 { - diff := math.Abs(elog - math.Log(n.exemplars[nIdx-1].GetValue())) - if diff < md { - // The value we are about to insert is closer to the previous exemplar at the insertion point than what we calculated before in rIdx. - // v--rIdx - // |-----------x-n-----------x----------------x----x-----| - // nIdx-1--^ ^--new exemplar value - // Do not make the spread worse, replace nIdx-1 and not rIdx. - md = diff - rIdx = nIdx - 1 - } - } - if nIdx < len(n.exemplars) { - diff := math.Abs(math.Log(n.exemplars[nIdx].GetValue()) - elog) - if diff < md { - // The value we are about to insert is closer to the next exemplar at the insertion point than what we calculated before in rIdx. - // v--rIdx - // |-----------x-----------n-x----------------x----x-----| - // new exemplar value--^ ^--nIdx - // Do not make the spread worse, replace nIdx-1 and not rIdx. - rIdx = nIdx - } - } - } - - // Adjust the slice according to rIdx and nIdx. - switch { - case rIdx == nIdx: - n.exemplars[nIdx] = e - case rIdx < nIdx: - n.exemplars = append(n.exemplars[:rIdx], append(n.exemplars[rIdx+1:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...)...) - case rIdx > nIdx: - n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, append(n.exemplars[nIdx:rIdx], n.exemplars[rIdx+1:]...)...)...) - } -} - -type constNativeHistogram struct { - desc *Desc - dto.Histogram - labelPairs []*dto.LabelPair -} - -func validateCount(sum float64, count uint64, negativeBuckets, positiveBuckets map[int]int64, zeroBucket uint64) error { - var bucketPopulationSum int64 - for _, v := range positiveBuckets { - bucketPopulationSum += v - } - for _, v := range negativeBuckets { - bucketPopulationSum += v - } - bucketPopulationSum += int64(zeroBucket) - - // If the sum of observations is NaN, the number of observations must be greater or equal to the sum of all bucket counts. - // Otherwise, the number of observations must be equal to the sum of all bucket counts . - - if math.IsNaN(sum) && bucketPopulationSum > int64(count) || - !math.IsNaN(sum) && bucketPopulationSum != int64(count) { - return errors.New("the sum of all bucket populations exceeds the count of observations") - } - return nil -} - -// NewConstNativeHistogram returns a metric representing a Prometheus native histogram with -// fixed values for the count, sum, and positive/negative/zero bucket counts. As those parameters -// cannot be changed, the returned value does not implement the Histogram -// interface (but only the Metric interface). Users of this package will not -// have much use for it in regular operations. However, when implementing custom -// OpenTelemetry Collectors, it is useful as a throw-away metric that is generated on the fly -// to send it to Prometheus in the Collect method. -// -// zeroBucket counts all (positive and negative) -// observations in the zero bucket (with an absolute value less or equal -// the current threshold). -// positiveBuckets and negativeBuckets are separate maps for negative and positive -// observations. The map's value is an int64, counting observations in -// that bucket. The map's key is the -// index of the bucket according to the used -// Schema. Index 0 is for an upper bound of 1 in positive buckets and for a lower bound of -1 in negative buckets. -// NewConstNativeHistogram returns an error if -// - the length of labelValues is not consistent with the variable labels in Desc or if Desc is invalid. -// - the schema passed is not between 8 and -4 -// - the sum of counts in all buckets including the zero bucket does not equal the count if sum is not NaN (or exceeds the count if sum is NaN) -// -// See https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/#exponential-histograms for more details about the conversion from OTel to Prometheus. -func NewConstNativeHistogram( - desc *Desc, - count uint64, - sum float64, - positiveBuckets, negativeBuckets map[int]int64, - zeroBucket uint64, - schema int32, - zeroThreshold float64, - createdTimestamp time.Time, - labelValues ...string, -) (Metric, error) { - if desc.err != nil { - return nil, desc.err - } - if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { - return nil, err - } - if schema > nativeHistogramSchemaMaximum || schema < nativeHistogramSchemaMinimum { - return nil, errors.New("invalid native histogram schema") - } - if err := validateCount(sum, count, negativeBuckets, positiveBuckets, zeroBucket); err != nil { - return nil, err - } - - NegativeSpan, NegativeDelta := makeBucketsFromMap(negativeBuckets) - PositiveSpan, PositiveDelta := makeBucketsFromMap(positiveBuckets) - ret := &constNativeHistogram{ - desc: desc, - Histogram: dto.Histogram{ - CreatedTimestamp: timestamppb.New(createdTimestamp), - Schema: &schema, - ZeroThreshold: &zeroThreshold, - SampleCount: &count, - SampleSum: &sum, - - NegativeSpan: NegativeSpan, - NegativeDelta: NegativeDelta, - - PositiveSpan: PositiveSpan, - PositiveDelta: PositiveDelta, - - ZeroCount: proto.Uint64(zeroBucket), - }, - labelPairs: MakeLabelPairs(desc, labelValues), - } - if *ret.ZeroThreshold == 0 && *ret.ZeroCount == 0 && len(ret.PositiveSpan) == 0 && len(ret.NegativeSpan) == 0 { - ret.PositiveSpan = []*dto.BucketSpan{{ - Offset: proto.Int32(0), - Length: proto.Uint32(0), - }} - } - return ret, nil -} - -// MustNewConstNativeHistogram is a version of NewConstNativeHistogram that panics where -// NewConstNativeHistogram would have returned an error. -func MustNewConstNativeHistogram( - desc *Desc, - count uint64, - sum float64, - positiveBuckets, negativeBuckets map[int]int64, - zeroBucket uint64, - nativeHistogramSchema int32, - nativeHistogramZeroThreshold float64, - createdTimestamp time.Time, - labelValues ...string, -) Metric { - nativehistogram, err := NewConstNativeHistogram(desc, - count, - sum, - positiveBuckets, - negativeBuckets, - zeroBucket, - nativeHistogramSchema, - nativeHistogramZeroThreshold, - createdTimestamp, - labelValues...) - if err != nil { - panic(err) - } - return nativehistogram -} - -func (h *constNativeHistogram) Desc() *Desc { - return h.desc -} - -func (h *constNativeHistogram) Write(out *dto.Metric) error { - out.Histogram = &h.Histogram - out.Label = h.labelPairs - return nil -} - -func makeBucketsFromMap(buckets map[int]int64) ([]*dto.BucketSpan, []int64) { - if len(buckets) == 0 { - return nil, nil - } - var ii []int - for k := range buckets { - ii = append(ii, k) - } - sort.Ints(ii) - - var ( - spans []*dto.BucketSpan - deltas []int64 - prevCount int64 - nextI int - ) - - appendDelta := func(count int64) { - *spans[len(spans)-1].Length++ - deltas = append(deltas, count-prevCount) - prevCount = count - } - - for n, i := range ii { - count := buckets[i] - // Multiple spans with only small gaps in between are probably - // encoded more efficiently as one larger span with a few empty - // buckets. Needs some research to find the sweet spot. For now, - // we assume that gaps of one or two buckets should not create - // a new span. - iDelta := int32(i - nextI) - if n == 0 || iDelta > 2 { - // We have to create a new span, either because we are - // at the very beginning, or because we have found a gap - // of more than two buckets. - spans = append(spans, &dto.BucketSpan{ - Offset: proto.Int32(iDelta), - Length: proto.Uint32(0), - }) - } else { - // We have found a small gap (or no gap at all). - // Insert empty buckets as needed. - for j := int32(0); j < iDelta; j++ { - appendDelta(0) - } - } - appendDelta(count) - nextI = i + 1 - } - return spans, deltas -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go deleted file mode 100644 index 1ed5abe74c16..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2015 Björn Rabenstein -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// The code in this package is copy/paste to avoid a dependency. Hence this file -// carries the copyright of the original repo. -// https://github.com/beorn7/floats -package internal - -import ( - "math" -) - -// minNormalFloat64 is the smallest positive normal value of type float64. -var minNormalFloat64 = math.Float64frombits(0x0010000000000000) - -// AlmostEqualFloat64 returns true if a and b are equal within a relative error -// of epsilon. See http://floating-point-gui.de/errors/comparison/ for the -// details of the applied method. -func AlmostEqualFloat64(a, b, epsilon float64) bool { - if a == b { - return true - } - absA := math.Abs(a) - absB := math.Abs(b) - diff := math.Abs(a - b) - if a == 0 || b == 0 || absA+absB < minNormalFloat64 { - return diff < epsilon*minNormalFloat64 - } - return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon -} - -// AlmostEqualFloat64s is the slice form of AlmostEqualFloat64. -func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool { - if len(a) != len(b) { - return false - } - for i := range a { - if !AlmostEqualFloat64(a[i], b[i], epsilon) { - return false - } - } - return true -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go deleted file mode 100644 index 7bac0da33df7..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go +++ /dev/null @@ -1,655 +0,0 @@ -// Copyright 2022 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// It provides tools to compare sequences of strings and generate textual diffs. -// -// Maintaining `GetUnifiedDiffString` here because original repository -// (https://github.com/pmezard/go-difflib) is no longer maintained. -package internal - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" -) - -func minInt(a, b int) int { - if a < b { - return a - } - return b -} - -func maxInt(a, b int) int { - if a > b { - return a - } - return b -} - -func calculateRatio(matches, length int) float64 { - if length > 0 { - return 2.0 * float64(matches) / float64(length) - } - return 1.0 -} - -type Match struct { - A int - B int - Size int -} - -type OpCode struct { - Tag byte - I1 int - I2 int - J1 int - J2 int -} - -// SequenceMatcher compares sequence of strings. The basic -// algorithm predates, and is a little fancier than, an algorithm -// published in the late 1980's by Ratcliff and Obershelp under the -// hyperbolic name "gestalt pattern matching". The basic idea is to find -// the longest contiguous matching subsequence that contains no "junk" -// elements (R-O doesn't address junk). The same idea is then applied -// recursively to the pieces of the sequences to the left and to the right -// of the matching subsequence. This does not yield minimal edit -// sequences, but does tend to yield matches that "look right" to people. -// -// SequenceMatcher tries to compute a "human-friendly diff" between two -// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the -// longest *contiguous* & junk-free matching subsequence. That's what -// catches peoples' eyes. The Windows(tm) windiff has another interesting -// notion, pairing up elements that appear uniquely in each sequence. -// That, and the method here, appear to yield more intuitive difference -// reports than does diff. This method appears to be the least vulnerable -// to synching up on blocks of "junk lines", though (like blank lines in -// ordinary text files, or maybe "

" lines in HTML files). That may be -// because this is the only method of the 3 that has a *concept* of -// "junk" . -// -// Timing: Basic R-O is cubic time worst case and quadratic time expected -// case. SequenceMatcher is quadratic time for the worst case and has -// expected-case behavior dependent in a complicated way on how many -// elements the sequences have in common; best case time is linear. -type SequenceMatcher struct { - a []string - b []string - b2j map[string][]int - IsJunk func(string) bool - autoJunk bool - bJunk map[string]struct{} - matchingBlocks []Match - fullBCount map[string]int - bPopular map[string]struct{} - opCodes []OpCode -} - -func NewMatcher(a, b []string) *SequenceMatcher { - m := SequenceMatcher{autoJunk: true} - m.SetSeqs(a, b) - return &m -} - -func NewMatcherWithJunk(a, b []string, autoJunk bool, - isJunk func(string) bool, -) *SequenceMatcher { - m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} - m.SetSeqs(a, b) - return &m -} - -// Set two sequences to be compared. -func (m *SequenceMatcher) SetSeqs(a, b []string) { - m.SetSeq1(a) - m.SetSeq2(b) -} - -// Set the first sequence to be compared. The second sequence to be compared is -// not changed. -// -// SequenceMatcher computes and caches detailed information about the second -// sequence, so if you want to compare one sequence S against many sequences, -// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other -// sequences. -// -// See also SetSeqs() and SetSeq2(). -func (m *SequenceMatcher) SetSeq1(a []string) { - if &a == &m.a { - return - } - m.a = a - m.matchingBlocks = nil - m.opCodes = nil -} - -// Set the second sequence to be compared. The first sequence to be compared is -// not changed. -func (m *SequenceMatcher) SetSeq2(b []string) { - if &b == &m.b { - return - } - m.b = b - m.matchingBlocks = nil - m.opCodes = nil - m.fullBCount = nil - m.chainB() -} - -func (m *SequenceMatcher) chainB() { - // Populate line -> index mapping - b2j := map[string][]int{} - for i, s := range m.b { - indices := b2j[s] - indices = append(indices, i) - b2j[s] = indices - } - - // Purge junk elements - m.bJunk = map[string]struct{}{} - if m.IsJunk != nil { - junk := m.bJunk - for s := range b2j { - if m.IsJunk(s) { - junk[s] = struct{}{} - } - } - for s := range junk { - delete(b2j, s) - } - } - - // Purge remaining popular elements - popular := map[string]struct{}{} - n := len(m.b) - if m.autoJunk && n >= 200 { - ntest := n/100 + 1 - for s, indices := range b2j { - if len(indices) > ntest { - popular[s] = struct{}{} - } - } - for s := range popular { - delete(b2j, s) - } - } - m.bPopular = popular - m.b2j = b2j -} - -func (m *SequenceMatcher) isBJunk(s string) bool { - _, ok := m.bJunk[s] - return ok -} - -// Find longest matching block in a[alo:ahi] and b[blo:bhi]. -// -// If IsJunk is not defined: -// -// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where -// -// alo <= i <= i+k <= ahi -// blo <= j <= j+k <= bhi -// -// and for all (i',j',k') meeting those conditions, -// -// k >= k' -// i <= i' -// and if i == i', j <= j' -// -// In other words, of all maximal matching blocks, return one that -// starts earliest in a, and of all those maximal matching blocks that -// start earliest in a, return the one that starts earliest in b. -// -// If IsJunk is defined, first the longest matching block is -// determined as above, but with the additional restriction that no -// junk element appears in the block. Then that block is extended as -// far as possible by matching (only) junk elements on both sides. So -// the resulting block never matches on junk except as identical junk -// happens to be adjacent to an "interesting" match. -// -// If no blocks match, return (alo, blo, 0). -func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { - // CAUTION: stripping common prefix or suffix would be incorrect. - // E.g., - // ab - // acab - // Longest matching block is "ab", but if common prefix is - // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so - // strip, so ends up claiming that ab is changed to acab by - // inserting "ca" in the middle. That's minimal but unintuitive: - // "it's obvious" that someone inserted "ac" at the front. - // Windiff ends up at the same place as diff, but by pairing up - // the unique 'b's and then matching the first two 'a's. - besti, bestj, bestsize := alo, blo, 0 - - // find longest junk-free match - // during an iteration of the loop, j2len[j] = length of longest - // junk-free match ending with a[i-1] and b[j] - j2len := map[int]int{} - for i := alo; i != ahi; i++ { - // look at all instances of a[i] in b; note that because - // b2j has no junk keys, the loop is skipped if a[i] is junk - newj2len := map[int]int{} - for _, j := range m.b2j[m.a[i]] { - // a[i] matches b[j] - if j < blo { - continue - } - if j >= bhi { - break - } - k := j2len[j-1] + 1 - newj2len[j] = k - if k > bestsize { - besti, bestj, bestsize = i-k+1, j-k+1, k - } - } - j2len = newj2len - } - - // Extend the best by non-junk elements on each end. In particular, - // "popular" non-junk elements aren't in b2j, which greatly speeds - // the inner loop above, but also means "the best" match so far - // doesn't contain any junk *or* popular non-junk elements. - for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && - m.a[besti-1] == m.b[bestj-1] { - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - } - for besti+bestsize < ahi && bestj+bestsize < bhi && - !m.isBJunk(m.b[bestj+bestsize]) && - m.a[besti+bestsize] == m.b[bestj+bestsize] { - bestsize++ - } - - // Now that we have a wholly interesting match (albeit possibly - // empty!), we may as well suck up the matching junk on each - // side of it too. Can't think of a good reason not to, and it - // saves post-processing the (possibly considerable) expense of - // figuring out what to do with it. In the case of an empty - // interesting match, this is clearly the right thing to do, - // because no other kind of match is possible in the regions. - for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && - m.a[besti-1] == m.b[bestj-1] { - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - } - for besti+bestsize < ahi && bestj+bestsize < bhi && - m.isBJunk(m.b[bestj+bestsize]) && - m.a[besti+bestsize] == m.b[bestj+bestsize] { - bestsize++ - } - - return Match{A: besti, B: bestj, Size: bestsize} -} - -// Return list of triples describing matching subsequences. -// -// Each triple is of the form (i, j, n), and means that -// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in -// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are -// adjacent triples in the list, and the second is not the last triple in the -// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe -// adjacent equal blocks. -// -// The last triple is a dummy, (len(a), len(b), 0), and is the only -// triple with n==0. -func (m *SequenceMatcher) GetMatchingBlocks() []Match { - if m.matchingBlocks != nil { - return m.matchingBlocks - } - - var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match - matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { - match := m.findLongestMatch(alo, ahi, blo, bhi) - i, j, k := match.A, match.B, match.Size - if match.Size > 0 { - if alo < i && blo < j { - matched = matchBlocks(alo, i, blo, j, matched) - } - matched = append(matched, match) - if i+k < ahi && j+k < bhi { - matched = matchBlocks(i+k, ahi, j+k, bhi, matched) - } - } - return matched - } - matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) - - // It's possible that we have adjacent equal blocks in the - // matching_blocks list now. - nonAdjacent := []Match{} - i1, j1, k1 := 0, 0, 0 - for _, b := range matched { - // Is this block adjacent to i1, j1, k1? - i2, j2, k2 := b.A, b.B, b.Size - if i1+k1 == i2 && j1+k1 == j2 { - // Yes, so collapse them -- this just increases the length of - // the first block by the length of the second, and the first - // block so lengthened remains the block to compare against. - k1 += k2 - } else { - // Not adjacent. Remember the first block (k1==0 means it's - // the dummy we started with), and make the second block the - // new block to compare against. - if k1 > 0 { - nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) - } - i1, j1, k1 = i2, j2, k2 - } - } - if k1 > 0 { - nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) - } - - nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) - m.matchingBlocks = nonAdjacent - return m.matchingBlocks -} - -// Return list of 5-tuples describing how to turn a into b. -// -// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple -// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the -// tuple preceding it, and likewise for j1 == the previous j2. -// -// The tags are characters, with these meanings: -// -// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] -// -// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. -// -// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. -// -// 'e' (equal): a[i1:i2] == b[j1:j2] -func (m *SequenceMatcher) GetOpCodes() []OpCode { - if m.opCodes != nil { - return m.opCodes - } - i, j := 0, 0 - matching := m.GetMatchingBlocks() - opCodes := make([]OpCode, 0, len(matching)) - for _, m := range matching { - // invariant: we've pumped out correct diffs to change - // a[:i] into b[:j], and the next matching block is - // a[ai:ai+size] == b[bj:bj+size]. So we need to pump - // out a diff to change a[i:ai] into b[j:bj], pump out - // the matching block, and move (i,j) beyond the match - ai, bj, size := m.A, m.B, m.Size - tag := byte(0) - if i < ai && j < bj { - tag = 'r' - } else if i < ai { - tag = 'd' - } else if j < bj { - tag = 'i' - } - if tag > 0 { - opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) - } - i, j = ai+size, bj+size - // the list of matching blocks is terminated by a - // sentinel with size 0 - if size > 0 { - opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) - } - } - m.opCodes = opCodes - return m.opCodes -} - -// Isolate change clusters by eliminating ranges with no changes. -// -// Return a generator of groups with up to n lines of context. -// Each group is in the same format as returned by GetOpCodes(). -func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { - if n < 0 { - n = 3 - } - codes := m.GetOpCodes() - if len(codes) == 0 { - codes = []OpCode{{'e', 0, 1, 0, 1}} - } - // Fixup leading and trailing groups if they show no changes. - if codes[0].Tag == 'e' { - c := codes[0] - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[0] = OpCode{c.Tag, maxInt(i1, i2-n), i2, maxInt(j1, j2-n), j2} - } - if codes[len(codes)-1].Tag == 'e' { - c := codes[len(codes)-1] - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[len(codes)-1] = OpCode{c.Tag, i1, minInt(i2, i1+n), j1, minInt(j2, j1+n)} - } - nn := n + n - groups := [][]OpCode{} - group := []OpCode{} - for _, c := range codes { - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - // End the current group and start a new one whenever - // there is a large range with no changes. - if c.Tag == 'e' && i2-i1 > nn { - group = append(group, OpCode{ - c.Tag, i1, minInt(i2, i1+n), - j1, minInt(j2, j1+n), - }) - groups = append(groups, group) - group = []OpCode{} - i1, j1 = maxInt(i1, i2-n), maxInt(j1, j2-n) - } - group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) - } - if len(group) > 0 && (len(group) != 1 || group[0].Tag != 'e') { - groups = append(groups, group) - } - return groups -} - -// Return a measure of the sequences' similarity (float in [0,1]). -// -// Where T is the total number of elements in both sequences, and -// M is the number of matches, this is 2.0*M / T. -// Note that this is 1 if the sequences are identical, and 0 if -// they have nothing in common. -// -// .Ratio() is expensive to compute if you haven't already computed -// .GetMatchingBlocks() or .GetOpCodes(), in which case you may -// want to try .QuickRatio() or .RealQuickRation() first to get an -// upper bound. -func (m *SequenceMatcher) Ratio() float64 { - matches := 0 - for _, m := range m.GetMatchingBlocks() { - matches += m.Size - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() relatively quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute. -func (m *SequenceMatcher) QuickRatio() float64 { - // viewing a and b as multisets, set matches to the cardinality - // of their intersection; this counts the number of matches - // without regard to order, so is clearly an upper bound - if m.fullBCount == nil { - m.fullBCount = map[string]int{} - for _, s := range m.b { - m.fullBCount[s]++ - } - } - - // avail[x] is the number of times x appears in 'b' less the - // number of times we've seen it in 'a' so far ... kinda - avail := map[string]int{} - matches := 0 - for _, s := range m.a { - n, ok := avail[s] - if !ok { - n = m.fullBCount[s] - } - avail[s] = n - 1 - if n > 0 { - matches++ - } - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() very quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute than either .Ratio() or .QuickRatio(). -func (m *SequenceMatcher) RealQuickRatio() float64 { - la, lb := len(m.a), len(m.b) - return calculateRatio(minInt(la, lb), la+lb) -} - -// Convert range to the "ed" format -func formatRangeUnified(start, stop int) string { - // Per the diff spec at http://www.unix.org/single_unix_specification/ - beginning := start + 1 // lines start numbering with one - length := stop - start - if length == 1 { - return strconv.Itoa(beginning) - } - if length == 0 { - beginning-- // empty ranges begin at line just before the range - } - return fmt.Sprintf("%d,%d", beginning, length) -} - -// Unified diff parameters -type UnifiedDiff struct { - A []string // First sequence lines - FromFile string // First file name - FromDate string // First file time - B []string // Second sequence lines - ToFile string // Second file name - ToDate string // Second file time - Eol string // Headers end of line, defaults to LF - Context int // Number of context lines -} - -// Compare two sequences of lines; generate the delta as a unified diff. -// -// Unified diffs are a compact way of showing line changes and a few -// lines of context. The number of context lines is set by 'n' which -// defaults to three. -// -// By default, the diff control lines (those with ---, +++, or @@) are -// created with a trailing newline. This is helpful so that inputs -// created from file.readlines() result in diffs that are suitable for -// file.writelines() since both the inputs and outputs have trailing -// newlines. -// -// For inputs that do not have trailing newlines, set the lineterm -// argument to "" so that the output will be uniformly newline free. -// -// The unidiff format normally has a header for filenames and modification -// times. Any or all of these may be specified using strings for -// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. -// The modification times are normally expressed in the ISO 8601 format. -func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { - buf := bufio.NewWriter(writer) - defer buf.Flush() - wf := func(format string, args ...interface{}) error { - _, err := fmt.Fprintf(buf, format, args...) - return err - } - ws := func(s string) error { - _, err := buf.WriteString(s) - return err - } - - if len(diff.Eol) == 0 { - diff.Eol = "\n" - } - - started := false - m := NewMatcher(diff.A, diff.B) - for _, g := range m.GetGroupedOpCodes(diff.Context) { - if !started { - started = true - fromDate := "" - if len(diff.FromDate) > 0 { - fromDate = "\t" + diff.FromDate - } - toDate := "" - if len(diff.ToDate) > 0 { - toDate = "\t" + diff.ToDate - } - if diff.FromFile != "" || diff.ToFile != "" { - err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) - if err != nil { - return err - } - err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) - if err != nil { - return err - } - } - } - first, last := g[0], g[len(g)-1] - range1 := formatRangeUnified(first.I1, last.I2) - range2 := formatRangeUnified(first.J1, last.J2) - if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { - return err - } - for _, c := range g { - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - if c.Tag == 'e' { - for _, line := range diff.A[i1:i2] { - if err := ws(" " + line); err != nil { - return err - } - } - continue - } - if c.Tag == 'r' || c.Tag == 'd' { - for _, line := range diff.A[i1:i2] { - if err := ws("-" + line); err != nil { - return err - } - } - } - if c.Tag == 'r' || c.Tag == 'i' { - for _, line := range diff.B[j1:j2] { - if err := ws("+" + line); err != nil { - return err - } - } - } - } - } - return nil -} - -// Like WriteUnifiedDiff but returns the diff a string. -func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { - w := &bytes.Buffer{} - err := WriteUnifiedDiff(w, diff) - return w.String(), err -} - -// Split a string on "\n" while preserving them. The output can be used -// as input for UnifiedDiff and ContextDiff structures. -func SplitLines(s string) []string { - lines := strings.SplitAfter(s, "\n") - lines[len(lines)-1] += "\n" - return lines -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go deleted file mode 100644 index a4fa6eabd788..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package internal - -import "regexp" - -type GoCollectorRule struct { - Matcher *regexp.Regexp - Deny bool -} - -// GoCollectorOptions should not be used be directly by anything, except `collectors` package. -// Use it via collectors package instead. See issue -// https://github.com/prometheus/client_golang/issues/1030. -// -// This is internal, so external users only can use it via `collector.WithGoCollector*` methods -type GoCollectorOptions struct { - DisableMemStatsLikeMetrics bool - RuntimeMetricSumForHist map[string]string - RuntimeMetricRules []GoCollectorRule -} - -var GoCollectorDefaultRuntimeMetrics = regexp.MustCompile(`/gc/gogc:percent|/gc/gomemlimit:bytes|/sched/gomaxprocs:threads`) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go deleted file mode 100644 index d273b6640e4e..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build go1.17 -// +build go1.17 - -package internal - -import ( - "math" - "path" - "runtime/metrics" - "strings" - - "github.com/prometheus/common/model" -) - -// RuntimeMetricsToProm produces a Prometheus metric name from a runtime/metrics -// metric description and validates whether the metric is suitable for integration -// with Prometheus. -// -// Returns false if a name could not be produced, or if Prometheus does not understand -// the runtime/metrics Kind. -// -// Note that the main reason a name couldn't be produced is if the runtime/metrics -// package exports a name with characters outside the valid Prometheus metric name -// character set. This is theoretically possible, but should never happen in practice. -// Still, don't rely on it. -func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) { - namespace := "go" - - comp := strings.SplitN(d.Name, ":", 2) - key := comp[0] - unit := comp[1] - - // The last path element in the key is the name, - // the rest is the subsystem. - subsystem := path.Dir(key[1:] /* remove leading / */) - name := path.Base(key) - - // subsystem is translated by replacing all / and - with _. - subsystem = strings.ReplaceAll(subsystem, "/", "_") - subsystem = strings.ReplaceAll(subsystem, "-", "_") - - // unit is translated assuming that the unit contains no - // non-ASCII characters. - unit = strings.ReplaceAll(unit, "-", "_") - unit = strings.ReplaceAll(unit, "*", "_") - unit = strings.ReplaceAll(unit, "/", "_per_") - - // name has - replaced with _ and is concatenated with the unit and - // other data. - name = strings.ReplaceAll(name, "-", "_") - name += "_" + unit - if d.Cumulative && d.Kind != metrics.KindFloat64Histogram { - name += "_total" - } - - // Our current conversion moves to legacy naming, so use legacy validation. - valid := model.LegacyValidation.IsValidMetricName(namespace + "_" + subsystem + "_" + name) - switch d.Kind { - case metrics.KindUint64: - case metrics.KindFloat64: - case metrics.KindFloat64Histogram: - default: - valid = false - } - return namespace, subsystem, name, valid -} - -// RuntimeMetricsBucketsForUnit takes a set of buckets obtained for a runtime/metrics histogram -// type (so, lower-bound inclusive) and a unit from a runtime/metrics name, and produces -// a reduced set of buckets. This function always removes any -Inf bucket as it's represented -// as the bottom-most upper-bound inclusive bucket in Prometheus. -func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 { - switch unit { - case "bytes": - // Re-bucket as powers of 2. - return reBucketExp(buckets, 2) - case "seconds": - // Re-bucket as powers of 10 and then merge all buckets greater - // than 1 second into the +Inf bucket. - b := reBucketExp(buckets, 10) - for i := range b { - if b[i] <= 1 { - continue - } - b[i] = math.Inf(1) - b = b[:i+1] - break - } - return b - } - return buckets -} - -// reBucketExp takes a list of bucket boundaries (lower bound inclusive) and -// downsamples the buckets to those a multiple of base apart. The end result -// is a roughly exponential (in many cases, perfectly exponential) bucketing -// scheme. -func reBucketExp(buckets []float64, base float64) []float64 { - bucket := buckets[0] - var newBuckets []float64 - // We may see a -Inf here, in which case, add it and skip it - // since we risk producing NaNs otherwise. - // - // We need to preserve -Inf values to maintain runtime/metrics - // conventions. We'll strip it out later. - if bucket == math.Inf(-1) { - newBuckets = append(newBuckets, bucket) - buckets = buckets[1:] - bucket = buckets[0] - } - // From now on, bucket should always have a non-Inf value because - // Infs are only ever at the ends of the bucket lists, so - // arithmetic operations on it are non-NaN. - for i := 1; i < len(buckets); i++ { - if bucket >= 0 && buckets[i] < bucket*base { - // The next bucket we want to include is at least bucket*base. - continue - } else if bucket < 0 && buckets[i] < bucket/base { - // In this case the bucket we're targeting is negative, and since - // we're ascending through buckets here, we need to divide to get - // closer to zero exponentially. - continue - } - // The +Inf bucket will always be the last one, and we'll always - // end up including it here because bucket - newBuckets = append(newBuckets, bucket) - bucket = buckets[i] - } - return append(newBuckets, bucket) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go deleted file mode 100644 index 6515c114804f..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2018 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package internal - -import ( - "sort" - - dto "github.com/prometheus/client_model/go" -) - -// LabelPairSorter implements sort.Interface. It is used to sort a slice of -// dto.LabelPair pointers. -type LabelPairSorter []*dto.LabelPair - -func (s LabelPairSorter) Len() int { - return len(s) -} - -func (s LabelPairSorter) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s LabelPairSorter) Less(i, j int) bool { - return s[i].GetName() < s[j].GetName() -} - -// MetricSorter is a sortable slice of *dto.Metric. -type MetricSorter []*dto.Metric - -func (s MetricSorter) Len() int { - return len(s) -} - -func (s MetricSorter) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s MetricSorter) Less(i, j int) bool { - if len(s[i].Label) != len(s[j].Label) { - // This should not happen. The metrics are - // inconsistent. However, we have to deal with the fact, as - // people might use custom collectors or metric family injection - // to create inconsistent metrics. So let's simply compare the - // number of labels in this case. That will still yield - // reproducible sorting. - return len(s[i].Label) < len(s[j].Label) - } - for n, lp := range s[i].Label { - vi := lp.GetValue() - vj := s[j].Label[n].GetValue() - if vi != vj { - return vi < vj - } - } - - // We should never arrive here. Multiple metrics with the same - // label set in the same scrape will lead to undefined ingestion - // behavior. However, as above, we have to provide stable sorting - // here, even for inconsistent metrics. So sort equal metrics - // by their timestamp, with missing timestamps (implying "now") - // coming last. - if s[i].TimestampMs == nil { - return false - } - if s[j].TimestampMs == nil { - return true - } - return s[i].GetTimestampMs() < s[j].GetTimestampMs() -} - -// NormalizeMetricFamilies returns a MetricFamily slice with empty -// MetricFamilies pruned and the remaining MetricFamilies sorted by name within -// the slice, with the contained Metrics sorted within each MetricFamily. -func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily { - for _, mf := range metricFamiliesByName { - sort.Sort(MetricSorter(mf.Metric)) - } - names := make([]string, 0, len(metricFamiliesByName)) - for name, mf := range metricFamiliesByName { - if len(mf.Metric) > 0 { - names = append(names, name) - } - } - sort.Strings(names) - result := make([]*dto.MetricFamily, 0, len(names)) - for _, name := range names { - result = append(result, metricFamiliesByName[name]) - } - return result -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go deleted file mode 100644 index 5fe8d3b4d294..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2018 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "errors" - "fmt" - "strings" - "unicode/utf8" - - "github.com/prometheus/common/model" -) - -// Labels represents a collection of label name -> value mappings. This type is -// commonly used with the With(Labels) and GetMetricWith(Labels) methods of -// metric vector Collectors, e.g.: -// -// myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) -// -// The other use-case is the specification of constant label pairs in Opts or to -// create a Desc. -type Labels map[string]string - -// LabelConstraint normalizes label values. -type LabelConstraint func(string) string - -// ConstrainedLabels represents a label name and its constrain function -// to normalize label values. This type is commonly used when constructing -// metric vector Collectors. -type ConstrainedLabel struct { - Name string - Constraint LabelConstraint -} - -// ConstrainableLabels is an interface that allows creating of labels that can -// be optionally constrained. -// -// prometheus.V2().NewCounterVec(CounterVecOpts{ -// CounterOpts: {...}, // Usual CounterOpts fields -// VariableLabels: []ConstrainedLabels{ -// {Name: "A"}, -// {Name: "B", Constraint: func(v string) string { ... }}, -// }, -// }) -type ConstrainableLabels interface { - compile() *compiledLabels - labelNames() []string -} - -// ConstrainedLabels represents a collection of label name -> constrain function -// to normalize label values. This type is commonly used when constructing -// metric vector Collectors. -type ConstrainedLabels []ConstrainedLabel - -func (cls ConstrainedLabels) compile() *compiledLabels { - compiled := &compiledLabels{ - names: make([]string, len(cls)), - labelConstraints: map[string]LabelConstraint{}, - } - - for i, label := range cls { - compiled.names[i] = label.Name - if label.Constraint != nil { - compiled.labelConstraints[label.Name] = label.Constraint - } - } - - return compiled -} - -func (cls ConstrainedLabels) labelNames() []string { - names := make([]string, len(cls)) - for i, label := range cls { - names[i] = label.Name - } - return names -} - -// UnconstrainedLabels represents collection of label without any constraint on -// their value. Thus, it is simply a collection of label names. -// -// UnconstrainedLabels([]string{ "A", "B" }) -// -// is equivalent to -// -// ConstrainedLabels { -// { Name: "A" }, -// { Name: "B" }, -// } -type UnconstrainedLabels []string - -func (uls UnconstrainedLabels) compile() *compiledLabels { - return &compiledLabels{ - names: uls, - } -} - -func (uls UnconstrainedLabels) labelNames() []string { - return uls -} - -type compiledLabels struct { - names []string - labelConstraints map[string]LabelConstraint -} - -func (cls *compiledLabels) compile() *compiledLabels { - return cls -} - -func (cls *compiledLabels) labelNames() []string { - return cls.names -} - -func (cls *compiledLabels) constrain(labelName, value string) string { - if fn, ok := cls.labelConstraints[labelName]; ok && fn != nil { - return fn(value) - } - return value -} - -// reservedLabelPrefix is a prefix which is not legal in user-supplied -// label names. -const reservedLabelPrefix = "__" - -var errInconsistentCardinality = errors.New("inconsistent label cardinality") - -func makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error { - return fmt.Errorf( - "%w: %q has %d variable labels named %q but %d values %q were provided", - errInconsistentCardinality, fqName, - len(labels), labels, - len(labelValues), labelValues, - ) -} - -func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error { - if len(labels) != expectedNumberOfValues { - return fmt.Errorf( - "%w: expected %d label values but got %d in %#v", - errInconsistentCardinality, expectedNumberOfValues, - len(labels), labels, - ) - } - - for name, val := range labels { - if !utf8.ValidString(val) { - return fmt.Errorf("label %s: value %q is not valid UTF-8", name, val) - } - } - - return nil -} - -func validateLabelValues(vals []string, expectedNumberOfValues int) error { - if len(vals) != expectedNumberOfValues { - // The call below makes vals escape, copy them to avoid that. - vals := append([]string(nil), vals...) - return fmt.Errorf( - "%w: expected %d label values but got %d in %#v", - errInconsistentCardinality, expectedNumberOfValues, - len(vals), vals, - ) - } - - for _, val := range vals { - if !utf8.ValidString(val) { - return fmt.Errorf("label value %q is not valid UTF-8", val) - } - } - - return nil -} - -func checkLabelName(l string) bool { - //nolint:staticcheck // TODO: Don't use deprecated model.NameValidationScheme. - return model.NameValidationScheme.IsValidLabelName(l) && !strings.HasPrefix(l, reservedLabelPrefix) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go deleted file mode 100644 index 76e59f12880c..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "errors" - "math" - "sort" - "strings" - "time" - - dto "github.com/prometheus/client_model/go" - "github.com/prometheus/common/model" - "google.golang.org/protobuf/proto" -) - -var separatorByteSlice = []byte{model.SeparatorByte} // For convenient use with xxhash. - -// A Metric models a single sample value with its meta data being exported to -// Prometheus. Implementations of Metric in this package are Gauge, Counter, -// Histogram, Summary, and Untyped. -type Metric interface { - // Desc returns the descriptor for the Metric. This method idempotently - // returns the same descriptor throughout the lifetime of the - // Metric. The returned descriptor is immutable by contract. A Metric - // unable to describe itself must return an invalid descriptor (created - // with NewInvalidDesc). - Desc() *Desc - // Write encodes the Metric into a "Metric" Protocol Buffer data - // transmission object. - // - // Metric implementations must observe concurrency safety as reads of - // this metric may occur at any time, and any blocking occurs at the - // expense of total performance of rendering all registered - // metrics. Ideally, Metric implementations should support concurrent - // readers. - // - // While populating dto.Metric, it is the responsibility of the - // implementation to ensure validity of the Metric protobuf (like valid - // UTF-8 strings or syntactically valid metric and label names). It is - // recommended to sort labels lexicographically. Callers of Write should - // still make sure of sorting if they depend on it. - Write(*dto.Metric) error - // TODO(beorn7): The original rationale of passing in a pre-allocated - // dto.Metric protobuf to save allocations has disappeared. The - // signature of this method should be changed to "Write() (*dto.Metric, - // error)". -} - -// Opts bundles the options for creating most Metric types. Each metric -// implementation XXX has its own XXXOpts type, but in most cases, it is just -// an alias of this type (which might change when the requirement arises.) -// -// It is mandatory to set Name to a non-empty string. All other fields are -// optional and can safely be left at their zero value, although it is strongly -// encouraged to set a Help string. -type Opts struct { - // Namespace, Subsystem, and Name are components of the fully-qualified - // name of the Metric (created by joining these components with - // "_"). Only Name is mandatory, the others merely help structuring the - // name. Note that the fully-qualified name of the metric must be a - // valid Prometheus metric name. - Namespace string - Subsystem string - Name string - - // Help provides information about this metric. - // - // Metrics with the same fully-qualified name must have the same Help - // string. - Help string - - // ConstLabels are used to attach fixed labels to this metric. Metrics - // with the same fully-qualified name must have the same label names in - // their ConstLabels. - // - // ConstLabels are only used rarely. In particular, do not use them to - // attach the same labels to all your metrics. Those use cases are - // better covered by target labels set by the scraping Prometheus - // server, or by one specific metric (e.g. a build_info or a - // machine_role metric). See also - // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels - ConstLabels Labels - - // now is for testing purposes, by default it's time.Now. - now func() time.Time -} - -// BuildFQName joins the given three name components by "_". Empty name -// components are ignored. If the name parameter itself is empty, an empty -// string is returned, no matter what. Metric implementations included in this -// library use this function internally to generate the fully-qualified metric -// name from the name component in their Opts. Users of the library will only -// need this function if they implement their own Metric or instantiate a Desc -// (with NewDesc) directly. -func BuildFQName(namespace, subsystem, name string) string { - if name == "" { - return "" - } - - sb := strings.Builder{} - sb.Grow(len(namespace) + len(subsystem) + len(name) + 2) - - if namespace != "" { - sb.WriteString(namespace) - sb.WriteString("_") - } - - if subsystem != "" { - sb.WriteString(subsystem) - sb.WriteString("_") - } - - sb.WriteString(name) - - return sb.String() -} - -type invalidMetric struct { - desc *Desc - err error -} - -// NewInvalidMetric returns a metric whose Write method always returns the -// provided error. It is useful if a Collector finds itself unable to collect -// a metric and wishes to report an error to the registry. -func NewInvalidMetric(desc *Desc, err error) Metric { - return &invalidMetric{desc, err} -} - -func (m *invalidMetric) Desc() *Desc { return m.desc } - -func (m *invalidMetric) Write(*dto.Metric) error { return m.err } - -type timestampedMetric struct { - Metric - t time.Time -} - -func (m timestampedMetric) Write(pb *dto.Metric) error { - e := m.Metric.Write(pb) - pb.TimestampMs = proto.Int64(m.t.Unix()*1000 + int64(m.t.Nanosecond()/1000000)) - return e -} - -// NewMetricWithTimestamp returns a new Metric wrapping the provided Metric in a -// way that it has an explicit timestamp set to the provided Time. This is only -// useful in rare cases as the timestamp of a Prometheus metric should usually -// be set by the Prometheus server during scraping. Exceptions include mirroring -// metrics with given timestamps from other metric -// sources. -// -// NewMetricWithTimestamp works best with MustNewConstMetric, -// MustNewConstHistogram, and MustNewConstSummary, see example. -// -// Currently, the exposition formats used by Prometheus are limited to -// millisecond resolution. Thus, the provided time will be rounded down to the -// next full millisecond value. -func NewMetricWithTimestamp(t time.Time, m Metric) Metric { - return timestampedMetric{Metric: m, t: t} -} - -type withExemplarsMetric struct { - Metric - - exemplars []*dto.Exemplar -} - -func (m *withExemplarsMetric) Write(pb *dto.Metric) error { - if err := m.Metric.Write(pb); err != nil { - return err - } - - switch { - case pb.Counter != nil: - pb.Counter.Exemplar = m.exemplars[len(m.exemplars)-1] - case pb.Histogram != nil: - h := pb.Histogram - for _, e := range m.exemplars { - if (h.GetZeroThreshold() != 0 || h.GetZeroCount() != 0 || - len(h.PositiveSpan) != 0 || len(h.NegativeSpan) != 0) && - e.GetTimestamp() != nil { - h.Exemplars = append(h.Exemplars, e) - if len(h.Bucket) == 0 { - // Don't proceed to classic buckets if there are none. - continue - } - } - // h.Bucket are sorted by UpperBound. - i := sort.Search(len(h.Bucket), func(i int) bool { - return h.Bucket[i].GetUpperBound() >= e.GetValue() - }) - if i < len(h.Bucket) { - h.Bucket[i].Exemplar = e - } else { - // The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365. - b := &dto.Bucket{ - CumulativeCount: proto.Uint64(h.GetSampleCount()), - UpperBound: proto.Float64(math.Inf(1)), - Exemplar: e, - } - h.Bucket = append(h.Bucket, b) - } - } - default: - // TODO(bwplotka): Implement Gauge? - return errors.New("cannot inject exemplar into Gauge, Summary or Untyped") - } - - return nil -} - -// Exemplar is easier to use, user-facing representation of *dto.Exemplar. -type Exemplar struct { - Value float64 - Labels Labels - // Optional. - // Default value (time.Time{}) indicates its empty, which should be - // understood as time.Now() time at the moment of creation of metric. - Timestamp time.Time -} - -// NewMetricWithExemplars returns a new Metric wrapping the provided Metric with given -// exemplars. Exemplars are validated. -// -// Only last applicable exemplar is injected from the list. -// For example for Counter it means last exemplar is injected. -// For Histogram, it means last applicable exemplar for each bucket is injected. -// For a Native Histogram, all valid exemplars are injected. -// -// NewMetricWithExemplars works best with MustNewConstMetric and -// MustNewConstHistogram, see example. -func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) { - if len(exemplars) == 0 { - return nil, errors.New("no exemplar was passed for NewMetricWithExemplars") - } - - var ( - now = time.Now() - exs = make([]*dto.Exemplar, len(exemplars)) - err error - ) - for i, e := range exemplars { - ts := e.Timestamp - if ts.IsZero() { - ts = now - } - exs[i], err = newExemplar(e.Value, ts, e.Labels) - if err != nil { - return nil, err - } - } - - return &withExemplarsMetric{Metric: m, exemplars: exs}, nil -} - -// MustNewMetricWithExemplars is a version of NewMetricWithExemplars that panics where -// NewMetricWithExemplars would have returned an error. -func MustNewMetricWithExemplars(m Metric, exemplars ...Exemplar) Metric { - ret, err := NewMetricWithExemplars(m, exemplars...) - if err != nil { - panic(err) - } - return ret -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go deleted file mode 100644 index 7c12b210870a..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !js || wasm -// +build !js wasm - -package prometheus - -import "runtime" - -// getRuntimeNumThreads returns the number of open OS threads. -func getRuntimeNumThreads() float64 { - n, _ := runtime.ThreadCreateProfile(nil) - return float64(n) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go deleted file mode 100644 index 7348df01dfbc..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build js && !wasm -// +build js,!wasm - -package prometheus - -// getRuntimeNumThreads returns the number of open OS threads. -func getRuntimeNumThreads() float64 { - return 1 -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/observer.go b/vendor/github.com/prometheus/client_golang/prometheus/observer.go deleted file mode 100644 index 03773b21f759..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/observer.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -// Observer is the interface that wraps the Observe method, which is used by -// Histogram and Summary to add observations. -type Observer interface { - Observe(float64) -} - -// The ObserverFunc type is an adapter to allow the use of ordinary -// functions as Observers. If f is a function with the appropriate -// signature, ObserverFunc(f) is an Observer that calls f. -// -// This adapter is usually used in connection with the Timer type, and there are -// two general use cases: -// -// The most common one is to use a Gauge as the Observer for a Timer. -// See the "Gauge" Timer example. -// -// The more advanced use case is to create a function that dynamically decides -// which Observer to use for observing the duration. See the "Complex" Timer -// example. -type ObserverFunc func(float64) - -// Observe calls f(value). It implements Observer. -func (f ObserverFunc) Observe(value float64) { - f(value) -} - -// ObserverVec is an interface implemented by `HistogramVec` and `SummaryVec`. -type ObserverVec interface { - GetMetricWith(Labels) (Observer, error) - GetMetricWithLabelValues(lvs ...string) (Observer, error) - With(Labels) Observer - WithLabelValues(...string) Observer - CurryWith(Labels) (ObserverVec, error) - MustCurryWith(Labels) ObserverVec - - Collector -} - -// ExemplarObserver is implemented by Observers that offer the option of -// observing a value together with an exemplar. Its ObserveWithExemplar method -// works like the Observe method of an Observer but also replaces the currently -// saved exemplar (if any) with a new one, created from the provided value, the -// current time as timestamp, and the provided Labels. Empty Labels will lead to -// a valid (label-less) exemplar. But if Labels is nil, the current exemplar is -// left in place. ObserveWithExemplar panics if any of the provided labels are -// invalid or if the provided labels contain more than 128 runes in total. -type ExemplarObserver interface { - ObserveWithExemplar(value float64, exemplar Labels) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go deleted file mode 100644 index e7bce8b58ecb..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "errors" - "fmt" - "os" - "strconv" - "strings" -) - -type processCollector struct { - collectFn func(chan<- Metric) - describeFn func(chan<- *Desc) - pidFn func() (int, error) - reportErrors bool - cpuTotal *Desc - openFDs, maxFDs *Desc - vsize, maxVsize *Desc - rss *Desc - startTime *Desc - inBytes, outBytes *Desc -} - -// ProcessCollectorOpts defines the behavior of a process metrics collector -// created with NewProcessCollector. -type ProcessCollectorOpts struct { - // PidFn returns the PID of the process the collector collects metrics - // for. It is called upon each collection. By default, the PID of the - // current process is used, as determined on construction time by - // calling os.Getpid(). - PidFn func() (int, error) - // If non-empty, each of the collected metrics is prefixed by the - // provided string and an underscore ("_"). - Namespace string - // If true, any error encountered during collection is reported as an - // invalid metric (see NewInvalidMetric). Otherwise, errors are ignored - // and the collected metrics will be incomplete. (Possibly, no metrics - // will be collected at all.) While that's usually not desired, it is - // appropriate for the common "mix-in" of process metrics, where process - // metrics are nice to have, but failing to collect them should not - // disrupt the collection of the remaining metrics. - ReportErrors bool -} - -// NewProcessCollector is the obsolete version of collectors.NewProcessCollector. -// See there for documentation. -// -// Deprecated: Use collectors.NewProcessCollector instead. -func NewProcessCollector(opts ProcessCollectorOpts) Collector { - ns := "" - if len(opts.Namespace) > 0 { - ns = opts.Namespace + "_" - } - - c := &processCollector{ - reportErrors: opts.ReportErrors, - cpuTotal: NewDesc( - ns+"process_cpu_seconds_total", - "Total user and system CPU time spent in seconds.", - nil, nil, - ), - openFDs: NewDesc( - ns+"process_open_fds", - "Number of open file descriptors.", - nil, nil, - ), - maxFDs: NewDesc( - ns+"process_max_fds", - "Maximum number of open file descriptors.", - nil, nil, - ), - vsize: NewDesc( - ns+"process_virtual_memory_bytes", - "Virtual memory size in bytes.", - nil, nil, - ), - maxVsize: NewDesc( - ns+"process_virtual_memory_max_bytes", - "Maximum amount of virtual memory available in bytes.", - nil, nil, - ), - rss: NewDesc( - ns+"process_resident_memory_bytes", - "Resident memory size in bytes.", - nil, nil, - ), - startTime: NewDesc( - ns+"process_start_time_seconds", - "Start time of the process since unix epoch in seconds.", - nil, nil, - ), - inBytes: NewDesc( - ns+"process_network_receive_bytes_total", - "Number of bytes received by the process over the network.", - nil, nil, - ), - outBytes: NewDesc( - ns+"process_network_transmit_bytes_total", - "Number of bytes sent by the process over the network.", - nil, nil, - ), - } - - if opts.PidFn == nil { - c.pidFn = getPIDFn() - } else { - c.pidFn = opts.PidFn - } - - // Set up process metric collection if supported by the runtime. - if canCollectProcess() { - c.collectFn = c.processCollect - c.describeFn = c.describe - } else { - c.collectFn = c.errorCollectFn - c.describeFn = c.errorDescribeFn - } - - return c -} - -func (c *processCollector) errorCollectFn(ch chan<- Metric) { - c.reportError(ch, nil, errors.New("process metrics not supported on this platform")) -} - -func (c *processCollector) errorDescribeFn(ch chan<- *Desc) { - if c.reportErrors { - ch <- NewInvalidDesc(errors.New("process metrics not supported on this platform")) - } -} - -// Collect returns the current state of all metrics of the collector. -func (c *processCollector) Collect(ch chan<- Metric) { - c.collectFn(ch) -} - -// Describe returns all descriptions of the collector. -func (c *processCollector) Describe(ch chan<- *Desc) { - c.describeFn(ch) -} - -func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) { - if !c.reportErrors { - return - } - if desc == nil { - desc = NewInvalidDesc(err) - } - ch <- NewInvalidMetric(desc, err) -} - -// NewPidFileFn returns a function that retrieves a pid from the specified file. -// It is meant to be used for the PidFn field in ProcessCollectorOpts. -func NewPidFileFn(pidFilePath string) func() (int, error) { - return func() (int, error) { - content, err := os.ReadFile(pidFilePath) - if err != nil { - return 0, fmt.Errorf("can't read pid file %q: %w", pidFilePath, err) - } - pid, err := strconv.Atoi(strings.TrimSpace(string(content))) - if err != nil { - return 0, fmt.Errorf("can't parse pid file %q: %w", pidFilePath, err) - } - - return pid, nil - } -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go deleted file mode 100644 index b32c95fa3fab..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build darwin && !ios - -package prometheus - -import ( - "errors" - "fmt" - "os" - "syscall" - "time" - - "golang.org/x/sys/unix" -) - -// errNotImplemented is returned by stub functions that replace cgo functions, when cgo -// isn't available. -var errNotImplemented = errors.New("not implemented") - -type memoryInfo struct { - vsize uint64 // Virtual memory size in bytes - rss uint64 // Resident memory size in bytes -} - -func canCollectProcess() bool { - return true -} - -func getSoftLimit(which int) (uint64, error) { - rlimit := syscall.Rlimit{} - - if err := syscall.Getrlimit(which, &rlimit); err != nil { - return 0, err - } - - return rlimit.Cur, nil -} - -func getOpenFileCount() (float64, error) { - // Alternately, the undocumented proc_pidinfo(PROC_PIDLISTFDS) can be used to - // return a list of open fds, but that requires a way to call C APIs. The - // benefits, however, include fewer system calls and not failing when at the - // open file soft limit. - - if dir, err := os.Open("/dev/fd"); err != nil { - return 0.0, err - } else { - defer dir.Close() - - // Avoid ReadDir(), as it calls stat(2) on each descriptor. Not only is - // that info not used, but KQUEUE descriptors fail stat(2), which causes - // the whole method to fail. - if names, err := dir.Readdirnames(0); err != nil { - return 0.0, err - } else { - // Subtract 1 to ignore the open /dev/fd descriptor above. - return float64(len(names) - 1), nil - } - } -} - -func (c *processCollector) processCollect(ch chan<- Metric) { - if procs, err := unix.SysctlKinfoProcSlice("kern.proc.pid", os.Getpid()); err == nil { - if len(procs) == 1 { - startTime := float64(procs[0].Proc.P_starttime.Nano() / 1e9) - ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime) - } else { - err = fmt.Errorf("sysctl() returned %d proc structs (expected 1)", len(procs)) - c.reportError(ch, c.startTime, err) - } - } else { - c.reportError(ch, c.startTime, err) - } - - // The proc structure returned by kern.proc.pid above has an Rusage member, - // but it is not filled in, so it needs to be fetched by getrusage(2). For - // that call, the UTime, STime, and Maxrss members are filled out, but not - // Ixrss, Idrss, or Isrss for the memory usage. Memory stats will require - // access to the C API to call task_info(TASK_BASIC_INFO). - rusage := unix.Rusage{} - - if err := unix.Getrusage(syscall.RUSAGE_SELF, &rusage); err == nil { - cpuTime := time.Duration(rusage.Stime.Nano() + rusage.Utime.Nano()).Seconds() - ch <- MustNewConstMetric(c.cpuTotal, CounterValue, cpuTime) - } else { - c.reportError(ch, c.cpuTotal, err) - } - - if memInfo, err := getMemory(); err == nil { - ch <- MustNewConstMetric(c.rss, GaugeValue, float64(memInfo.rss)) - ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(memInfo.vsize)) - } else if !errors.Is(err, errNotImplemented) { - // Don't report an error when support is not compiled in. - c.reportError(ch, c.rss, err) - c.reportError(ch, c.vsize, err) - } - - if fds, err := getOpenFileCount(); err == nil { - ch <- MustNewConstMetric(c.openFDs, GaugeValue, fds) - } else { - c.reportError(ch, c.openFDs, err) - } - - if openFiles, err := getSoftLimit(syscall.RLIMIT_NOFILE); err == nil { - ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(openFiles)) - } else { - c.reportError(ch, c.maxFDs, err) - } - - if addressSpace, err := getSoftLimit(syscall.RLIMIT_AS); err == nil { - ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(addressSpace)) - } else { - c.reportError(ch, c.maxVsize, err) - } - - // TODO: socket(PF_SYSTEM) to fetch "com.apple.network.statistics" might - // be able to get the per-process network send/receive counts. -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c deleted file mode 100644 index d00a24315dee..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build darwin && !ios && cgo - -#include -#include -#include - -// The compiler warns that mach/shared_memory_server.h is deprecated, and to use -// mach/shared_region.h instead. But that doesn't define -// SHARED_DATA_REGION_SIZE or SHARED_TEXT_REGION_SIZE, so redefine them here and -// avoid a warning message when running tests. -#define GLOBAL_SHARED_TEXT_SEGMENT 0x90000000U -#define SHARED_DATA_REGION_SIZE 0x10000000 -#define SHARED_TEXT_REGION_SIZE 0x10000000 - - -int get_memory_info(unsigned long long *rss, unsigned long long *vsize) -{ - // This is lightly adapted from how ps(1) obtains its memory info. - // https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/tasks.c#L109 - - kern_return_t error; - task_t task = MACH_PORT_NULL; - mach_task_basic_info_data_t info; - mach_msg_type_number_t info_count = MACH_TASK_BASIC_INFO_COUNT; - - error = task_info( - mach_task_self(), - MACH_TASK_BASIC_INFO, - (task_info_t) &info, - &info_count ); - - if( error != KERN_SUCCESS ) - { - return error; - } - - *rss = info.resident_size; - *vsize = info.virtual_size; - - { - vm_region_basic_info_data_64_t b_info; - mach_vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT; - mach_vm_size_t size; - mach_port_t object_name; - - /* - * try to determine if this task has the split libraries - * mapped in... if so, adjust its virtual size down by - * the 2 segments that are used for split libraries - */ - info_count = VM_REGION_BASIC_INFO_COUNT_64; - - error = mach_vm_region( - mach_task_self(), - &address, - &size, - VM_REGION_BASIC_INFO_64, - (vm_region_info_t) &b_info, - &info_count, - &object_name); - - if (error == KERN_SUCCESS) { - if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) && - *vsize > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) { - *vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE); - } - } - } - - return 0; -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go deleted file mode 100644 index 9ac53f999252..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build darwin && !ios && cgo - -package prometheus - -/* -int get_memory_info(unsigned long long *rss, unsigned long long *vs); -*/ -import "C" -import "fmt" - -func getMemory() (*memoryInfo, error) { - var rss, vsize C.ulonglong - - if err := C.get_memory_info(&rss, &vsize); err != 0 { - return nil, fmt.Errorf("task_info() failed with 0x%x", int(err)) - } - - return &memoryInfo{vsize: uint64(vsize), rss: uint64(rss)}, nil -} - -// describe returns all descriptions of the collector for Darwin. -// Ensure that this list of descriptors is kept in sync with the metrics collected -// in the processCollect method. Any changes to the metrics in processCollect -// (such as adding or removing metrics) should be reflected in this list of descriptors. -func (c *processCollector) describe(ch chan<- *Desc) { - ch <- c.cpuTotal - ch <- c.openFDs - ch <- c.maxFDs - ch <- c.maxVsize - ch <- c.startTime - ch <- c.rss - ch <- c.vsize - - /* the process could be collected but not implemented yet - ch <- c.inBytes - ch <- c.outBytes - */ -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go deleted file mode 100644 index 378865129b77..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build darwin && !ios && !cgo - -package prometheus - -func getMemory() (*memoryInfo, error) { - return nil, errNotImplemented -} - -// describe returns all descriptions of the collector for Darwin. -// Ensure that this list of descriptors is kept in sync with the metrics collected -// in the processCollect method. Any changes to the metrics in processCollect -// (such as adding or removing metrics) should be reflected in this list of descriptors. -func (c *processCollector) describe(ch chan<- *Desc) { - ch <- c.cpuTotal - ch <- c.openFDs - ch <- c.maxFDs - ch <- c.maxVsize - ch <- c.startTime - - /* the process could be collected but not implemented yet - ch <- c.rss - ch <- c.vsize - ch <- c.inBytes - ch <- c.outBytes - */ -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go deleted file mode 100644 index 7732b7f37648..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build wasip1 || js || ios -// +build wasip1 js ios - -package prometheus - -func canCollectProcess() bool { - return false -} - -func (c *processCollector) processCollect(ch chan<- Metric) { - c.errorCollectFn(ch) -} - -// describe returns all descriptions of the collector for wasip1 and js. -// Ensure that this list of descriptors is kept in sync with the metrics collected -// in the processCollect method. Any changes to the metrics in processCollect -// (such as adding or removing metrics) should be reflected in this list of descriptors. -func (c *processCollector) describe(ch chan<- *Desc) { - c.errorDescribeFn(ch) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go deleted file mode 100644 index 8074f70f5d91..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2019 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows && !js && !wasip1 && !darwin -// +build !windows,!js,!wasip1,!darwin - -package prometheus - -import ( - "github.com/prometheus/procfs" -) - -func canCollectProcess() bool { - _, err := procfs.NewDefaultFS() - return err == nil -} - -func (c *processCollector) processCollect(ch chan<- Metric) { - pid, err := c.pidFn() - if err != nil { - c.reportError(ch, nil, err) - return - } - - p, err := procfs.NewProc(pid) - if err != nil { - c.reportError(ch, nil, err) - return - } - - if stat, err := p.Stat(); err == nil { - ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime()) - ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory())) - ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory())) - if startTime, err := stat.StartTime(); err == nil { - ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime) - } else { - c.reportError(ch, c.startTime, err) - } - } else { - c.reportError(ch, nil, err) - } - - if fds, err := p.FileDescriptorsLen(); err == nil { - ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds)) - } else { - c.reportError(ch, c.openFDs, err) - } - - if limits, err := p.Limits(); err == nil { - ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles)) - ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace)) - } else { - c.reportError(ch, nil, err) - } - - if netstat, err := p.Netstat(); err == nil { - var inOctets, outOctets float64 - if netstat.InOctets != nil { - inOctets = *netstat.InOctets - } - if netstat.OutOctets != nil { - outOctets = *netstat.OutOctets - } - ch <- MustNewConstMetric(c.inBytes, CounterValue, inOctets) - ch <- MustNewConstMetric(c.outBytes, CounterValue, outOctets) - } else { - c.reportError(ch, nil, err) - } -} - -// describe returns all descriptions of the collector for others than windows, js, wasip1 and darwin. -// Ensure that this list of descriptors is kept in sync with the metrics collected -// in the processCollect method. Any changes to the metrics in processCollect -// (such as adding or removing metrics) should be reflected in this list of descriptors. -func (c *processCollector) describe(ch chan<- *Desc) { - ch <- c.cpuTotal - ch <- c.openFDs - ch <- c.maxFDs - ch <- c.vsize - ch <- c.maxVsize - ch <- c.rss - ch <- c.startTime - ch <- c.inBytes - ch <- c.outBytes -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go deleted file mode 100644 index fa474289ef8c..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2019 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -func canCollectProcess() bool { - return true -} - -var ( - modpsapi = syscall.NewLazyDLL("psapi.dll") - modkernel32 = syscall.NewLazyDLL("kernel32.dll") - - procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") - procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount") -) - -type processMemoryCounters struct { - // System interface description - // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex - - // Refer to the Golang internal implementation - // https://golang.org/src/internal/syscall/windows/psapi_windows.go - _ uint32 - PageFaultCount uint32 - PeakWorkingSetSize uintptr - WorkingSetSize uintptr - QuotaPeakPagedPoolUsage uintptr - QuotaPagedPoolUsage uintptr - QuotaPeakNonPagedPoolUsage uintptr - QuotaNonPagedPoolUsage uintptr - PagefileUsage uintptr - PeakPagefileUsage uintptr - PrivateUsage uintptr -} - -func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) { - mem := processMemoryCounters{} - r1, _, err := procGetProcessMemoryInfo.Call( - uintptr(handle), - uintptr(unsafe.Pointer(&mem)), - uintptr(unsafe.Sizeof(mem)), - ) - if r1 != 1 { - return mem, err - } else { - return mem, nil - } -} - -func getProcessHandleCount(handle windows.Handle) (uint32, error) { - var count uint32 - r1, _, err := procGetProcessHandleCount.Call( - uintptr(handle), - uintptr(unsafe.Pointer(&count)), - ) - if r1 != 1 { - return 0, err - } else { - return count, nil - } -} - -func (c *processCollector) processCollect(ch chan<- Metric) { - h := windows.CurrentProcess() - - var startTime, exitTime, kernelTime, userTime windows.Filetime - err := windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime) - if err != nil { - c.reportError(ch, nil, err) - return - } - ch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9)) - ch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime)) - - mem, err := getProcessMemoryInfo(h) - if err != nil { - c.reportError(ch, nil, err) - return - } - ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage)) - ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize)) - - handles, err := getProcessHandleCount(h) - if err != nil { - c.reportError(ch, nil, err) - return - } - ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles)) - ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process. -} - -// describe returns all descriptions of the collector for windows. -// Ensure that this list of descriptors is kept in sync with the metrics collected -// in the processCollect method. Any changes to the metrics in processCollect -// (such as adding or removing metrics) should be reflected in this list of descriptors. -func (c *processCollector) describe(ch chan<- *Desc) { - ch <- c.cpuTotal - ch <- c.openFDs - ch <- c.maxFDs - ch <- c.vsize - ch <- c.rss - ch <- c.startTime -} - -func fileTimeToSeconds(ft windows.Filetime) float64 { - return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7 -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go deleted file mode 100644 index c6fd2f58b742..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go +++ /dev/null @@ -1,1076 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "bytes" - "errors" - "fmt" - "os" - "path/filepath" - "runtime" - "sort" - "strconv" - "strings" - "sync" - "unicode/utf8" - - "github.com/prometheus/client_golang/prometheus/internal" - - "github.com/cespare/xxhash/v2" - dto "github.com/prometheus/client_model/go" - "github.com/prometheus/common/expfmt" - "google.golang.org/protobuf/proto" -) - -const ( - // Capacity for the channel to collect metrics and descriptors. - capMetricChan = 1000 - capDescChan = 10 -) - -// DefaultRegisterer and DefaultGatherer are the implementations of the -// Registerer and Gatherer interface a number of convenience functions in this -// package act on. Initially, both variables point to the same Registry, which -// has a process collector (currently on Linux only, see NewProcessCollector) -// and a Go collector (see NewGoCollector, in particular the note about -// stop-the-world implication with Go versions older than 1.9) already -// registered. This approach to keep default instances as global state mirrors -// the approach of other packages in the Go standard library. Note that there -// are caveats. Change the variables with caution and only if you understand the -// consequences. Users who want to avoid global state altogether should not use -// the convenience functions and act on custom instances instead. -var ( - defaultRegistry = NewRegistry() - DefaultRegisterer Registerer = defaultRegistry - DefaultGatherer Gatherer = defaultRegistry -) - -func init() { - MustRegister(NewProcessCollector(ProcessCollectorOpts{})) - MustRegister(NewGoCollector()) -} - -// NewRegistry creates a new vanilla Registry without any Collectors -// pre-registered. -func NewRegistry() *Registry { - return &Registry{ - collectorsByID: map[uint64]Collector{}, - descIDs: map[uint64]struct{}{}, - dimHashesByName: map[string]uint64{}, - } -} - -// NewPedanticRegistry returns a registry that checks during collection if each -// collected Metric is consistent with its reported Desc, and if the Desc has -// actually been registered with the registry. Unchecked Collectors (those whose -// Describe method does not yield any descriptors) are excluded from the check. -// -// Usually, a Registry will be happy as long as the union of all collected -// Metrics is consistent and valid even if some metrics are not consistent with -// their own Desc or a Desc provided by their registered Collector. Well-behaved -// Collectors and Metrics will only provide consistent Descs. This Registry is -// useful to test the implementation of Collectors and Metrics. -func NewPedanticRegistry() *Registry { - r := NewRegistry() - r.pedanticChecksEnabled = true - return r -} - -// Registerer is the interface for the part of a registry in charge of -// registering and unregistering. Users of custom registries should use -// Registerer as type for registration purposes (rather than the Registry type -// directly). In that way, they are free to use custom Registerer implementation -// (e.g. for testing purposes). -type Registerer interface { - // Register registers a new Collector to be included in metrics - // collection. It returns an error if the descriptors provided by the - // Collector are invalid or if they — in combination with descriptors of - // already registered Collectors — do not fulfill the consistency and - // uniqueness criteria described in the documentation of metric.Desc. - // - // If the provided Collector is equal to a Collector already registered - // (which includes the case of re-registering the same Collector), the - // returned error is an instance of AlreadyRegisteredError, which - // contains the previously registered Collector. - // - // A Collector whose Describe method does not yield any Desc is treated - // as unchecked. Registration will always succeed. No check for - // re-registering (see previous paragraph) is performed. Thus, the - // caller is responsible for not double-registering the same unchecked - // Collector, and for providing a Collector that will not cause - // inconsistent metrics on collection. (This would lead to scrape - // errors.) - Register(Collector) error - // MustRegister works like Register but registers any number of - // Collectors and panics upon the first registration that causes an - // error. - MustRegister(...Collector) - // Unregister unregisters the Collector that equals the Collector passed - // in as an argument. (Two Collectors are considered equal if their - // Describe method yields the same set of descriptors.) The function - // returns whether a Collector was unregistered. Note that an unchecked - // Collector cannot be unregistered (as its Describe method does not - // yield any descriptor). - // - // Note that even after unregistering, it will not be possible to - // register a new Collector that is inconsistent with the unregistered - // Collector, e.g. a Collector collecting metrics with the same name but - // a different help string. The rationale here is that the same registry - // instance must only collect consistent metrics throughout its - // lifetime. - Unregister(Collector) bool -} - -// Gatherer is the interface for the part of a registry in charge of gathering -// the collected metrics into a number of MetricFamilies. The Gatherer interface -// comes with the same general implication as described for the Registerer -// interface. -type Gatherer interface { - // Gather calls the Collect method of the registered Collectors and then - // gathers the collected metrics into a lexicographically sorted slice - // of uniquely named MetricFamily protobufs. Gather ensures that the - // returned slice is valid and self-consistent so that it can be used - // for valid exposition. As an exception to the strict consistency - // requirements described for metric.Desc, Gather will tolerate - // different sets of label names for metrics of the same metric family. - // - // Even if an error occurs, Gather attempts to gather as many metrics as - // possible. Hence, if a non-nil error is returned, the returned - // MetricFamily slice could be nil (in case of a fatal error that - // prevented any meaningful metric collection) or contain a number of - // MetricFamily protobufs, some of which might be incomplete, and some - // might be missing altogether. The returned error (which might be a - // MultiError) explains the details. Note that this is mostly useful for - // debugging purposes. If the gathered protobufs are to be used for - // exposition in actual monitoring, it is almost always better to not - // expose an incomplete result and instead disregard the returned - // MetricFamily protobufs in case the returned error is non-nil. - Gather() ([]*dto.MetricFamily, error) -} - -// Register registers the provided Collector with the DefaultRegisterer. -// -// Register is a shortcut for DefaultRegisterer.Register(c). See there for more -// details. -func Register(c Collector) error { - return DefaultRegisterer.Register(c) -} - -// MustRegister registers the provided Collectors with the DefaultRegisterer and -// panics if any error occurs. -// -// MustRegister is a shortcut for DefaultRegisterer.MustRegister(cs...). See -// there for more details. -func MustRegister(cs ...Collector) { - DefaultRegisterer.MustRegister(cs...) -} - -// Unregister removes the registration of the provided Collector from the -// DefaultRegisterer. -// -// Unregister is a shortcut for DefaultRegisterer.Unregister(c). See there for -// more details. -func Unregister(c Collector) bool { - return DefaultRegisterer.Unregister(c) -} - -// GathererFunc turns a function into a Gatherer. -type GathererFunc func() ([]*dto.MetricFamily, error) - -// Gather implements Gatherer. -func (gf GathererFunc) Gather() ([]*dto.MetricFamily, error) { - return gf() -} - -// AlreadyRegisteredError is returned by the Register method if the Collector to -// be registered has already been registered before, or a different Collector -// that collects the same metrics has been registered before. Registration fails -// in that case, but you can detect from the kind of error what has -// happened. The error contains fields for the existing Collector and the -// (rejected) new Collector that equals the existing one. This can be used to -// find out if an equal Collector has been registered before and switch over to -// using the old one, as demonstrated in the example. -type AlreadyRegisteredError struct { - ExistingCollector, NewCollector Collector -} - -func (err AlreadyRegisteredError) Error() string { - return "duplicate metrics collector registration attempted" -} - -// MultiError is a slice of errors implementing the error interface. It is used -// by a Gatherer to report multiple errors during MetricFamily gathering. -type MultiError []error - -// Error formats the contained errors as a bullet point list, preceded by the -// total number of errors. Note that this results in a multi-line string. -func (errs MultiError) Error() string { - if len(errs) == 0 { - return "" - } - buf := &bytes.Buffer{} - fmt.Fprintf(buf, "%d error(s) occurred:", len(errs)) - for _, err := range errs { - fmt.Fprintf(buf, "\n* %s", err) - } - return buf.String() -} - -// Append appends the provided error if it is not nil. -func (errs *MultiError) Append(err error) { - if err != nil { - *errs = append(*errs, err) - } -} - -// MaybeUnwrap returns nil if len(errs) is 0. It returns the first and only -// contained error as error if len(errs is 1). In all other cases, it returns -// the MultiError directly. This is helpful for returning a MultiError in a way -// that only uses the MultiError if needed. -func (errs MultiError) MaybeUnwrap() error { - switch len(errs) { - case 0: - return nil - case 1: - return errs[0] - default: - return errs - } -} - -// Registry registers Prometheus collectors, collects their metrics, and gathers -// them into MetricFamilies for exposition. It implements Registerer, Gatherer, -// and Collector. The zero value is not usable. Create instances with -// NewRegistry or NewPedanticRegistry. -// -// Registry implements Collector to allow it to be used for creating groups of -// metrics. See the Grouping example for how this can be done. -type Registry struct { - mtx sync.RWMutex - collectorsByID map[uint64]Collector // ID is a hash of the descIDs. - descIDs map[uint64]struct{} - dimHashesByName map[string]uint64 - uncheckedCollectors []Collector - pedanticChecksEnabled bool -} - -// Register implements Registerer. -func (r *Registry) Register(c Collector) error { - var ( - descChan = make(chan *Desc, capDescChan) - newDescIDs = map[uint64]struct{}{} - newDimHashesByName = map[string]uint64{} - collectorID uint64 // All desc IDs XOR'd together. - duplicateDescErr error - ) - go func() { - c.Describe(descChan) - close(descChan) - }() - r.mtx.Lock() - defer func() { - // Drain channel in case of premature return to not leak a goroutine. - for range descChan { - } - r.mtx.Unlock() - }() - // Conduct various tests... - for desc := range descChan { - - // Is the descriptor valid at all? - if desc.err != nil { - return fmt.Errorf("descriptor %s is invalid: %w", desc, desc.err) - } - - // Is the descID unique? - // (In other words: Is the fqName + constLabel combination unique?) - if _, exists := r.descIDs[desc.id]; exists { - duplicateDescErr = fmt.Errorf("descriptor %s already exists with the same fully-qualified name and const label values", desc) - } - // If it is not a duplicate desc in this collector, XOR it to - // the collectorID. (We allow duplicate descs within the same - // collector, but their existence must be a no-op.) - if _, exists := newDescIDs[desc.id]; !exists { - newDescIDs[desc.id] = struct{}{} - collectorID ^= desc.id - } - - // Are all the label names and the help string consistent with - // previous descriptors of the same name? - // First check existing descriptors... - if dimHash, exists := r.dimHashesByName[desc.fqName]; exists { - if dimHash != desc.dimHash { - return fmt.Errorf("a previously registered descriptor with the same fully-qualified name as %s has different label names or a different help string", desc) - } - continue - } - - // ...then check the new descriptors already seen. - if dimHash, exists := newDimHashesByName[desc.fqName]; exists { - if dimHash != desc.dimHash { - return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc) - } - continue - } - newDimHashesByName[desc.fqName] = desc.dimHash - } - // A Collector yielding no Desc at all is considered unchecked. - if len(newDescIDs) == 0 { - r.uncheckedCollectors = append(r.uncheckedCollectors, c) - return nil - } - if existing, exists := r.collectorsByID[collectorID]; exists { - switch e := existing.(type) { - case *wrappingCollector: - return AlreadyRegisteredError{ - ExistingCollector: e.unwrapRecursively(), - NewCollector: c, - } - default: - return AlreadyRegisteredError{ - ExistingCollector: e, - NewCollector: c, - } - } - } - // If the collectorID is new, but at least one of the descs existed - // before, we are in trouble. - if duplicateDescErr != nil { - return duplicateDescErr - } - - // Only after all tests have passed, actually register. - r.collectorsByID[collectorID] = c - for hash := range newDescIDs { - r.descIDs[hash] = struct{}{} - } - for name, dimHash := range newDimHashesByName { - r.dimHashesByName[name] = dimHash - } - return nil -} - -// Unregister implements Registerer. -func (r *Registry) Unregister(c Collector) bool { - var ( - descChan = make(chan *Desc, capDescChan) - descIDs = map[uint64]struct{}{} - collectorID uint64 // All desc IDs XOR'd together. - ) - go func() { - c.Describe(descChan) - close(descChan) - }() - for desc := range descChan { - if _, exists := descIDs[desc.id]; !exists { - collectorID ^= desc.id - descIDs[desc.id] = struct{}{} - } - } - - r.mtx.RLock() - if _, exists := r.collectorsByID[collectorID]; !exists { - r.mtx.RUnlock() - return false - } - r.mtx.RUnlock() - - r.mtx.Lock() - defer r.mtx.Unlock() - - delete(r.collectorsByID, collectorID) - for id := range descIDs { - delete(r.descIDs, id) - } - // dimHashesByName is left untouched as those must be consistent - // throughout the lifetime of a program. - return true -} - -// MustRegister implements Registerer. -func (r *Registry) MustRegister(cs ...Collector) { - for _, c := range cs { - if err := r.Register(c); err != nil { - panic(err) - } - } -} - -// Gather implements Gatherer. -func (r *Registry) Gather() ([]*dto.MetricFamily, error) { - r.mtx.RLock() - - if len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 { - // Fast path. - r.mtx.RUnlock() - return nil, nil - } - - var ( - checkedMetricChan = make(chan Metric, capMetricChan) - uncheckedMetricChan = make(chan Metric, capMetricChan) - metricHashes = map[uint64]struct{}{} - wg sync.WaitGroup - errs MultiError // The collected errors to return in the end. - registeredDescIDs map[uint64]struct{} // Only used for pedantic checks - ) - - goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors) - metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName)) - checkedCollectors := make(chan Collector, len(r.collectorsByID)) - uncheckedCollectors := make(chan Collector, len(r.uncheckedCollectors)) - for _, collector := range r.collectorsByID { - checkedCollectors <- collector - } - for _, collector := range r.uncheckedCollectors { - uncheckedCollectors <- collector - } - // In case pedantic checks are enabled, we have to copy the map before - // giving up the RLock. - if r.pedanticChecksEnabled { - registeredDescIDs = make(map[uint64]struct{}, len(r.descIDs)) - for id := range r.descIDs { - registeredDescIDs[id] = struct{}{} - } - } - r.mtx.RUnlock() - - wg.Add(goroutineBudget) - - collectWorker := func() { - for { - select { - case collector := <-checkedCollectors: - collector.Collect(checkedMetricChan) - case collector := <-uncheckedCollectors: - collector.Collect(uncheckedMetricChan) - default: - return - } - wg.Done() - } - } - - // Start the first worker now to make sure at least one is running. - go collectWorker() - goroutineBudget-- - - // Close checkedMetricChan and uncheckedMetricChan once all collectors - // are collected. - go func() { - wg.Wait() - close(checkedMetricChan) - close(uncheckedMetricChan) - }() - - // Drain checkedMetricChan and uncheckedMetricChan in case of premature return. - defer func() { - if checkedMetricChan != nil { - for range checkedMetricChan { - } - } - if uncheckedMetricChan != nil { - for range uncheckedMetricChan { - } - } - }() - - // Copy the channel references so we can nil them out later to remove - // them from the select statements below. - cmc := checkedMetricChan - umc := uncheckedMetricChan - - for { - select { - case metric, ok := <-cmc: - if !ok { - cmc = nil - break - } - errs.Append(processMetric( - metric, metricFamiliesByName, - metricHashes, - registeredDescIDs, - )) - case metric, ok := <-umc: - if !ok { - umc = nil - break - } - errs.Append(processMetric( - metric, metricFamiliesByName, - metricHashes, - nil, - )) - default: - if goroutineBudget <= 0 || len(checkedCollectors)+len(uncheckedCollectors) == 0 { - // All collectors are already being worked on or - // we have already as many goroutines started as - // there are collectors. Do the same as above, - // just without the default. - select { - case metric, ok := <-cmc: - if !ok { - cmc = nil - break - } - errs.Append(processMetric( - metric, metricFamiliesByName, - metricHashes, - registeredDescIDs, - )) - case metric, ok := <-umc: - if !ok { - umc = nil - break - } - errs.Append(processMetric( - metric, metricFamiliesByName, - metricHashes, - nil, - )) - } - break - } - // Start more workers. - go collectWorker() - goroutineBudget-- - runtime.Gosched() - } - // Once both checkedMetricChan and uncheckedMetricChan are closed - // and drained, the contraption above will nil out cmc and umc, - // and then we can leave the collect loop here. - if cmc == nil && umc == nil { - break - } - } - return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap() -} - -// Describe implements Collector. -func (r *Registry) Describe(ch chan<- *Desc) { - r.mtx.RLock() - defer r.mtx.RUnlock() - - // Only report the checked Collectors; unchecked collectors don't report any - // Desc. - for _, c := range r.collectorsByID { - c.Describe(ch) - } -} - -// Collect implements Collector. -func (r *Registry) Collect(ch chan<- Metric) { - r.mtx.RLock() - defer r.mtx.RUnlock() - - for _, c := range r.collectorsByID { - c.Collect(ch) - } - for _, c := range r.uncheckedCollectors { - c.Collect(ch) - } -} - -// WriteToTextfile calls Gather on the provided Gatherer, encodes the result in the -// Prometheus text format, and writes it to a temporary file. Upon success, the -// temporary file is renamed to the provided filename. -// -// This is intended for use with the textfile collector of the node exporter. -// Note that the node exporter expects the filename to be suffixed with ".prom". -func WriteToTextfile(filename string, g Gatherer) error { - tmp, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)) - if err != nil { - return err - } - defer os.Remove(tmp.Name()) - - mfs, err := g.Gather() - if err != nil { - return err - } - for _, mf := range mfs { - if _, err := expfmt.MetricFamilyToText(tmp, mf); err != nil { - return err - } - } - if err := tmp.Close(); err != nil { - return err - } - - if err := os.Chmod(tmp.Name(), 0o644); err != nil { - return err - } - return os.Rename(tmp.Name(), filename) -} - -// processMetric is an internal helper method only used by the Gather method. -func processMetric( - metric Metric, - metricFamiliesByName map[string]*dto.MetricFamily, - metricHashes map[uint64]struct{}, - registeredDescIDs map[uint64]struct{}, -) error { - desc := metric.Desc() - // Wrapped metrics collected by an unchecked Collector can have an - // invalid Desc. - if desc.err != nil { - return desc.err - } - dtoMetric := &dto.Metric{} - if err := metric.Write(dtoMetric); err != nil { - return fmt.Errorf("error collecting metric %v: %w", desc, err) - } - metricFamily, ok := metricFamiliesByName[desc.fqName] - if ok { // Existing name. - if metricFamily.GetHelp() != desc.help { - return fmt.Errorf( - "collected metric %s %s has help %q but should have %q", - desc.fqName, dtoMetric, desc.help, metricFamily.GetHelp(), - ) - } - // TODO(beorn7): Simplify switch once Desc has type. - switch metricFamily.GetType() { - case dto.MetricType_COUNTER: - if dtoMetric.Counter == nil { - return fmt.Errorf( - "collected metric %s %s should be a Counter", - desc.fqName, dtoMetric, - ) - } - case dto.MetricType_GAUGE: - if dtoMetric.Gauge == nil { - return fmt.Errorf( - "collected metric %s %s should be a Gauge", - desc.fqName, dtoMetric, - ) - } - case dto.MetricType_SUMMARY: - if dtoMetric.Summary == nil { - return fmt.Errorf( - "collected metric %s %s should be a Summary", - desc.fqName, dtoMetric, - ) - } - case dto.MetricType_UNTYPED: - if dtoMetric.Untyped == nil { - return fmt.Errorf( - "collected metric %s %s should be Untyped", - desc.fqName, dtoMetric, - ) - } - case dto.MetricType_HISTOGRAM: - if dtoMetric.Histogram == nil { - return fmt.Errorf( - "collected metric %s %s should be a Histogram", - desc.fqName, dtoMetric, - ) - } - default: - panic("encountered MetricFamily with invalid type") - } - } else { // New name. - metricFamily = &dto.MetricFamily{} - metricFamily.Name = proto.String(desc.fqName) - metricFamily.Help = proto.String(desc.help) - // TODO(beorn7): Simplify switch once Desc has type. - switch { - case dtoMetric.Gauge != nil: - metricFamily.Type = dto.MetricType_GAUGE.Enum() - case dtoMetric.Counter != nil: - metricFamily.Type = dto.MetricType_COUNTER.Enum() - case dtoMetric.Summary != nil: - metricFamily.Type = dto.MetricType_SUMMARY.Enum() - case dtoMetric.Untyped != nil: - metricFamily.Type = dto.MetricType_UNTYPED.Enum() - case dtoMetric.Histogram != nil: - metricFamily.Type = dto.MetricType_HISTOGRAM.Enum() - default: - return fmt.Errorf("empty metric collected: %s", dtoMetric) - } - if err := checkSuffixCollisions(metricFamily, metricFamiliesByName); err != nil { - return err - } - metricFamiliesByName[desc.fqName] = metricFamily - } - if err := checkMetricConsistency(metricFamily, dtoMetric, metricHashes); err != nil { - return err - } - if registeredDescIDs != nil { - // Is the desc registered at all? - if _, exist := registeredDescIDs[desc.id]; !exist { - return fmt.Errorf( - "collected metric %s %s with unregistered descriptor %s", - metricFamily.GetName(), dtoMetric, desc, - ) - } - if err := checkDescConsistency(metricFamily, dtoMetric, desc); err != nil { - return err - } - } - metricFamily.Metric = append(metricFamily.Metric, dtoMetric) - return nil -} - -// Gatherers is a slice of Gatherer instances that implements the Gatherer -// interface itself. Its Gather method calls Gather on all Gatherers in the -// slice in order and returns the merged results. Errors returned from the -// Gather calls are all returned in a flattened MultiError. Duplicate and -// inconsistent Metrics are skipped (first occurrence in slice order wins) and -// reported in the returned error. -// -// Gatherers can be used to merge the Gather results from multiple -// Registries. It also provides a way to directly inject existing MetricFamily -// protobufs into the gathering by creating a custom Gatherer with a Gather -// method that simply returns the existing MetricFamily protobufs. Note that no -// registration is involved (in contrast to Collector registration), so -// obviously registration-time checks cannot happen. Any inconsistencies between -// the gathered MetricFamilies are reported as errors by the Gather method, and -// inconsistent Metrics are dropped. Invalid parts of the MetricFamilies -// (e.g. syntactically invalid metric or label names) will go undetected. -type Gatherers []Gatherer - -// Gather implements Gatherer. -func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) { - var ( - metricFamiliesByName = map[string]*dto.MetricFamily{} - metricHashes = map[uint64]struct{}{} - errs MultiError // The collected errors to return in the end. - ) - - for i, g := range gs { - mfs, err := g.Gather() - if err != nil { - multiErr := MultiError{} - if errors.As(err, &multiErr) { - for _, err := range multiErr { - errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) - } - } else { - errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) - } - } - for _, mf := range mfs { - existingMF, exists := metricFamiliesByName[mf.GetName()] - if exists { - if existingMF.GetHelp() != mf.GetHelp() { - errs = append(errs, fmt.Errorf( - "gathered metric family %s has help %q but should have %q", - mf.GetName(), mf.GetHelp(), existingMF.GetHelp(), - )) - continue - } - if existingMF.GetType() != mf.GetType() { - errs = append(errs, fmt.Errorf( - "gathered metric family %s has type %s but should have %s", - mf.GetName(), mf.GetType(), existingMF.GetType(), - )) - continue - } - } else { - existingMF = &dto.MetricFamily{} - existingMF.Name = mf.Name - existingMF.Help = mf.Help - existingMF.Type = mf.Type - if err := checkSuffixCollisions(existingMF, metricFamiliesByName); err != nil { - errs = append(errs, err) - continue - } - metricFamiliesByName[mf.GetName()] = existingMF - } - for _, m := range mf.Metric { - if err := checkMetricConsistency(existingMF, m, metricHashes); err != nil { - errs = append(errs, err) - continue - } - existingMF.Metric = append(existingMF.Metric, m) - } - } - } - return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap() -} - -// checkSuffixCollisions checks for collisions with the “magic” suffixes the -// Prometheus text format and the internal metric representation of the -// Prometheus server add while flattening Summaries and Histograms. -func checkSuffixCollisions(mf *dto.MetricFamily, mfs map[string]*dto.MetricFamily) error { - var ( - newName = mf.GetName() - newType = mf.GetType() - newNameWithoutSuffix = "" - ) - switch { - case strings.HasSuffix(newName, "_count"): - newNameWithoutSuffix = newName[:len(newName)-6] - case strings.HasSuffix(newName, "_sum"): - newNameWithoutSuffix = newName[:len(newName)-4] - case strings.HasSuffix(newName, "_bucket"): - newNameWithoutSuffix = newName[:len(newName)-7] - } - if newNameWithoutSuffix != "" { - if existingMF, ok := mfs[newNameWithoutSuffix]; ok { - switch existingMF.GetType() { - case dto.MetricType_SUMMARY: - if !strings.HasSuffix(newName, "_bucket") { - return fmt.Errorf( - "collected metric named %q collides with previously collected summary named %q", - newName, newNameWithoutSuffix, - ) - } - case dto.MetricType_HISTOGRAM: - return fmt.Errorf( - "collected metric named %q collides with previously collected histogram named %q", - newName, newNameWithoutSuffix, - ) - } - } - } - if newType == dto.MetricType_SUMMARY || newType == dto.MetricType_HISTOGRAM { - if _, ok := mfs[newName+"_count"]; ok { - return fmt.Errorf( - "collected histogram or summary named %q collides with previously collected metric named %q", - newName, newName+"_count", - ) - } - if _, ok := mfs[newName+"_sum"]; ok { - return fmt.Errorf( - "collected histogram or summary named %q collides with previously collected metric named %q", - newName, newName+"_sum", - ) - } - } - if newType == dto.MetricType_HISTOGRAM { - if _, ok := mfs[newName+"_bucket"]; ok { - return fmt.Errorf( - "collected histogram named %q collides with previously collected metric named %q", - newName, newName+"_bucket", - ) - } - } - return nil -} - -// checkMetricConsistency checks if the provided Metric is consistent with the -// provided MetricFamily. It also hashes the Metric labels and the MetricFamily -// name. If the resulting hash is already in the provided metricHashes, an error -// is returned. If not, it is added to metricHashes. -func checkMetricConsistency( - metricFamily *dto.MetricFamily, - dtoMetric *dto.Metric, - metricHashes map[uint64]struct{}, -) error { - name := metricFamily.GetName() - - // Type consistency with metric family. - if metricFamily.GetType() == dto.MetricType_GAUGE && dtoMetric.Gauge == nil || - metricFamily.GetType() == dto.MetricType_COUNTER && dtoMetric.Counter == nil || - metricFamily.GetType() == dto.MetricType_SUMMARY && dtoMetric.Summary == nil || - metricFamily.GetType() == dto.MetricType_HISTOGRAM && dtoMetric.Histogram == nil || - metricFamily.GetType() == dto.MetricType_UNTYPED && dtoMetric.Untyped == nil { - return fmt.Errorf( - "collected metric %q { %s} is not a %s", - name, dtoMetric, metricFamily.GetType(), - ) - } - - previousLabelName := "" - for _, labelPair := range dtoMetric.GetLabel() { - labelName := labelPair.GetName() - if labelName == previousLabelName { - return fmt.Errorf( - "collected metric %q { %s} has two or more labels with the same name: %s", - name, dtoMetric, labelName, - ) - } - if !checkLabelName(labelName) { - return fmt.Errorf( - "collected metric %q { %s} has a label with an invalid name: %s", - name, dtoMetric, labelName, - ) - } - if dtoMetric.Summary != nil && labelName == quantileLabel { - return fmt.Errorf( - "collected metric %q { %s} must not have an explicit %q label", - name, dtoMetric, quantileLabel, - ) - } - if !utf8.ValidString(labelPair.GetValue()) { - return fmt.Errorf( - "collected metric %q { %s} has a label named %q whose value is not utf8: %#v", - name, dtoMetric, labelName, labelPair.GetValue()) - } - previousLabelName = labelName - } - - // Is the metric unique (i.e. no other metric with the same name and the same labels)? - h := xxhash.New() - h.WriteString(name) - h.Write(separatorByteSlice) - // Make sure label pairs are sorted. We depend on it for the consistency - // check. - if !sort.IsSorted(internal.LabelPairSorter(dtoMetric.Label)) { - // We cannot sort dtoMetric.Label in place as it is immutable by contract. - copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label)) - copy(copiedLabels, dtoMetric.Label) - sort.Sort(internal.LabelPairSorter(copiedLabels)) - dtoMetric.Label = copiedLabels - } - for _, lp := range dtoMetric.Label { - h.WriteString(lp.GetName()) - h.Write(separatorByteSlice) - h.WriteString(lp.GetValue()) - h.Write(separatorByteSlice) - } - if dtoMetric.TimestampMs != nil { - h.WriteString(strconv.FormatInt(*(dtoMetric.TimestampMs), 10)) - h.Write(separatorByteSlice) - } - hSum := h.Sum64() - if _, exists := metricHashes[hSum]; exists { - return fmt.Errorf( - "collected metric %q { %s} was collected before with the same name and label values", - name, dtoMetric, - ) - } - metricHashes[hSum] = struct{}{} - return nil -} - -func checkDescConsistency( - metricFamily *dto.MetricFamily, - dtoMetric *dto.Metric, - desc *Desc, -) error { - // Desc help consistency with metric family help. - if metricFamily.GetHelp() != desc.help { - return fmt.Errorf( - "collected metric %s %s has help %q but should have %q", - metricFamily.GetName(), dtoMetric, metricFamily.GetHelp(), desc.help, - ) - } - - // Is the desc consistent with the content of the metric? - lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label)) - copy(lpsFromDesc, desc.constLabelPairs) - for _, l := range desc.variableLabels.names { - lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{ - Name: proto.String(l), - }) - } - if len(lpsFromDesc) != len(dtoMetric.Label) { - return fmt.Errorf( - "labels in collected metric %s %s are inconsistent with descriptor %s", - metricFamily.GetName(), dtoMetric, desc, - ) - } - sort.Sort(internal.LabelPairSorter(lpsFromDesc)) - for i, lpFromDesc := range lpsFromDesc { - lpFromMetric := dtoMetric.Label[i] - if lpFromDesc.GetName() != lpFromMetric.GetName() || - lpFromDesc.Value != nil && lpFromDesc.GetValue() != lpFromMetric.GetValue() { - return fmt.Errorf( - "labels in collected metric %s %s are inconsistent with descriptor %s", - metricFamily.GetName(), dtoMetric, desc, - ) - } - } - return nil -} - -var _ TransactionalGatherer = &MultiTRegistry{} - -// MultiTRegistry is a TransactionalGatherer that joins gathered metrics from multiple -// transactional gatherers. -// -// It is caller responsibility to ensure two registries have mutually exclusive metric families, -// no deduplication will happen. -type MultiTRegistry struct { - tGatherers []TransactionalGatherer -} - -// NewMultiTRegistry creates MultiTRegistry. -func NewMultiTRegistry(tGatherers ...TransactionalGatherer) *MultiTRegistry { - return &MultiTRegistry{ - tGatherers: tGatherers, - } -} - -// Gather implements TransactionalGatherer interface. -func (r *MultiTRegistry) Gather() (mfs []*dto.MetricFamily, done func(), err error) { - errs := MultiError{} - - dFns := make([]func(), 0, len(r.tGatherers)) - // TODO(bwplotka): Implement concurrency for those? - for _, g := range r.tGatherers { - // TODO(bwplotka): Check for duplicates? - m, d, err := g.Gather() - errs.Append(err) - - mfs = append(mfs, m...) - dFns = append(dFns, d) - } - - // TODO(bwplotka): Consider sort in place, given metric family in gather is sorted already. - sort.Slice(mfs, func(i, j int) bool { - return *mfs[i].Name < *mfs[j].Name - }) - return mfs, func() { - for _, d := range dFns { - d() - } - }, errs.MaybeUnwrap() -} - -// TransactionalGatherer represents transactional gatherer that can be triggered to notify gatherer that memory -// used by metric family is no longer used by a caller. This allows implementations with cache. -type TransactionalGatherer interface { - // Gather returns metrics in a lexicographically sorted slice - // of uniquely named MetricFamily protobufs. Gather ensures that the - // returned slice is valid and self-consistent so that it can be used - // for valid exposition. As an exception to the strict consistency - // requirements described for metric.Desc, Gather will tolerate - // different sets of label names for metrics of the same metric family. - // - // Even if an error occurs, Gather attempts to gather as many metrics as - // possible. Hence, if a non-nil error is returned, the returned - // MetricFamily slice could be nil (in case of a fatal error that - // prevented any meaningful metric collection) or contain a number of - // MetricFamily protobufs, some of which might be incomplete, and some - // might be missing altogether. The returned error (which might be a - // MultiError) explains the details. Note that this is mostly useful for - // debugging purposes. If the gathered protobufs are to be used for - // exposition in actual monitoring, it is almost always better to not - // expose an incomplete result and instead disregard the returned - // MetricFamily protobufs in case the returned error is non-nil. - // - // Important: done is expected to be triggered (even if the error occurs!) - // once caller does not need returned slice of dto.MetricFamily. - Gather() (_ []*dto.MetricFamily, done func(), err error) -} - -// ToTransactionalGatherer transforms Gatherer to transactional one with noop as done function. -func ToTransactionalGatherer(g Gatherer) TransactionalGatherer { - return &noTransactionGatherer{g: g} -} - -type noTransactionGatherer struct { - g Gatherer -} - -// Gather implements TransactionalGatherer interface. -func (g *noTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) { - mfs, err := g.g.Gather() - return mfs, func() {}, err -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go deleted file mode 100644 index ac5203c6faa5..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go +++ /dev/null @@ -1,830 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "fmt" - "math" - "runtime" - "sort" - "sync" - "sync/atomic" - "time" - - dto "github.com/prometheus/client_model/go" - - "github.com/beorn7/perks/quantile" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -// quantileLabel is used for the label that defines the quantile in a -// summary. -const quantileLabel = "quantile" - -// A Summary captures individual observations from an event or sample stream and -// summarizes them in a manner similar to traditional summary statistics: 1. sum -// of observations, 2. observation count, 3. rank estimations. -// -// A typical use-case is the observation of request latencies. By default, a -// Summary provides the median, the 90th and the 99th percentile of the latency -// as rank estimations. However, the default behavior will change in the -// upcoming v1.0.0 of the library. There will be no rank estimations at all by -// default. For a sane transition, it is recommended to set the desired rank -// estimations explicitly. -// -// Note that the rank estimations cannot be aggregated in a meaningful way with -// the Prometheus query language (i.e. you cannot average or add them). If you -// need aggregatable quantiles (e.g. you want the 99th percentile latency of all -// queries served across all instances of a service), consider the Histogram -// metric type. See the Prometheus documentation for more details. -// -// To create Summary instances, use NewSummary. -type Summary interface { - Metric - Collector - - // Observe adds a single observation to the summary. Observations are - // usually positive or zero. Negative observations are accepted but - // prevent current versions of Prometheus from properly detecting - // counter resets in the sum of observations. See - // https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations - // for details. - Observe(float64) -} - -var errQuantileLabelNotAllowed = fmt.Errorf( - "%q is not allowed as label name in summaries", quantileLabel, -) - -// Default values for SummaryOpts. -const ( - // DefMaxAge is the default duration for which observations stay - // relevant. - DefMaxAge time.Duration = 10 * time.Minute - // DefAgeBuckets is the default number of buckets used to calculate the - // age of observations. - DefAgeBuckets = 5 - // DefBufCap is the standard buffer size for collecting Summary observations. - DefBufCap = 500 -) - -// SummaryOpts bundles the options for creating a Summary metric. It is -// mandatory to set Name to a non-empty string. While all other fields are -// optional and can safely be left at their zero value, it is recommended to set -// a help string and to explicitly set the Objectives field to the desired value -// as the default value will change in the upcoming v1.0.0 of the library. -type SummaryOpts struct { - // Namespace, Subsystem, and Name are components of the fully-qualified - // name of the Summary (created by joining these components with - // "_"). Only Name is mandatory, the others merely help structuring the - // name. Note that the fully-qualified name of the Summary must be a - // valid Prometheus metric name. - Namespace string - Subsystem string - Name string - - // Help provides information about this Summary. - // - // Metrics with the same fully-qualified name must have the same Help - // string. - Help string - - // ConstLabels are used to attach fixed labels to this metric. Metrics - // with the same fully-qualified name must have the same label names in - // their ConstLabels. - // - // Due to the way a Summary is represented in the Prometheus text format - // and how it is handled by the Prometheus server internally, “quantile” - // is an illegal label name. Construction of a Summary or SummaryVec - // will panic if this label name is used in ConstLabels. - // - // ConstLabels are only used rarely. In particular, do not use them to - // attach the same labels to all your metrics. Those use cases are - // better covered by target labels set by the scraping Prometheus - // server, or by one specific metric (e.g. a build_info or a - // machine_role metric). See also - // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels - ConstLabels Labels - - // Objectives defines the quantile rank estimates with their respective - // absolute error. If Objectives[q] = e, then the value reported for q - // will be the φ-quantile value for some φ between q-e and q+e. The - // default value is an empty map, resulting in a summary without - // quantiles. - Objectives map[float64]float64 - - // MaxAge defines the duration for which an observation stays relevant - // for the summary. Only applies to pre-calculated quantiles, does not - // apply to _sum and _count. Must be positive. The default value is - // DefMaxAge. - MaxAge time.Duration - - // AgeBuckets is the number of buckets used to exclude observations that - // are older than MaxAge from the summary. A higher number has a - // resource penalty, so only increase it if the higher resolution is - // really required. For very high observation rates, you might want to - // reduce the number of age buckets. With only one age bucket, you will - // effectively see a complete reset of the summary each time MaxAge has - // passed. The default value is DefAgeBuckets. - AgeBuckets uint32 - - // BufCap defines the default sample stream buffer size. The default - // value of DefBufCap should suffice for most uses. If there is a need - // to increase the value, a multiple of 500 is recommended (because that - // is the internal buffer size of the underlying package - // "github.com/bmizerany/perks/quantile"). - BufCap uint32 - - // now is for testing purposes, by default it's time.Now. - now func() time.Time -} - -// SummaryVecOpts bundles the options to create a SummaryVec metric. -// It is mandatory to set SummaryOpts, see there for mandatory fields. VariableLabels -// is optional and can safely be left to its default value. -type SummaryVecOpts struct { - SummaryOpts - - // VariableLabels are used to partition the metric vector by the given set - // of labels. Each label value will be constrained with the optional Constraint - // function, if provided. - VariableLabels ConstrainableLabels -} - -// Problem with the sliding-window decay algorithm... The Merge method of -// perk/quantile is actually not working as advertised - and it might be -// unfixable, as the underlying algorithm is apparently not capable of merging -// summaries in the first place. To avoid using Merge, we are currently adding -// observations to _each_ age bucket, i.e. the effort to add a sample is -// essentially multiplied by the number of age buckets. When rotating age -// buckets, we empty the previous head stream. On scrape time, we simply take -// the quantiles from the head stream (no merging required). Result: More effort -// on observation time, less effort on scrape time, which is exactly the -// opposite of what we try to accomplish, but at least the results are correct. -// -// The quite elegant previous contraption to merge the age buckets efficiently -// on scrape time (see code up commit 6b9530d72ea715f0ba612c0120e6e09fbf1d49d0) -// can't be used anymore. - -// NewSummary creates a new Summary based on the provided SummaryOpts. -func NewSummary(opts SummaryOpts) Summary { - return newSummary( - NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - nil, - opts.ConstLabels, - ), - opts, - ) -} - -func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary { - if len(desc.variableLabels.names) != len(labelValues) { - panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues)) - } - - for _, n := range desc.variableLabels.names { - if n == quantileLabel { - panic(errQuantileLabelNotAllowed) - } - } - for _, lp := range desc.constLabelPairs { - if lp.GetName() == quantileLabel { - panic(errQuantileLabelNotAllowed) - } - } - - if opts.Objectives == nil { - opts.Objectives = map[float64]float64{} - } - - if opts.MaxAge < 0 { - panic(fmt.Errorf("illegal max age MaxAge=%v", opts.MaxAge)) - } - if opts.MaxAge == 0 { - opts.MaxAge = DefMaxAge - } - - if opts.AgeBuckets == 0 { - opts.AgeBuckets = DefAgeBuckets - } - - if opts.BufCap == 0 { - opts.BufCap = DefBufCap - } - - if opts.now == nil { - opts.now = time.Now - } - if len(opts.Objectives) == 0 { - // Use the lock-free implementation of a Summary without objectives. - s := &noObjectivesSummary{ - desc: desc, - labelPairs: MakeLabelPairs(desc, labelValues), - counts: [2]*summaryCounts{{}, {}}, - } - s.init(s) // Init self-collection. - s.createdTs = timestamppb.New(opts.now()) - return s - } - - s := &summary{ - desc: desc, - now: opts.now, - - objectives: opts.Objectives, - sortedObjectives: make([]float64, 0, len(opts.Objectives)), - - labelPairs: MakeLabelPairs(desc, labelValues), - - hotBuf: make([]float64, 0, opts.BufCap), - coldBuf: make([]float64, 0, opts.BufCap), - streamDuration: opts.MaxAge / time.Duration(opts.AgeBuckets), - } - s.headStreamExpTime = opts.now().Add(s.streamDuration) - s.hotBufExpTime = s.headStreamExpTime - - for i := uint32(0); i < opts.AgeBuckets; i++ { - s.streams = append(s.streams, s.newStream()) - } - s.headStream = s.streams[0] - - for qu := range s.objectives { - s.sortedObjectives = append(s.sortedObjectives, qu) - } - sort.Float64s(s.sortedObjectives) - - s.init(s) // Init self-collection. - s.createdTs = timestamppb.New(opts.now()) - return s -} - -type summary struct { - selfCollector - - bufMtx sync.Mutex // Protects hotBuf and hotBufExpTime. - mtx sync.Mutex // Protects every other moving part. - // Lock bufMtx before mtx if both are needed. - - desc *Desc - - now func() time.Time - - objectives map[float64]float64 - sortedObjectives []float64 - - labelPairs []*dto.LabelPair - - sum float64 - cnt uint64 - - hotBuf, coldBuf []float64 - - streams []*quantile.Stream - streamDuration time.Duration - headStream *quantile.Stream - headStreamIdx int - headStreamExpTime, hotBufExpTime time.Time - - createdTs *timestamppb.Timestamp -} - -func (s *summary) Desc() *Desc { - return s.desc -} - -func (s *summary) Observe(v float64) { - s.bufMtx.Lock() - defer s.bufMtx.Unlock() - - now := s.now() - if now.After(s.hotBufExpTime) { - s.asyncFlush(now) - } - s.hotBuf = append(s.hotBuf, v) - if len(s.hotBuf) == cap(s.hotBuf) { - s.asyncFlush(now) - } -} - -func (s *summary) Write(out *dto.Metric) error { - sum := &dto.Summary{ - CreatedTimestamp: s.createdTs, - } - qs := make([]*dto.Quantile, 0, len(s.objectives)) - - s.bufMtx.Lock() - s.mtx.Lock() - // Swap bufs even if hotBuf is empty to set new hotBufExpTime. - s.swapBufs(s.now()) - s.bufMtx.Unlock() - - s.flushColdBuf() - sum.SampleCount = proto.Uint64(s.cnt) - sum.SampleSum = proto.Float64(s.sum) - - for _, rank := range s.sortedObjectives { - var q float64 - if s.headStream.Count() == 0 { - q = math.NaN() - } else { - q = s.headStream.Query(rank) - } - qs = append(qs, &dto.Quantile{ - Quantile: proto.Float64(rank), - Value: proto.Float64(q), - }) - } - - s.mtx.Unlock() - - if len(qs) > 0 { - sort.Sort(quantSort(qs)) - } - sum.Quantile = qs - - out.Summary = sum - out.Label = s.labelPairs - return nil -} - -func (s *summary) newStream() *quantile.Stream { - return quantile.NewTargeted(s.objectives) -} - -// asyncFlush needs bufMtx locked. -func (s *summary) asyncFlush(now time.Time) { - s.mtx.Lock() - s.swapBufs(now) - - // Unblock the original goroutine that was responsible for the mutation - // that triggered the compaction. But hold onto the global non-buffer - // state mutex until the operation finishes. - go func() { - s.flushColdBuf() - s.mtx.Unlock() - }() -} - -// rotateStreams needs mtx AND bufMtx locked. -func (s *summary) maybeRotateStreams() { - for !s.hotBufExpTime.Equal(s.headStreamExpTime) { - s.headStream.Reset() - s.headStreamIdx++ - if s.headStreamIdx >= len(s.streams) { - s.headStreamIdx = 0 - } - s.headStream = s.streams[s.headStreamIdx] - s.headStreamExpTime = s.headStreamExpTime.Add(s.streamDuration) - } -} - -// flushColdBuf needs mtx locked. -func (s *summary) flushColdBuf() { - for _, v := range s.coldBuf { - for _, stream := range s.streams { - stream.Insert(v) - } - s.cnt++ - s.sum += v - } - s.coldBuf = s.coldBuf[0:0] - s.maybeRotateStreams() -} - -// swapBufs needs mtx AND bufMtx locked, coldBuf must be empty. -func (s *summary) swapBufs(now time.Time) { - if len(s.coldBuf) != 0 { - panic("coldBuf is not empty") - } - s.hotBuf, s.coldBuf = s.coldBuf, s.hotBuf - // hotBuf is now empty and gets new expiration set. - for now.After(s.hotBufExpTime) { - s.hotBufExpTime = s.hotBufExpTime.Add(s.streamDuration) - } -} - -type summaryCounts struct { - // sumBits contains the bits of the float64 representing the sum of all - // observations. sumBits and count have to go first in the struct to - // guarantee alignment for atomic operations. - // http://golang.org/pkg/sync/atomic/#pkg-note-BUG - sumBits uint64 - count uint64 -} - -type noObjectivesSummary struct { - // countAndHotIdx enables lock-free writes with use of atomic updates. - // The most significant bit is the hot index [0 or 1] of the count field - // below. Observe calls update the hot one. All remaining bits count the - // number of Observe calls. Observe starts by incrementing this counter, - // and finish by incrementing the count field in the respective - // summaryCounts, as a marker for completion. - // - // Calls of the Write method (which are non-mutating reads from the - // perspective of the summary) swap the hot–cold under the writeMtx - // lock. A cooldown is awaited (while locked) by comparing the number of - // observations with the initiation count. Once they match, then the - // last observation on the now cool one has completed. All cool fields must - // be merged into the new hot before releasing writeMtx. - - // Fields with atomic access first! See alignment constraint: - // http://golang.org/pkg/sync/atomic/#pkg-note-BUG - countAndHotIdx uint64 - - selfCollector - desc *Desc - writeMtx sync.Mutex // Only used in the Write method. - - // Two counts, one is "hot" for lock-free observations, the other is - // "cold" for writing out a dto.Metric. It has to be an array of - // pointers to guarantee 64bit alignment of the histogramCounts, see - // http://golang.org/pkg/sync/atomic/#pkg-note-BUG. - counts [2]*summaryCounts - - labelPairs []*dto.LabelPair - - createdTs *timestamppb.Timestamp -} - -func (s *noObjectivesSummary) Desc() *Desc { - return s.desc -} - -func (s *noObjectivesSummary) Observe(v float64) { - // We increment h.countAndHotIdx so that the counter in the lower - // 63 bits gets incremented. At the same time, we get the new value - // back, which we can use to find the currently-hot counts. - n := atomic.AddUint64(&s.countAndHotIdx, 1) - hotCounts := s.counts[n>>63] - - for { - oldBits := atomic.LoadUint64(&hotCounts.sumBits) - newBits := math.Float64bits(math.Float64frombits(oldBits) + v) - if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) { - break - } - } - // Increment count last as we take it as a signal that the observation - // is complete. - atomic.AddUint64(&hotCounts.count, 1) -} - -func (s *noObjectivesSummary) Write(out *dto.Metric) error { - // For simplicity, we protect this whole method by a mutex. It is not in - // the hot path, i.e. Observe is called much more often than Write. The - // complication of making Write lock-free isn't worth it, if possible at - // all. - s.writeMtx.Lock() - defer s.writeMtx.Unlock() - - // Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0) - // without touching the count bits. See the struct comments for a full - // description of the algorithm. - n := atomic.AddUint64(&s.countAndHotIdx, 1<<63) - // count is contained unchanged in the lower 63 bits. - count := n & ((1 << 63) - 1) - // The most significant bit tells us which counts is hot. The complement - // is thus the cold one. - hotCounts := s.counts[n>>63] - coldCounts := s.counts[(^n)>>63] - - // Await cooldown. - for count != atomic.LoadUint64(&coldCounts.count) { - runtime.Gosched() // Let observations get work done. - } - - sum := &dto.Summary{ - SampleCount: proto.Uint64(count), - SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))), - CreatedTimestamp: s.createdTs, - } - - out.Summary = sum - out.Label = s.labelPairs - - // Finally add all the cold counts to the new hot counts and reset the cold counts. - atomic.AddUint64(&hotCounts.count, count) - atomic.StoreUint64(&coldCounts.count, 0) - for { - oldBits := atomic.LoadUint64(&hotCounts.sumBits) - newBits := math.Float64bits(math.Float64frombits(oldBits) + sum.GetSampleSum()) - if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) { - atomic.StoreUint64(&coldCounts.sumBits, 0) - break - } - } - return nil -} - -type quantSort []*dto.Quantile - -func (s quantSort) Len() int { - return len(s) -} - -func (s quantSort) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s quantSort) Less(i, j int) bool { - return s[i].GetQuantile() < s[j].GetQuantile() -} - -// SummaryVec is a Collector that bundles a set of Summaries that all share the -// same Desc, but have different values for their variable labels. This is used -// if you want to count the same thing partitioned by various dimensions -// (e.g. HTTP request latencies, partitioned by status code and method). Create -// instances with NewSummaryVec. -type SummaryVec struct { - *MetricVec -} - -// NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and -// partitioned by the given label names. -// -// Due to the way a Summary is represented in the Prometheus text format and how -// it is handled by the Prometheus server internally, “quantile” is an illegal -// label name. NewSummaryVec will panic if this label name is used. -func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { - return V2.NewSummaryVec(SummaryVecOpts{ - SummaryOpts: opts, - VariableLabels: UnconstrainedLabels(labelNames), - }) -} - -// NewSummaryVec creates a new SummaryVec based on the provided SummaryVecOpts. -func (v2) NewSummaryVec(opts SummaryVecOpts) *SummaryVec { - for _, ln := range opts.VariableLabels.labelNames() { - if ln == quantileLabel { - panic(errQuantileLabelNotAllowed) - } - } - desc := V2.NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - opts.VariableLabels, - opts.ConstLabels, - ) - return &SummaryVec{ - MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { - return newSummary(desc, opts.SummaryOpts, lvs...) - }), - } -} - -// GetMetricWithLabelValues returns the Summary for the given slice of label -// values (same order as the variable labels in Desc). If that combination of -// label values is accessed for the first time, a new Summary is created. -// -// It is possible to call this method without using the returned Summary to only -// create the new Summary but leave it at its starting value, a Summary without -// any observations. -// -// Keeping the Summary for later use is possible (and should be considered if -// performance is critical), but keep in mind that Reset, DeleteLabelValues and -// Delete can be used to delete the Summary from the SummaryVec. In that case, -// the Summary will still exist, but it will not be exported anymore, even if a -// Summary with the same label values is created later. See also the CounterVec -// example. -// -// An error is returned if the number of label values is not the same as the -// number of variable labels in Desc (minus any curried labels). -// -// Note that for more than one label value, this method is prone to mistakes -// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as -// an alternative to avoid that type of mistake. For higher label numbers, the -// latter has a much more readable (albeit more verbose) syntax, but it comes -// with a performance overhead (for creating and processing the Labels map). -// See also the GaugeVec example. -func (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { - metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) - if metric != nil { - return metric.(Observer), err - } - return nil, err -} - -// GetMetricWith returns the Summary for the given Labels map (the label names -// must match those of the variable labels in Desc). If that label map is -// accessed for the first time, a new Summary is created. Implications of -// creating a Summary without using it and keeping the Summary for later use are -// the same as for GetMetricWithLabelValues. -// -// An error is returned if the number and names of the Labels are inconsistent -// with those of the variable labels in Desc (minus any curried labels). -// -// This method is used for the same purpose as -// GetMetricWithLabelValues(...string). See there for pros and cons of the two -// methods. -func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) { - metric, err := v.MetricVec.GetMetricWith(labels) - if metric != nil { - return metric.(Observer), err - } - return nil, err -} - -// WithLabelValues works as GetMetricWithLabelValues, but panics where -// GetMetricWithLabelValues would have returned an error. Not returning an -// error allows shortcuts like -// -// myVec.WithLabelValues("404", "GET").Observe(42.21) -func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { - s, err := v.GetMetricWithLabelValues(lvs...) - if err != nil { - panic(err) - } - return s -} - -// With works as GetMetricWith, but panics where GetMetricWithLabels would have -// returned an error. Not returning an error allows shortcuts like -// -// myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) -func (v *SummaryVec) With(labels Labels) Observer { - s, err := v.GetMetricWith(labels) - if err != nil { - panic(err) - } - return s -} - -// CurryWith returns a vector curried with the provided labels, i.e. the -// returned vector has those labels pre-set for all labeled operations performed -// on it. The cardinality of the curried vector is reduced accordingly. The -// order of the remaining labels stays the same (just with the curried labels -// taken out of the sequence – which is relevant for the -// (GetMetric)WithLabelValues methods). It is possible to curry a curried -// vector, but only with labels not yet used for currying before. -// -// The metrics contained in the SummaryVec are shared between the curried and -// uncurried vectors. They are just accessed differently. Curried and uncurried -// vectors behave identically in terms of collection. Only one must be -// registered with a given registry (usually the uncurried version). The Reset -// method deletes all metrics, even if called on a curried vector. -func (v *SummaryVec) CurryWith(labels Labels) (ObserverVec, error) { - vec, err := v.MetricVec.CurryWith(labels) - if vec != nil { - return &SummaryVec{vec}, err - } - return nil, err -} - -// MustCurryWith works as CurryWith but panics where CurryWith would have -// returned an error. -func (v *SummaryVec) MustCurryWith(labels Labels) ObserverVec { - vec, err := v.CurryWith(labels) - if err != nil { - panic(err) - } - return vec -} - -type constSummary struct { - desc *Desc - count uint64 - sum float64 - quantiles map[float64]float64 - labelPairs []*dto.LabelPair - createdTs *timestamppb.Timestamp -} - -func (s *constSummary) Desc() *Desc { - return s.desc -} - -func (s *constSummary) Write(out *dto.Metric) error { - sum := &dto.Summary{ - CreatedTimestamp: s.createdTs, - } - qs := make([]*dto.Quantile, 0, len(s.quantiles)) - - sum.SampleCount = proto.Uint64(s.count) - sum.SampleSum = proto.Float64(s.sum) - - for rank, q := range s.quantiles { - qs = append(qs, &dto.Quantile{ - Quantile: proto.Float64(rank), - Value: proto.Float64(q), - }) - } - - if len(qs) > 0 { - sort.Sort(quantSort(qs)) - } - sum.Quantile = qs - - out.Summary = sum - out.Label = s.labelPairs - - return nil -} - -// NewConstSummary returns a metric representing a Prometheus summary with fixed -// values for the count, sum, and quantiles. As those parameters cannot be -// changed, the returned value does not implement the Summary interface (but -// only the Metric interface). Users of this package will not have much use for -// it in regular operations. However, when implementing custom Collectors, it is -// useful as a throw-away metric that is generated on the fly to send it to -// Prometheus in the Collect method. -// -// quantiles maps ranks to quantile values. For example, a median latency of -// 0.23s and a 99th percentile latency of 0.56s would be expressed as: -// -// map[float64]float64{0.5: 0.23, 0.99: 0.56} -// -// NewConstSummary returns an error if the length of labelValues is not -// consistent with the variable labels in Desc or if Desc is invalid. -func NewConstSummary( - desc *Desc, - count uint64, - sum float64, - quantiles map[float64]float64, - labelValues ...string, -) (Metric, error) { - if desc.err != nil { - return nil, desc.err - } - if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { - return nil, err - } - return &constSummary{ - desc: desc, - count: count, - sum: sum, - quantiles: quantiles, - labelPairs: MakeLabelPairs(desc, labelValues), - }, nil -} - -// MustNewConstSummary is a version of NewConstSummary that panics where -// NewConstMetric would have returned an error. -func MustNewConstSummary( - desc *Desc, - count uint64, - sum float64, - quantiles map[float64]float64, - labelValues ...string, -) Metric { - m, err := NewConstSummary(desc, count, sum, quantiles, labelValues...) - if err != nil { - panic(err) - } - return m -} - -// NewConstSummaryWithCreatedTimestamp does the same thing as NewConstSummary but sets the created timestamp. -func NewConstSummaryWithCreatedTimestamp( - desc *Desc, - count uint64, - sum float64, - quantiles map[float64]float64, - ct time.Time, - labelValues ...string, -) (Metric, error) { - if desc.err != nil { - return nil, desc.err - } - if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { - return nil, err - } - return &constSummary{ - desc: desc, - count: count, - sum: sum, - quantiles: quantiles, - labelPairs: MakeLabelPairs(desc, labelValues), - createdTs: timestamppb.New(ct), - }, nil -} - -// MustNewConstSummaryWithCreatedTimestamp is a version of NewConstSummaryWithCreatedTimestamp that panics where -// NewConstSummaryWithCreatedTimestamp would have returned an error. -func MustNewConstSummaryWithCreatedTimestamp( - desc *Desc, - count uint64, - sum float64, - quantiles map[float64]float64, - ct time.Time, - labelValues ...string, -) Metric { - m, err := NewConstSummaryWithCreatedTimestamp(desc, count, sum, quantiles, ct, labelValues...) - if err != nil { - panic(err) - } - return m -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/timer.go b/vendor/github.com/prometheus/client_golang/prometheus/timer.go deleted file mode 100644 index 52344fef53f5..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/timer.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2016 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import "time" - -// Timer is a helper type to time functions. Use NewTimer to create new -// instances. -type Timer struct { - begin time.Time - observer Observer -} - -// NewTimer creates a new Timer. The provided Observer is used to observe a -// duration in seconds. If the Observer implements ExemplarObserver, passing exemplar -// later on will be also supported. -// Timer is usually used to time a function call in the -// following way: -// -// func TimeMe() { -// timer := NewTimer(myHistogram) -// defer timer.ObserveDuration() -// // Do actual work. -// } -// -// or -// -// func TimeMeWithExemplar() { -// timer := NewTimer(myHistogram) -// defer timer.ObserveDurationWithExemplar(exemplar) -// // Do actual work. -// } -func NewTimer(o Observer) *Timer { - return &Timer{ - begin: time.Now(), - observer: o, - } -} - -// ObserveDuration records the duration passed since the Timer was created with -// NewTimer. It calls the Observe method of the Observer provided during -// construction with the duration in seconds as an argument. The observed -// duration is also returned. ObserveDuration is usually called with a defer -// statement. -// -// Note that this method is only guaranteed to never observe negative durations -// if used with Go1.9+. -func (t *Timer) ObserveDuration() time.Duration { - d := time.Since(t.begin) - if t.observer != nil { - t.observer.Observe(d.Seconds()) - } - return d -} - -// ObserveDurationWithExemplar is like ObserveDuration, but it will also -// observe exemplar with the duration unless exemplar is nil or provided Observer can't -// be casted to ExemplarObserver. -func (t *Timer) ObserveDurationWithExemplar(exemplar Labels) time.Duration { - d := time.Since(t.begin) - eo, ok := t.observer.(ExemplarObserver) - if ok && exemplar != nil { - eo.ObserveWithExemplar(d.Seconds(), exemplar) - return d - } - if t.observer != nil { - t.observer.Observe(d.Seconds()) - } - return d -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/untyped.go b/vendor/github.com/prometheus/client_golang/prometheus/untyped.go deleted file mode 100644 index 0f9ce63f4093..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/untyped.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -// UntypedOpts is an alias for Opts. See there for doc comments. -type UntypedOpts Opts - -// UntypedFunc works like GaugeFunc but the collected metric is of type -// "Untyped". UntypedFunc is useful to mirror an external metric of unknown -// type. -// -// To create UntypedFunc instances, use NewUntypedFunc. -type UntypedFunc interface { - Metric - Collector -} - -// NewUntypedFunc creates a new UntypedFunc based on the provided -// UntypedOpts. The value reported is determined by calling the given function -// from within the Write method. Take into account that metric collection may -// happen concurrently. If that results in concurrent calls to Write, like in -// the case where an UntypedFunc is directly registered with Prometheus, the -// provided function must be concurrency-safe. -func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc { - return newValueFunc(NewDesc( - BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), - opts.Help, - nil, - opts.ConstLabels, - ), UntypedValue, function) -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go deleted file mode 100644 index cc23011fad23..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/value.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "errors" - "fmt" - "sort" - "time" - "unicode/utf8" - - "github.com/prometheus/client_golang/prometheus/internal" - - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -// ValueType is an enumeration of metric types that represent a simple value. -type ValueType int - -// Possible values for the ValueType enum. Use UntypedValue to mark a metric -// with an unknown type. -const ( - _ ValueType = iota - CounterValue - GaugeValue - UntypedValue -) - -var ( - CounterMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_COUNTER; return &d }() - GaugeMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_GAUGE; return &d }() - UntypedMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_UNTYPED; return &d }() -) - -func (v ValueType) ToDTO() *dto.MetricType { - switch v { - case CounterValue: - return CounterMetricTypePtr - case GaugeValue: - return GaugeMetricTypePtr - default: - return UntypedMetricTypePtr - } -} - -// valueFunc is a generic metric for simple values retrieved on collect time -// from a function. It implements Metric and Collector. Its effective type is -// determined by ValueType. This is a low-level building block used by the -// library to back the implementations of CounterFunc, GaugeFunc, and -// UntypedFunc. -type valueFunc struct { - selfCollector - - desc *Desc - valType ValueType - function func() float64 - labelPairs []*dto.LabelPair -} - -// newValueFunc returns a newly allocated valueFunc with the given Desc and -// ValueType. The value reported is determined by calling the given function -// from within the Write method. Take into account that metric collection may -// happen concurrently. If that results in concurrent calls to Write, like in -// the case where a valueFunc is directly registered with Prometheus, the -// provided function must be concurrency-safe. -func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc { - result := &valueFunc{ - desc: desc, - valType: valueType, - function: function, - labelPairs: MakeLabelPairs(desc, nil), - } - result.init(result) - return result -} - -func (v *valueFunc) Desc() *Desc { - return v.desc -} - -func (v *valueFunc) Write(out *dto.Metric) error { - return populateMetric(v.valType, v.function(), v.labelPairs, nil, out, nil) -} - -// NewConstMetric returns a metric with one fixed value that cannot be -// changed. Users of this package will not have much use for it in regular -// operations. However, when implementing custom Collectors, it is useful as a -// throw-away metric that is generated on the fly to send it to Prometheus in -// the Collect method. NewConstMetric returns an error if the length of -// labelValues is not consistent with the variable labels in Desc or if Desc is -// invalid. -func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) { - if desc.err != nil { - return nil, desc.err - } - if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { - return nil, err - } - - metric := &dto.Metric{} - if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, nil); err != nil { - return nil, err - } - - return &constMetric{ - desc: desc, - metric: metric, - }, nil -} - -// MustNewConstMetric is a version of NewConstMetric that panics where -// NewConstMetric would have returned an error. -func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric { - m, err := NewConstMetric(desc, valueType, value, labelValues...) - if err != nil { - panic(err) - } - return m -} - -// NewConstMetricWithCreatedTimestamp does the same thing as NewConstMetric, but generates Counters -// with created timestamp set and returns an error for other metric types. -func NewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) (Metric, error) { - if desc.err != nil { - return nil, desc.err - } - if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { - return nil, err - } - switch valueType { - case CounterValue: - break - default: - return nil, errors.New("created timestamps are only supported for counters") - } - - metric := &dto.Metric{} - if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, timestamppb.New(ct)); err != nil { - return nil, err - } - - return &constMetric{ - desc: desc, - metric: metric, - }, nil -} - -// MustNewConstMetricWithCreatedTimestamp is a version of NewConstMetricWithCreatedTimestamp that panics where -// NewConstMetricWithCreatedTimestamp would have returned an error. -func MustNewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) Metric { - m, err := NewConstMetricWithCreatedTimestamp(desc, valueType, value, ct, labelValues...) - if err != nil { - panic(err) - } - return m -} - -type constMetric struct { - desc *Desc - metric *dto.Metric -} - -func (m *constMetric) Desc() *Desc { - return m.desc -} - -func (m *constMetric) Write(out *dto.Metric) error { - out.Label = m.metric.Label - out.Counter = m.metric.Counter - out.Gauge = m.metric.Gauge - out.Untyped = m.metric.Untyped - return nil -} - -func populateMetric( - t ValueType, - v float64, - labelPairs []*dto.LabelPair, - e *dto.Exemplar, - m *dto.Metric, - ct *timestamppb.Timestamp, -) error { - m.Label = labelPairs - switch t { - case CounterValue: - m.Counter = &dto.Counter{Value: proto.Float64(v), Exemplar: e, CreatedTimestamp: ct} - case GaugeValue: - m.Gauge = &dto.Gauge{Value: proto.Float64(v)} - case UntypedValue: - m.Untyped = &dto.Untyped{Value: proto.Float64(v)} - default: - return fmt.Errorf("encountered unknown type %v", t) - } - return nil -} - -// MakeLabelPairs is a helper function to create protobuf LabelPairs from the -// variable and constant labels in the provided Desc. The values for the -// variable labels are defined by the labelValues slice, which must be in the -// same order as the corresponding variable labels in the Desc. -// -// This function is only needed for custom Metric implementations. See MetricVec -// example. -func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { - totalLen := len(desc.variableLabels.names) + len(desc.constLabelPairs) - if totalLen == 0 { - // Super fast path. - return nil - } - if len(desc.variableLabels.names) == 0 { - // Moderately fast path. - return desc.constLabelPairs - } - labelPairs := make([]*dto.LabelPair, 0, totalLen) - for i, l := range desc.variableLabels.names { - labelPairs = append(labelPairs, &dto.LabelPair{ - Name: proto.String(l), - Value: proto.String(labelValues[i]), - }) - } - labelPairs = append(labelPairs, desc.constLabelPairs...) - sort.Sort(internal.LabelPairSorter(labelPairs)) - return labelPairs -} - -// ExemplarMaxRunes is the max total number of runes allowed in exemplar labels. -const ExemplarMaxRunes = 128 - -// newExemplar creates a new dto.Exemplar from the provided values. An error is -// returned if any of the label names or values are invalid or if the total -// number of runes in the label names and values exceeds ExemplarMaxRunes. -func newExemplar(value float64, ts time.Time, l Labels) (*dto.Exemplar, error) { - e := &dto.Exemplar{} - e.Value = proto.Float64(value) - tsProto := timestamppb.New(ts) - if err := tsProto.CheckValid(); err != nil { - return nil, err - } - e.Timestamp = tsProto - labelPairs := make([]*dto.LabelPair, 0, len(l)) - var runes int - for name, value := range l { - if !checkLabelName(name) { - return nil, fmt.Errorf("exemplar label name %q is invalid", name) - } - runes += utf8.RuneCountInString(name) - if !utf8.ValidString(value) { - return nil, fmt.Errorf("exemplar label value %q is not valid UTF-8", value) - } - runes += utf8.RuneCountInString(value) - labelPairs = append(labelPairs, &dto.LabelPair{ - Name: proto.String(name), - Value: proto.String(value), - }) - } - if runes > ExemplarMaxRunes { - return nil, fmt.Errorf("exemplar labels have %d runes, exceeding the limit of %d", runes, ExemplarMaxRunes) - } - e.Label = labelPairs - return e, nil -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go deleted file mode 100644 index 487b466563bb..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go +++ /dev/null @@ -1,709 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "fmt" - "sync" - - "github.com/prometheus/common/model" -) - -// MetricVec is a Collector to bundle metrics of the same name that differ in -// their label values. MetricVec is not used directly but as a building block -// for implementations of vectors of a given metric type, like GaugeVec, -// CounterVec, SummaryVec, and HistogramVec. It is exported so that it can be -// used for custom Metric implementations. -// -// To create a FooVec for custom Metric Foo, embed a pointer to MetricVec in -// FooVec and initialize it with NewMetricVec. Implement wrappers for -// GetMetricWithLabelValues and GetMetricWith that return (Foo, error) rather -// than (Metric, error). Similarly, create a wrapper for CurryWith that returns -// (*FooVec, error) rather than (*MetricVec, error). It is recommended to also -// add the convenience methods WithLabelValues, With, and MustCurryWith, which -// panic instead of returning errors. See also the MetricVec example. -type MetricVec struct { - *metricMap - - curry []curriedLabelValue - - // hashAdd and hashAddByte can be replaced for testing collision handling. - hashAdd func(h uint64, s string) uint64 - hashAddByte func(h uint64, b byte) uint64 -} - -// NewMetricVec returns an initialized metricVec. -func NewMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec { - return &MetricVec{ - metricMap: &metricMap{ - metrics: map[uint64][]metricWithLabelValues{}, - desc: desc, - newMetric: newMetric, - }, - hashAdd: hashAdd, - hashAddByte: hashAddByte, - } -} - -// DeleteLabelValues removes the metric where the variable labels are the same -// as those passed in as labels (same order as the VariableLabels in Desc). It -// returns true if a metric was deleted. -// -// It is not an error if the number of label values is not the same as the -// number of VariableLabels in Desc. However, such inconsistent label count can -// never match an actual metric, so the method will always return false in that -// case. -// -// Note that for more than one label value, this method is prone to mistakes -// caused by an incorrect order of arguments. Consider Delete(Labels) as an -// alternative to avoid that type of mistake. For higher label numbers, the -// latter has a much more readable (albeit more verbose) syntax, but it comes -// with a performance overhead (for creating and processing the Labels map). -// See also the CounterVec example. -func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { - lvs = constrainLabelValues(m.desc, lvs, m.curry) - - h, err := m.hashLabelValues(lvs) - if err != nil { - return false - } - - return m.deleteByHashWithLabelValues(h, lvs, m.curry) -} - -// Delete deletes the metric where the variable labels are the same as those -// passed in as labels. It returns true if a metric was deleted. -// -// It is not an error if the number and names of the Labels are inconsistent -// with those of the VariableLabels in Desc. However, such inconsistent Labels -// can never match an actual metric, so the method will always return false in -// that case. -// -// This method is used for the same purpose as DeleteLabelValues(...string). See -// there for pros and cons of the two methods. -func (m *MetricVec) Delete(labels Labels) bool { - labels, closer := constrainLabels(m.desc, labels) - defer closer() - - h, err := m.hashLabels(labels) - if err != nil { - return false - } - - return m.deleteByHashWithLabels(h, labels, m.curry) -} - -// DeletePartialMatch deletes all metrics where the variable labels contain all of those -// passed in as labels. The order of the labels does not matter. -// It returns the number of metrics deleted. -// -// Note that curried labels will never be matched if deleting from the curried vector. -// To match curried labels with DeletePartialMatch, it must be called on the base vector. -func (m *MetricVec) DeletePartialMatch(labels Labels) int { - labels, closer := constrainLabels(m.desc, labels) - defer closer() - - return m.deleteByLabels(labels, m.curry) -} - -// Without explicit forwarding of Describe, Collect, Reset, those methods won't -// show up in GoDoc. - -// Describe implements Collector. -func (m *MetricVec) Describe(ch chan<- *Desc) { m.metricMap.Describe(ch) } - -// Collect implements Collector. -func (m *MetricVec) Collect(ch chan<- Metric) { m.metricMap.Collect(ch) } - -// Reset deletes all metrics in this vector. -func (m *MetricVec) Reset() { m.metricMap.Reset() } - -// CurryWith returns a vector curried with the provided labels, i.e. the -// returned vector has those labels pre-set for all labeled operations performed -// on it. The cardinality of the curried vector is reduced accordingly. The -// order of the remaining labels stays the same (just with the curried labels -// taken out of the sequence – which is relevant for the -// (GetMetric)WithLabelValues methods). It is possible to curry a curried -// vector, but only with labels not yet used for currying before. -// -// The metrics contained in the MetricVec are shared between the curried and -// uncurried vectors. They are just accessed differently. Curried and uncurried -// vectors behave identically in terms of collection. Only one must be -// registered with a given registry (usually the uncurried version). The Reset -// method deletes all metrics, even if called on a curried vector. -// -// Note that CurryWith is usually not called directly but through a wrapper -// around MetricVec, implementing a vector for a specific Metric -// implementation, for example GaugeVec. -func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { - var ( - newCurry []curriedLabelValue - oldCurry = m.curry - iCurry int - ) - for i, labelName := range m.desc.variableLabels.names { - val, ok := labels[labelName] - if iCurry < len(oldCurry) && oldCurry[iCurry].index == i { - if ok { - return nil, fmt.Errorf("label name %q is already curried", labelName) - } - newCurry = append(newCurry, oldCurry[iCurry]) - iCurry++ - } else { - if !ok { - continue // Label stays uncurried. - } - newCurry = append(newCurry, curriedLabelValue{ - i, - m.desc.variableLabels.constrain(labelName, val), - }) - } - } - if l := len(oldCurry) + len(labels) - len(newCurry); l > 0 { - return nil, fmt.Errorf("%d unknown label(s) found during currying", l) - } - - return &MetricVec{ - metricMap: m.metricMap, - curry: newCurry, - hashAdd: m.hashAdd, - hashAddByte: m.hashAddByte, - }, nil -} - -// GetMetricWithLabelValues returns the Metric for the given slice of label -// values (same order as the variable labels in Desc). If that combination of -// label values is accessed for the first time, a new Metric is created (by -// calling the newMetric function provided during construction of the -// MetricVec). -// -// It is possible to call this method without using the returned Metric to only -// create the new Metric but leave it in its initial state. -// -// Keeping the Metric for later use is possible (and should be considered if -// performance is critical), but keep in mind that Reset, DeleteLabelValues and -// Delete can be used to delete the Metric from the MetricVec. In that case, the -// Metric will still exist, but it will not be exported anymore, even if a -// Metric with the same label values is created later. -// -// An error is returned if the number of label values is not the same as the -// number of variable labels in Desc (minus any curried labels). -// -// Note that for more than one label value, this method is prone to mistakes -// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as -// an alternative to avoid that type of mistake. For higher label numbers, the -// latter has a much more readable (albeit more verbose) syntax, but it comes -// with a performance overhead (for creating and processing the Labels map). -// -// Note that GetMetricWithLabelValues is usually not called directly but through -// a wrapper around MetricVec, implementing a vector for a specific Metric -// implementation, for example GaugeVec. -func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { - lvs = constrainLabelValues(m.desc, lvs, m.curry) - h, err := m.hashLabelValues(lvs) - if err != nil { - return nil, err - } - - return m.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil -} - -// GetMetricWith returns the Metric for the given Labels map (the label names -// must match those of the variable labels in Desc). If that label map is -// accessed for the first time, a new Metric is created. Implications of -// creating a Metric without using it and keeping the Metric for later use -// are the same as for GetMetricWithLabelValues. -// -// An error is returned if the number and names of the Labels are inconsistent -// with those of the variable labels in Desc (minus any curried labels). -// -// This method is used for the same purpose as -// GetMetricWithLabelValues(...string). See there for pros and cons of the two -// methods. -// -// Note that GetMetricWith is usually not called directly but through a wrapper -// around MetricVec, implementing a vector for a specific Metric implementation, -// for example GaugeVec. -func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { - labels, closer := constrainLabels(m.desc, labels) - defer closer() - - h, err := m.hashLabels(labels) - if err != nil { - return nil, err - } - - return m.getOrCreateMetricWithLabels(h, labels, m.curry), nil -} - -func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) { - if err := validateLabelValues(vals, len(m.desc.variableLabels.names)-len(m.curry)); err != nil { - return 0, err - } - - var ( - h = hashNew() - curry = m.curry - iVals, iCurry int - ) - for i := 0; i < len(m.desc.variableLabels.names); i++ { - if iCurry < len(curry) && curry[iCurry].index == i { - h = m.hashAdd(h, curry[iCurry].value) - iCurry++ - } else { - h = m.hashAdd(h, vals[iVals]) - iVals++ - } - h = m.hashAddByte(h, model.SeparatorByte) - } - return h, nil -} - -func (m *MetricVec) hashLabels(labels Labels) (uint64, error) { - if err := validateValuesInLabels(labels, len(m.desc.variableLabels.names)-len(m.curry)); err != nil { - return 0, err - } - - var ( - h = hashNew() - curry = m.curry - iCurry int - ) - for i, labelName := range m.desc.variableLabels.names { - val, ok := labels[labelName] - if iCurry < len(curry) && curry[iCurry].index == i { - if ok { - return 0, fmt.Errorf("label name %q is already curried", labelName) - } - h = m.hashAdd(h, curry[iCurry].value) - iCurry++ - } else { - if !ok { - return 0, fmt.Errorf("label name %q missing in label map", labelName) - } - h = m.hashAdd(h, val) - } - h = m.hashAddByte(h, model.SeparatorByte) - } - return h, nil -} - -// metricWithLabelValues provides the metric and its label values for -// disambiguation on hash collision. -type metricWithLabelValues struct { - values []string - metric Metric -} - -// curriedLabelValue sets the curried value for a label at the given index. -type curriedLabelValue struct { - index int - value string -} - -// metricMap is a helper for metricVec and shared between differently curried -// metricVecs. -type metricMap struct { - mtx sync.RWMutex // Protects metrics. - metrics map[uint64][]metricWithLabelValues - desc *Desc - newMetric func(labelValues ...string) Metric -} - -// Describe implements Collector. It will send exactly one Desc to the provided -// channel. -func (m *metricMap) Describe(ch chan<- *Desc) { - ch <- m.desc -} - -// Collect implements Collector. -func (m *metricMap) Collect(ch chan<- Metric) { - m.mtx.RLock() - defer m.mtx.RUnlock() - - for _, metrics := range m.metrics { - for _, metric := range metrics { - ch <- metric.metric - } - } -} - -// Reset deletes all metrics in this vector. -func (m *metricMap) Reset() { - m.mtx.Lock() - defer m.mtx.Unlock() - - for h := range m.metrics { - delete(m.metrics, h) - } -} - -// deleteByHashWithLabelValues removes the metric from the hash bucket h. If -// there are multiple matches in the bucket, use lvs to select a metric and -// remove only that metric. -func (m *metricMap) deleteByHashWithLabelValues( - h uint64, lvs []string, curry []curriedLabelValue, -) bool { - m.mtx.Lock() - defer m.mtx.Unlock() - - metrics, ok := m.metrics[h] - if !ok { - return false - } - - i := findMetricWithLabelValues(metrics, lvs, curry) - if i >= len(metrics) { - return false - } - - if len(metrics) > 1 { - old := metrics - m.metrics[h] = append(metrics[:i], metrics[i+1:]...) - old[len(old)-1] = metricWithLabelValues{} - } else { - delete(m.metrics, h) - } - return true -} - -// deleteByHashWithLabels removes the metric from the hash bucket h. If there -// are multiple matches in the bucket, use lvs to select a metric and remove -// only that metric. -func (m *metricMap) deleteByHashWithLabels( - h uint64, labels Labels, curry []curriedLabelValue, -) bool { - m.mtx.Lock() - defer m.mtx.Unlock() - - metrics, ok := m.metrics[h] - if !ok { - return false - } - i := findMetricWithLabels(m.desc, metrics, labels, curry) - if i >= len(metrics) { - return false - } - - if len(metrics) > 1 { - old := metrics - m.metrics[h] = append(metrics[:i], metrics[i+1:]...) - old[len(old)-1] = metricWithLabelValues{} - } else { - delete(m.metrics, h) - } - return true -} - -// deleteByLabels deletes a metric if the given labels are present in the metric. -func (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int { - m.mtx.Lock() - defer m.mtx.Unlock() - - var numDeleted int - - for h, metrics := range m.metrics { - i := findMetricWithPartialLabels(m.desc, metrics, labels, curry) - if i >= len(metrics) { - // Didn't find matching labels in this metric slice. - continue - } - delete(m.metrics, h) - numDeleted++ - } - - return numDeleted -} - -// findMetricWithPartialLabel returns the index of the matching metric or -// len(metrics) if not found. -func findMetricWithPartialLabels( - desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue, -) int { - for i, metric := range metrics { - if matchPartialLabels(desc, metric.values, labels, curry) { - return i - } - } - return len(metrics) -} - -// indexOf searches the given slice of strings for the target string and returns -// the index or len(items) as well as a boolean whether the search succeeded. -func indexOf(target string, items []string) (int, bool) { - for i, l := range items { - if l == target { - return i, true - } - } - return len(items), false -} - -// valueMatchesVariableOrCurriedValue determines if a value was previously curried, -// and returns whether it matches either the "base" value or the curried value accordingly. -// It also indicates whether the match is against a curried or uncurried value. -func valueMatchesVariableOrCurriedValue(targetValue string, index int, values []string, curry []curriedLabelValue) (bool, bool) { - for _, curriedValue := range curry { - if curriedValue.index == index { - // This label was curried. See if the curried value matches our target. - return curriedValue.value == targetValue, true - } - } - // This label was not curried. See if the current value matches our target label. - return values[index] == targetValue, false -} - -// matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present. -func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool { - for l, v := range labels { - // Check if the target label exists in our metrics and get the index. - varLabelIndex, validLabel := indexOf(l, desc.variableLabels.names) - if validLabel { - // Check the value of that label against the target value. - // We don't consider curried values in partial matches. - matches, curried := valueMatchesVariableOrCurriedValue(v, varLabelIndex, values, curry) - if matches && !curried { - continue - } - } - return false - } - return true -} - -// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value -// or creates it and returns the new one. -// -// This function holds the mutex. -func (m *metricMap) getOrCreateMetricWithLabelValues( - hash uint64, lvs []string, curry []curriedLabelValue, -) Metric { - m.mtx.RLock() - metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs, curry) - m.mtx.RUnlock() - if ok { - return metric - } - - m.mtx.Lock() - defer m.mtx.Unlock() - metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs, curry) - if !ok { - inlinedLVs := inlineLabelValues(lvs, curry) - metric = m.newMetric(inlinedLVs...) - m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: inlinedLVs, metric: metric}) - } - return metric -} - -// getOrCreateMetricWithLabels retrieves the metric by hash and label value -// or creates it and returns the new one. -// -// This function holds the mutex. -func (m *metricMap) getOrCreateMetricWithLabels( - hash uint64, labels Labels, curry []curriedLabelValue, -) Metric { - m.mtx.RLock() - metric, ok := m.getMetricWithHashAndLabels(hash, labels, curry) - m.mtx.RUnlock() - if ok { - return metric - } - - m.mtx.Lock() - defer m.mtx.Unlock() - metric, ok = m.getMetricWithHashAndLabels(hash, labels, curry) - if !ok { - lvs := extractLabelValues(m.desc, labels, curry) - metric = m.newMetric(lvs...) - m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: lvs, metric: metric}) - } - return metric -} - -// getMetricWithHashAndLabelValues gets a metric while handling possible -// collisions in the hash space. Must be called while holding the read mutex. -func (m *metricMap) getMetricWithHashAndLabelValues( - h uint64, lvs []string, curry []curriedLabelValue, -) (Metric, bool) { - metrics, ok := m.metrics[h] - if ok { - if i := findMetricWithLabelValues(metrics, lvs, curry); i < len(metrics) { - return metrics[i].metric, true - } - } - return nil, false -} - -// getMetricWithHashAndLabels gets a metric while handling possible collisions in -// the hash space. Must be called while holding read mutex. -func (m *metricMap) getMetricWithHashAndLabels( - h uint64, labels Labels, curry []curriedLabelValue, -) (Metric, bool) { - metrics, ok := m.metrics[h] - if ok { - if i := findMetricWithLabels(m.desc, metrics, labels, curry); i < len(metrics) { - return metrics[i].metric, true - } - } - return nil, false -} - -// findMetricWithLabelValues returns the index of the matching metric or -// len(metrics) if not found. -func findMetricWithLabelValues( - metrics []metricWithLabelValues, lvs []string, curry []curriedLabelValue, -) int { - for i, metric := range metrics { - if matchLabelValues(metric.values, lvs, curry) { - return i - } - } - return len(metrics) -} - -// findMetricWithLabels returns the index of the matching metric or len(metrics) -// if not found. -func findMetricWithLabels( - desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue, -) int { - for i, metric := range metrics { - if matchLabels(desc, metric.values, labels, curry) { - return i - } - } - return len(metrics) -} - -func matchLabelValues(values, lvs []string, curry []curriedLabelValue) bool { - if len(values) != len(lvs)+len(curry) { - return false - } - var iLVs, iCurry int - for i, v := range values { - if iCurry < len(curry) && curry[iCurry].index == i { - if v != curry[iCurry].value { - return false - } - iCurry++ - continue - } - if v != lvs[iLVs] { - return false - } - iLVs++ - } - return true -} - -func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool { - if len(values) != len(labels)+len(curry) { - return false - } - iCurry := 0 - for i, k := range desc.variableLabels.names { - if iCurry < len(curry) && curry[iCurry].index == i { - if values[i] != curry[iCurry].value { - return false - } - iCurry++ - continue - } - if values[i] != labels[k] { - return false - } - } - return true -} - -func extractLabelValues(desc *Desc, labels Labels, curry []curriedLabelValue) []string { - labelValues := make([]string, len(labels)+len(curry)) - iCurry := 0 - for i, k := range desc.variableLabels.names { - if iCurry < len(curry) && curry[iCurry].index == i { - labelValues[i] = curry[iCurry].value - iCurry++ - continue - } - labelValues[i] = labels[k] - } - return labelValues -} - -func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string { - labelValues := make([]string, len(lvs)+len(curry)) - var iCurry, iLVs int - for i := range labelValues { - if iCurry < len(curry) && curry[iCurry].index == i { - labelValues[i] = curry[iCurry].value - iCurry++ - continue - } - labelValues[i] = lvs[iLVs] - iLVs++ - } - return labelValues -} - -var labelsPool = &sync.Pool{ - New: func() interface{} { - return make(Labels) - }, -} - -func constrainLabels(desc *Desc, labels Labels) (Labels, func()) { - if len(desc.variableLabels.labelConstraints) == 0 { - // Fast path when there's no constraints - return labels, func() {} - } - - constrainedLabels := labelsPool.Get().(Labels) - for l, v := range labels { - constrainedLabels[l] = desc.variableLabels.constrain(l, v) - } - - return constrainedLabels, func() { - for k := range constrainedLabels { - delete(constrainedLabels, k) - } - labelsPool.Put(constrainedLabels) - } -} - -func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string { - if len(desc.variableLabels.labelConstraints) == 0 { - // Fast path when there's no constraints - return lvs - } - - constrainedValues := make([]string, len(lvs)) - var iCurry, iLVs int - for i := 0; i < len(lvs)+len(curry); i++ { - if iCurry < len(curry) && curry[iCurry].index == i { - iCurry++ - continue - } - - if i < len(desc.variableLabels.names) { - constrainedValues[iLVs] = desc.variableLabels.constrain( - desc.variableLabels.names[i], - lvs[iLVs], - ) - } else { - constrainedValues[iLVs] = lvs[iLVs] - } - iLVs++ - } - return constrainedValues -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vnext.go b/vendor/github.com/prometheus/client_golang/prometheus/vnext.go deleted file mode 100644 index 42bc3a8f0661..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/vnext.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2022 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -type v2 struct{} - -// V2 is a struct that can be referenced to access experimental API that might -// be present in v2 of client golang someday. It offers extended functionality -// of v1 with slightly changed API. It is acceptable to use some pieces from v1 -// and e.g `prometheus.NewGauge` and some from v2 e.g. `prometheus.V2.NewDesc` -// in the same codebase. -var V2 = v2{} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go deleted file mode 100644 index 2ed1285068ee..000000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2018 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus - -import ( - "fmt" - "sort" - - "github.com/prometheus/client_golang/prometheus/internal" - - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/proto" -) - -// WrapRegistererWith returns a Registerer wrapping the provided -// Registerer. Collectors registered with the returned Registerer will be -// registered with the wrapped Registerer in a modified way. The modified -// Collector adds the provided Labels to all Metrics it collects (as -// ConstLabels). The Metrics collected by the unmodified Collector must not -// duplicate any of those labels. Wrapping a nil value is valid, resulting -// in a no-op Registerer. -// -// WrapRegistererWith provides a way to add fixed labels to a subset of -// Collectors. It should not be used to add fixed labels to all metrics -// exposed. See also -// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels -// -// Conflicts between Collectors registered through the original Registerer with -// Collectors registered through the wrapping Registerer will still be -// detected. Any AlreadyRegisteredError returned by the Register method of -// either Registerer will contain the ExistingCollector in the form it was -// provided to the respective registry. -// -// The Collector example demonstrates a use of WrapRegistererWith. -func WrapRegistererWith(labels Labels, reg Registerer) Registerer { - return &wrappingRegisterer{ - wrappedRegisterer: reg, - labels: labels, - } -} - -// WrapRegistererWithPrefix returns a Registerer wrapping the provided -// Registerer. Collectors registered with the returned Registerer will be -// registered with the wrapped Registerer in a modified way. The modified -// Collector adds the provided prefix to the name of all Metrics it collects. -// Wrapping a nil value is valid, resulting in a no-op Registerer. -// -// WrapRegistererWithPrefix is useful to have one place to prefix all metrics of -// a sub-system. To make this work, register metrics of the sub-system with the -// wrapping Registerer returned by WrapRegistererWithPrefix. It is rarely useful -// to use the same prefix for all metrics exposed. In particular, do not prefix -// metric names that are standardized across applications, as that would break -// horizontal monitoring, for example the metrics provided by the Go collector -// (see NewGoCollector) and the process collector (see NewProcessCollector). (In -// fact, those metrics are already prefixed with "go_" or "process_", -// respectively.) -// -// Conflicts between Collectors registered through the original Registerer with -// Collectors registered through the wrapping Registerer will still be -// detected. Any AlreadyRegisteredError returned by the Register method of -// either Registerer will contain the ExistingCollector in the form it was -// provided to the respective registry. -func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer { - return &wrappingRegisterer{ - wrappedRegisterer: reg, - prefix: prefix, - } -} - -// WrapCollectorWith returns a Collector wrapping the provided Collector. The -// wrapped Collector will add the provided Labels to all Metrics it collects (as -// ConstLabels). The Metrics collected by the unmodified Collector must not -// duplicate any of those labels. -// -// WrapCollectorWith can be useful to work with multiple instances of a third -// party library that does not expose enough flexibility on the lifecycle of its -// registered metrics. -// For example, let's say you have a foo.New(reg Registerer) constructor that -// registers metrics but never unregisters them, and you want to create multiple -// instances of foo.Foo with different labels. -// The way to achieve that, is to create a new Registry, pass it to foo.New, -// then use WrapCollectorWith to wrap that Registry with the desired labels and -// register that as a collector in your main Registry. -// Then you can un-register the wrapped collector effectively un-registering the -// metrics registered by foo.New. -func WrapCollectorWith(labels Labels, c Collector) Collector { - return &wrappingCollector{ - wrappedCollector: c, - labels: labels, - } -} - -// WrapCollectorWithPrefix returns a Collector wrapping the provided Collector. The -// wrapped Collector will add the provided prefix to the name of all Metrics it collects. -// -// See the documentation of WrapCollectorWith for more details on the use case. -func WrapCollectorWithPrefix(prefix string, c Collector) Collector { - return &wrappingCollector{ - wrappedCollector: c, - prefix: prefix, - } -} - -type wrappingRegisterer struct { - wrappedRegisterer Registerer - prefix string - labels Labels -} - -func (r *wrappingRegisterer) Register(c Collector) error { - if r.wrappedRegisterer == nil { - return nil - } - return r.wrappedRegisterer.Register(&wrappingCollector{ - wrappedCollector: c, - prefix: r.prefix, - labels: r.labels, - }) -} - -func (r *wrappingRegisterer) MustRegister(cs ...Collector) { - if r.wrappedRegisterer == nil { - return - } - for _, c := range cs { - if err := r.Register(c); err != nil { - panic(err) - } - } -} - -func (r *wrappingRegisterer) Unregister(c Collector) bool { - if r.wrappedRegisterer == nil { - return false - } - return r.wrappedRegisterer.Unregister(&wrappingCollector{ - wrappedCollector: c, - prefix: r.prefix, - labels: r.labels, - }) -} - -type wrappingCollector struct { - wrappedCollector Collector - prefix string - labels Labels -} - -func (c *wrappingCollector) Collect(ch chan<- Metric) { - wrappedCh := make(chan Metric) - go func() { - c.wrappedCollector.Collect(wrappedCh) - close(wrappedCh) - }() - for m := range wrappedCh { - ch <- &wrappingMetric{ - wrappedMetric: m, - prefix: c.prefix, - labels: c.labels, - } - } -} - -func (c *wrappingCollector) Describe(ch chan<- *Desc) { - wrappedCh := make(chan *Desc) - go func() { - c.wrappedCollector.Describe(wrappedCh) - close(wrappedCh) - }() - for desc := range wrappedCh { - ch <- wrapDesc(desc, c.prefix, c.labels) - } -} - -func (c *wrappingCollector) unwrapRecursively() Collector { - switch wc := c.wrappedCollector.(type) { - case *wrappingCollector: - return wc.unwrapRecursively() - default: - return wc - } -} - -type wrappingMetric struct { - wrappedMetric Metric - prefix string - labels Labels -} - -func (m *wrappingMetric) Desc() *Desc { - return wrapDesc(m.wrappedMetric.Desc(), m.prefix, m.labels) -} - -func (m *wrappingMetric) Write(out *dto.Metric) error { - if err := m.wrappedMetric.Write(out); err != nil { - return err - } - if len(m.labels) == 0 { - // No wrapping labels. - return nil - } - for ln, lv := range m.labels { - out.Label = append(out.Label, &dto.LabelPair{ - Name: proto.String(ln), - Value: proto.String(lv), - }) - } - sort.Sort(internal.LabelPairSorter(out.Label)) - return nil -} - -func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc { - constLabels := Labels{} - for _, lp := range desc.constLabelPairs { - constLabels[*lp.Name] = *lp.Value - } - for ln, lv := range labels { - if _, alreadyUsed := constLabels[ln]; alreadyUsed { - return &Desc{ - fqName: desc.fqName, - help: desc.help, - variableLabels: desc.variableLabels, - constLabelPairs: desc.constLabelPairs, - err: fmt.Errorf("attempted wrapping with already existing label name %q", ln), - } - } - constLabels[ln] = lv - } - // NewDesc will do remaining validations. - newDesc := V2.NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels) - // Propagate errors if there was any. This will override any errer - // created by NewDesc above, i.e. earlier errors get precedence. - if desc.err != nil { - newDesc.err = desc.err - } - return newDesc -} diff --git a/vendor/github.com/prometheus/client_model/LICENSE b/vendor/github.com/prometheus/client_model/LICENSE deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/vendor/github.com/prometheus/client_model/LICENSE +++ /dev/null @@ -1,201 +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. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/prometheus/client_model/NOTICE b/vendor/github.com/prometheus/client_model/NOTICE deleted file mode 100644 index 20110e410e57..000000000000 --- a/vendor/github.com/prometheus/client_model/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Data model artifacts for Prometheus. -Copyright 2012-2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). diff --git a/vendor/github.com/prometheus/client_model/go/metrics.pb.go b/vendor/github.com/prometheus/client_model/go/metrics.pb.go deleted file mode 100644 index 2f15490758ab..000000000000 --- a/vendor/github.com/prometheus/client_model/go/metrics.pb.go +++ /dev/null @@ -1,1399 +0,0 @@ -// Copyright 2013 Prometheus Team -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc v3.20.3 -// source: io/prometheus/client/metrics.proto - -package io_prometheus_client - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type MetricType int32 - -const ( - // COUNTER must use the Metric field "counter". - MetricType_COUNTER MetricType = 0 - // GAUGE must use the Metric field "gauge". - MetricType_GAUGE MetricType = 1 - // SUMMARY must use the Metric field "summary". - MetricType_SUMMARY MetricType = 2 - // UNTYPED must use the Metric field "untyped". - MetricType_UNTYPED MetricType = 3 - // HISTOGRAM must use the Metric field "histogram". - MetricType_HISTOGRAM MetricType = 4 - // GAUGE_HISTOGRAM must use the Metric field "histogram". - MetricType_GAUGE_HISTOGRAM MetricType = 5 -) - -// Enum value maps for MetricType. -var ( - MetricType_name = map[int32]string{ - 0: "COUNTER", - 1: "GAUGE", - 2: "SUMMARY", - 3: "UNTYPED", - 4: "HISTOGRAM", - 5: "GAUGE_HISTOGRAM", - } - MetricType_value = map[string]int32{ - "COUNTER": 0, - "GAUGE": 1, - "SUMMARY": 2, - "UNTYPED": 3, - "HISTOGRAM": 4, - "GAUGE_HISTOGRAM": 5, - } -) - -func (x MetricType) Enum() *MetricType { - p := new(MetricType) - *p = x - return p -} - -func (x MetricType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (MetricType) Descriptor() protoreflect.EnumDescriptor { - return file_io_prometheus_client_metrics_proto_enumTypes[0].Descriptor() -} - -func (MetricType) Type() protoreflect.EnumType { - return &file_io_prometheus_client_metrics_proto_enumTypes[0] -} - -func (x MetricType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Do not use. -func (x *MetricType) UnmarshalJSON(b []byte) error { - num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) - if err != nil { - return err - } - *x = MetricType(num) - return nil -} - -// Deprecated: Use MetricType.Descriptor instead. -func (MetricType) EnumDescriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{0} -} - -type LabelPair struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` -} - -func (x *LabelPair) Reset() { - *x = LabelPair{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LabelPair) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LabelPair) ProtoMessage() {} - -func (x *LabelPair) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LabelPair.ProtoReflect.Descriptor instead. -func (*LabelPair) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{0} -} - -func (x *LabelPair) GetName() string { - if x != nil && x.Name != nil { - return *x.Name - } - return "" -} - -func (x *LabelPair) GetValue() string { - if x != nil && x.Value != nil { - return *x.Value - } - return "" -} - -type Gauge struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` -} - -func (x *Gauge) Reset() { - *x = Gauge{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Gauge) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Gauge) ProtoMessage() {} - -func (x *Gauge) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Gauge.ProtoReflect.Descriptor instead. -func (*Gauge) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{1} -} - -func (x *Gauge) GetValue() float64 { - if x != nil && x.Value != nil { - return *x.Value - } - return 0 -} - -type Counter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` - Exemplar *Exemplar `protobuf:"bytes,2,opt,name=exemplar" json:"exemplar,omitempty"` - CreatedTimestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_timestamp,json=createdTimestamp" json:"created_timestamp,omitempty"` -} - -func (x *Counter) Reset() { - *x = Counter{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Counter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Counter) ProtoMessage() {} - -func (x *Counter) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Counter.ProtoReflect.Descriptor instead. -func (*Counter) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{2} -} - -func (x *Counter) GetValue() float64 { - if x != nil && x.Value != nil { - return *x.Value - } - return 0 -} - -func (x *Counter) GetExemplar() *Exemplar { - if x != nil { - return x.Exemplar - } - return nil -} - -func (x *Counter) GetCreatedTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.CreatedTimestamp - } - return nil -} - -type Quantile struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Quantile *float64 `protobuf:"fixed64,1,opt,name=quantile" json:"quantile,omitempty"` - Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` -} - -func (x *Quantile) Reset() { - *x = Quantile{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Quantile) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Quantile) ProtoMessage() {} - -func (x *Quantile) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Quantile.ProtoReflect.Descriptor instead. -func (*Quantile) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{3} -} - -func (x *Quantile) GetQuantile() float64 { - if x != nil && x.Quantile != nil { - return *x.Quantile - } - return 0 -} - -func (x *Quantile) GetValue() float64 { - if x != nil && x.Value != nil { - return *x.Value - } - return 0 -} - -type Summary struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"` - SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"` - Quantile []*Quantile `protobuf:"bytes,3,rep,name=quantile" json:"quantile,omitempty"` - CreatedTimestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_timestamp,json=createdTimestamp" json:"created_timestamp,omitempty"` -} - -func (x *Summary) Reset() { - *x = Summary{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Summary) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Summary) ProtoMessage() {} - -func (x *Summary) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Summary.ProtoReflect.Descriptor instead. -func (*Summary) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{4} -} - -func (x *Summary) GetSampleCount() uint64 { - if x != nil && x.SampleCount != nil { - return *x.SampleCount - } - return 0 -} - -func (x *Summary) GetSampleSum() float64 { - if x != nil && x.SampleSum != nil { - return *x.SampleSum - } - return 0 -} - -func (x *Summary) GetQuantile() []*Quantile { - if x != nil { - return x.Quantile - } - return nil -} - -func (x *Summary) GetCreatedTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.CreatedTimestamp - } - return nil -} - -type Untyped struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` -} - -func (x *Untyped) Reset() { - *x = Untyped{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Untyped) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Untyped) ProtoMessage() {} - -func (x *Untyped) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Untyped.ProtoReflect.Descriptor instead. -func (*Untyped) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{5} -} - -func (x *Untyped) GetValue() float64 { - if x != nil && x.Value != nil { - return *x.Value - } - return 0 -} - -type Histogram struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"` - SampleCountFloat *float64 `protobuf:"fixed64,4,opt,name=sample_count_float,json=sampleCountFloat" json:"sample_count_float,omitempty"` // Overrides sample_count if > 0. - SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"` - // Buckets for the conventional histogram. - Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"` // Ordered in increasing order of upper_bound, +Inf bucket is optional. - CreatedTimestamp *timestamppb.Timestamp `protobuf:"bytes,15,opt,name=created_timestamp,json=createdTimestamp" json:"created_timestamp,omitempty"` - // schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8. - // They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and - // then each power of two is divided into 2^n logarithmic buckets. - // Or in other words, each bucket boundary is the previous boundary times 2^(2^-n). - // In the future, more bucket schemas may be added using numbers < -4 or > 8. - Schema *int32 `protobuf:"zigzag32,5,opt,name=schema" json:"schema,omitempty"` - ZeroThreshold *float64 `protobuf:"fixed64,6,opt,name=zero_threshold,json=zeroThreshold" json:"zero_threshold,omitempty"` // Breadth of the zero bucket. - ZeroCount *uint64 `protobuf:"varint,7,opt,name=zero_count,json=zeroCount" json:"zero_count,omitempty"` // Count in zero bucket. - ZeroCountFloat *float64 `protobuf:"fixed64,8,opt,name=zero_count_float,json=zeroCountFloat" json:"zero_count_float,omitempty"` // Overrides sb_zero_count if > 0. - // Negative buckets for the native histogram. - NegativeSpan []*BucketSpan `protobuf:"bytes,9,rep,name=negative_span,json=negativeSpan" json:"negative_span,omitempty"` - // Use either "negative_delta" or "negative_count", the former for - // regular histograms with integer counts, the latter for float - // histograms. - NegativeDelta []int64 `protobuf:"zigzag64,10,rep,name=negative_delta,json=negativeDelta" json:"negative_delta,omitempty"` // Count delta of each bucket compared to previous one (or to zero for 1st bucket). - NegativeCount []float64 `protobuf:"fixed64,11,rep,name=negative_count,json=negativeCount" json:"negative_count,omitempty"` // Absolute count of each bucket. - // Positive buckets for the native histogram. - // Use a no-op span (offset 0, length 0) for a native histogram without any - // observations yet and with a zero_threshold of 0. Otherwise, it would be - // indistinguishable from a classic histogram. - PositiveSpan []*BucketSpan `protobuf:"bytes,12,rep,name=positive_span,json=positiveSpan" json:"positive_span,omitempty"` - // Use either "positive_delta" or "positive_count", the former for - // regular histograms with integer counts, the latter for float - // histograms. - PositiveDelta []int64 `protobuf:"zigzag64,13,rep,name=positive_delta,json=positiveDelta" json:"positive_delta,omitempty"` // Count delta of each bucket compared to previous one (or to zero for 1st bucket). - PositiveCount []float64 `protobuf:"fixed64,14,rep,name=positive_count,json=positiveCount" json:"positive_count,omitempty"` // Absolute count of each bucket. - // Only used for native histograms. These exemplars MUST have a timestamp. - Exemplars []*Exemplar `protobuf:"bytes,16,rep,name=exemplars" json:"exemplars,omitempty"` -} - -func (x *Histogram) Reset() { - *x = Histogram{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Histogram) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Histogram) ProtoMessage() {} - -func (x *Histogram) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Histogram.ProtoReflect.Descriptor instead. -func (*Histogram) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{6} -} - -func (x *Histogram) GetSampleCount() uint64 { - if x != nil && x.SampleCount != nil { - return *x.SampleCount - } - return 0 -} - -func (x *Histogram) GetSampleCountFloat() float64 { - if x != nil && x.SampleCountFloat != nil { - return *x.SampleCountFloat - } - return 0 -} - -func (x *Histogram) GetSampleSum() float64 { - if x != nil && x.SampleSum != nil { - return *x.SampleSum - } - return 0 -} - -func (x *Histogram) GetBucket() []*Bucket { - if x != nil { - return x.Bucket - } - return nil -} - -func (x *Histogram) GetCreatedTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.CreatedTimestamp - } - return nil -} - -func (x *Histogram) GetSchema() int32 { - if x != nil && x.Schema != nil { - return *x.Schema - } - return 0 -} - -func (x *Histogram) GetZeroThreshold() float64 { - if x != nil && x.ZeroThreshold != nil { - return *x.ZeroThreshold - } - return 0 -} - -func (x *Histogram) GetZeroCount() uint64 { - if x != nil && x.ZeroCount != nil { - return *x.ZeroCount - } - return 0 -} - -func (x *Histogram) GetZeroCountFloat() float64 { - if x != nil && x.ZeroCountFloat != nil { - return *x.ZeroCountFloat - } - return 0 -} - -func (x *Histogram) GetNegativeSpan() []*BucketSpan { - if x != nil { - return x.NegativeSpan - } - return nil -} - -func (x *Histogram) GetNegativeDelta() []int64 { - if x != nil { - return x.NegativeDelta - } - return nil -} - -func (x *Histogram) GetNegativeCount() []float64 { - if x != nil { - return x.NegativeCount - } - return nil -} - -func (x *Histogram) GetPositiveSpan() []*BucketSpan { - if x != nil { - return x.PositiveSpan - } - return nil -} - -func (x *Histogram) GetPositiveDelta() []int64 { - if x != nil { - return x.PositiveDelta - } - return nil -} - -func (x *Histogram) GetPositiveCount() []float64 { - if x != nil { - return x.PositiveCount - } - return nil -} - -func (x *Histogram) GetExemplars() []*Exemplar { - if x != nil { - return x.Exemplars - } - return nil -} - -// A Bucket of a conventional histogram, each of which is treated as -// an individual counter-like time series by Prometheus. -type Bucket struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"` // Cumulative in increasing order. - CumulativeCountFloat *float64 `protobuf:"fixed64,4,opt,name=cumulative_count_float,json=cumulativeCountFloat" json:"cumulative_count_float,omitempty"` // Overrides cumulative_count if > 0. - UpperBound *float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"` // Inclusive. - Exemplar *Exemplar `protobuf:"bytes,3,opt,name=exemplar" json:"exemplar,omitempty"` -} - -func (x *Bucket) Reset() { - *x = Bucket{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Bucket) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Bucket) ProtoMessage() {} - -func (x *Bucket) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Bucket.ProtoReflect.Descriptor instead. -func (*Bucket) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{7} -} - -func (x *Bucket) GetCumulativeCount() uint64 { - if x != nil && x.CumulativeCount != nil { - return *x.CumulativeCount - } - return 0 -} - -func (x *Bucket) GetCumulativeCountFloat() float64 { - if x != nil && x.CumulativeCountFloat != nil { - return *x.CumulativeCountFloat - } - return 0 -} - -func (x *Bucket) GetUpperBound() float64 { - if x != nil && x.UpperBound != nil { - return *x.UpperBound - } - return 0 -} - -func (x *Bucket) GetExemplar() *Exemplar { - if x != nil { - return x.Exemplar - } - return nil -} - -// A BucketSpan defines a number of consecutive buckets in a native -// histogram with their offset. Logically, it would be more -// straightforward to include the bucket counts in the Span. However, -// the protobuf representation is more compact in the way the data is -// structured here (with all the buckets in a single array separate -// from the Spans). -type BucketSpan struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Offset *int32 `protobuf:"zigzag32,1,opt,name=offset" json:"offset,omitempty"` // Gap to previous span, or starting point for 1st span (which can be negative). - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` // Length of consecutive buckets. -} - -func (x *BucketSpan) Reset() { - *x = BucketSpan{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BucketSpan) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BucketSpan) ProtoMessage() {} - -func (x *BucketSpan) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BucketSpan.ProtoReflect.Descriptor instead. -func (*BucketSpan) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{8} -} - -func (x *BucketSpan) GetOffset() int32 { - if x != nil && x.Offset != nil { - return *x.Offset - } - return 0 -} - -func (x *BucketSpan) GetLength() uint32 { - if x != nil && x.Length != nil { - return *x.Length - } - return 0 -} - -type Exemplar struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"` - Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` - Timestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=timestamp" json:"timestamp,omitempty"` // OpenMetrics-style. -} - -func (x *Exemplar) Reset() { - *x = Exemplar{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Exemplar) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Exemplar) ProtoMessage() {} - -func (x *Exemplar) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Exemplar.ProtoReflect.Descriptor instead. -func (*Exemplar) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{9} -} - -func (x *Exemplar) GetLabel() []*LabelPair { - if x != nil { - return x.Label - } - return nil -} - -func (x *Exemplar) GetValue() float64 { - if x != nil && x.Value != nil { - return *x.Value - } - return 0 -} - -func (x *Exemplar) GetTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.Timestamp - } - return nil -} - -type Metric struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"` - Gauge *Gauge `protobuf:"bytes,2,opt,name=gauge" json:"gauge,omitempty"` - Counter *Counter `protobuf:"bytes,3,opt,name=counter" json:"counter,omitempty"` - Summary *Summary `protobuf:"bytes,4,opt,name=summary" json:"summary,omitempty"` - Untyped *Untyped `protobuf:"bytes,5,opt,name=untyped" json:"untyped,omitempty"` - Histogram *Histogram `protobuf:"bytes,7,opt,name=histogram" json:"histogram,omitempty"` - TimestampMs *int64 `protobuf:"varint,6,opt,name=timestamp_ms,json=timestampMs" json:"timestamp_ms,omitempty"` -} - -func (x *Metric) Reset() { - *x = Metric{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Metric) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Metric) ProtoMessage() {} - -func (x *Metric) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Metric.ProtoReflect.Descriptor instead. -func (*Metric) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{10} -} - -func (x *Metric) GetLabel() []*LabelPair { - if x != nil { - return x.Label - } - return nil -} - -func (x *Metric) GetGauge() *Gauge { - if x != nil { - return x.Gauge - } - return nil -} - -func (x *Metric) GetCounter() *Counter { - if x != nil { - return x.Counter - } - return nil -} - -func (x *Metric) GetSummary() *Summary { - if x != nil { - return x.Summary - } - return nil -} - -func (x *Metric) GetUntyped() *Untyped { - if x != nil { - return x.Untyped - } - return nil -} - -func (x *Metric) GetHistogram() *Histogram { - if x != nil { - return x.Histogram - } - return nil -} - -func (x *Metric) GetTimestampMs() int64 { - if x != nil && x.TimestampMs != nil { - return *x.TimestampMs - } - return 0 -} - -type MetricFamily struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Help *string `protobuf:"bytes,2,opt,name=help" json:"help,omitempty"` - Type *MetricType `protobuf:"varint,3,opt,name=type,enum=io.prometheus.client.MetricType" json:"type,omitempty"` - Metric []*Metric `protobuf:"bytes,4,rep,name=metric" json:"metric,omitempty"` - Unit *string `protobuf:"bytes,5,opt,name=unit" json:"unit,omitempty"` -} - -func (x *MetricFamily) Reset() { - *x = MetricFamily{} - if protoimpl.UnsafeEnabled { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MetricFamily) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MetricFamily) ProtoMessage() {} - -func (x *MetricFamily) ProtoReflect() protoreflect.Message { - mi := &file_io_prometheus_client_metrics_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MetricFamily.ProtoReflect.Descriptor instead. -func (*MetricFamily) Descriptor() ([]byte, []int) { - return file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{11} -} - -func (x *MetricFamily) GetName() string { - if x != nil && x.Name != nil { - return *x.Name - } - return "" -} - -func (x *MetricFamily) GetHelp() string { - if x != nil && x.Help != nil { - return *x.Help - } - return "" -} - -func (x *MetricFamily) GetType() MetricType { - if x != nil && x.Type != nil { - return *x.Type - } - return MetricType_COUNTER -} - -func (x *MetricFamily) GetMetric() []*Metric { - if x != nil { - return x.Metric - } - return nil -} - -func (x *MetricFamily) GetUnit() string { - if x != nil && x.Unit != nil { - return *x.Unit - } - return "" -} - -var File_io_prometheus_client_metrics_proto protoreflect.FileDescriptor - -var file_io_prometheus_client_metrics_proto_rawDesc = []byte{ - 0x0a, 0x22, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2f, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, - 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x09, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x1d, 0x0a, 0x05, 0x47, 0x61, 0x75, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, - 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78, 0x65, - 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x12, - 0x47, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3c, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, - 0x74, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, - 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x53, 0x75, 0x6d, 0x12, 0x3a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, - 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x51, 0x75, - 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, - 0x12, 0x47, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x1f, 0x0a, 0x07, 0x55, 0x6e, 0x74, - 0x79, 0x70, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xea, 0x05, 0x0a, 0x09, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x12, 0x34, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, - 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, - 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x47, - 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, - 0x25, 0x0a, 0x0e, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, - 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x7a, 0x65, 0x72, 0x6f, 0x54, 0x68, 0x72, - 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x7a, 0x65, 0x72, 0x6f, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, - 0x0e, 0x7a, 0x65, 0x72, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, - 0x45, 0x0a, 0x0d, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x6e, - 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, - 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75, - 0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x0c, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x76, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x12, 0x52, 0x0d, - 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x25, 0x0a, - 0x0e, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x0b, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0d, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x0d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69, 0x6f, - 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x0c, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x0d, 0x20, - 0x03, 0x28, 0x12, 0x52, 0x0d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x44, 0x65, 0x6c, - 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0d, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x09, 0x65, 0x78, 0x65, - 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, - 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x09, 0x65, 0x78, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x06, 0x42, 0x75, 0x63, 0x6b, - 0x65, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x63, 0x75, - 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, - 0x16, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x14, 0x63, - 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c, - 0x6f, 0x61, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x70, 0x65, 0x72, 0x42, - 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, - 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, - 0x22, 0x3c, 0x0a, 0x0a, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, - 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x91, - 0x01, 0x0a, 0x08, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x12, 0x35, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69, 0x6f, 0x2e, - 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x22, 0xff, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x35, 0x0a, - 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69, - 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x12, 0x31, 0x0a, 0x05, 0x67, 0x61, 0x75, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, - 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x61, 0x75, 0x67, 0x65, - 0x52, 0x05, 0x67, 0x61, 0x75, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, - 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x12, 0x37, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, - 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x37, 0x0a, 0x07, 0x75, 0x6e, 0x74, - 0x79, 0x70, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e, - 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x2e, 0x55, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x52, 0x07, 0x75, 0x6e, 0x74, 0x79, 0x70, - 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, - 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x69, 0x73, - 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x09, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, - 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6d, - 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x4d, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, - 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c, - 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x12, 0x34, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x69, 0x6f, - 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, - 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x2a, 0x62, 0x0a, - 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, - 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, - 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x4d, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x02, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x54, 0x59, 0x50, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0d, 0x0a, - 0x09, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, - 0x47, 0x41, 0x55, 0x47, 0x45, 0x5f, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x10, - 0x05, 0x42, 0x52, 0x0a, 0x14, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, - 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, - 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x67, 0x6f, - 0x3b, 0x69, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x5f, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, -} - -var ( - file_io_prometheus_client_metrics_proto_rawDescOnce sync.Once - file_io_prometheus_client_metrics_proto_rawDescData = file_io_prometheus_client_metrics_proto_rawDesc -) - -func file_io_prometheus_client_metrics_proto_rawDescGZIP() []byte { - file_io_prometheus_client_metrics_proto_rawDescOnce.Do(func() { - file_io_prometheus_client_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_io_prometheus_client_metrics_proto_rawDescData) - }) - return file_io_prometheus_client_metrics_proto_rawDescData -} - -var file_io_prometheus_client_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_io_prometheus_client_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 12) -var file_io_prometheus_client_metrics_proto_goTypes = []interface{}{ - (MetricType)(0), // 0: io.prometheus.client.MetricType - (*LabelPair)(nil), // 1: io.prometheus.client.LabelPair - (*Gauge)(nil), // 2: io.prometheus.client.Gauge - (*Counter)(nil), // 3: io.prometheus.client.Counter - (*Quantile)(nil), // 4: io.prometheus.client.Quantile - (*Summary)(nil), // 5: io.prometheus.client.Summary - (*Untyped)(nil), // 6: io.prometheus.client.Untyped - (*Histogram)(nil), // 7: io.prometheus.client.Histogram - (*Bucket)(nil), // 8: io.prometheus.client.Bucket - (*BucketSpan)(nil), // 9: io.prometheus.client.BucketSpan - (*Exemplar)(nil), // 10: io.prometheus.client.Exemplar - (*Metric)(nil), // 11: io.prometheus.client.Metric - (*MetricFamily)(nil), // 12: io.prometheus.client.MetricFamily - (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp -} -var file_io_prometheus_client_metrics_proto_depIdxs = []int32{ - 10, // 0: io.prometheus.client.Counter.exemplar:type_name -> io.prometheus.client.Exemplar - 13, // 1: io.prometheus.client.Counter.created_timestamp:type_name -> google.protobuf.Timestamp - 4, // 2: io.prometheus.client.Summary.quantile:type_name -> io.prometheus.client.Quantile - 13, // 3: io.prometheus.client.Summary.created_timestamp:type_name -> google.protobuf.Timestamp - 8, // 4: io.prometheus.client.Histogram.bucket:type_name -> io.prometheus.client.Bucket - 13, // 5: io.prometheus.client.Histogram.created_timestamp:type_name -> google.protobuf.Timestamp - 9, // 6: io.prometheus.client.Histogram.negative_span:type_name -> io.prometheus.client.BucketSpan - 9, // 7: io.prometheus.client.Histogram.positive_span:type_name -> io.prometheus.client.BucketSpan - 10, // 8: io.prometheus.client.Histogram.exemplars:type_name -> io.prometheus.client.Exemplar - 10, // 9: io.prometheus.client.Bucket.exemplar:type_name -> io.prometheus.client.Exemplar - 1, // 10: io.prometheus.client.Exemplar.label:type_name -> io.prometheus.client.LabelPair - 13, // 11: io.prometheus.client.Exemplar.timestamp:type_name -> google.protobuf.Timestamp - 1, // 12: io.prometheus.client.Metric.label:type_name -> io.prometheus.client.LabelPair - 2, // 13: io.prometheus.client.Metric.gauge:type_name -> io.prometheus.client.Gauge - 3, // 14: io.prometheus.client.Metric.counter:type_name -> io.prometheus.client.Counter - 5, // 15: io.prometheus.client.Metric.summary:type_name -> io.prometheus.client.Summary - 6, // 16: io.prometheus.client.Metric.untyped:type_name -> io.prometheus.client.Untyped - 7, // 17: io.prometheus.client.Metric.histogram:type_name -> io.prometheus.client.Histogram - 0, // 18: io.prometheus.client.MetricFamily.type:type_name -> io.prometheus.client.MetricType - 11, // 19: io.prometheus.client.MetricFamily.metric:type_name -> io.prometheus.client.Metric - 20, // [20:20] is the sub-list for method output_type - 20, // [20:20] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name -} - -func init() { file_io_prometheus_client_metrics_proto_init() } -func file_io_prometheus_client_metrics_proto_init() { - if File_io_prometheus_client_metrics_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_io_prometheus_client_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LabelPair); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Gauge); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Counter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Quantile); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Summary); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Untyped); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Histogram); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Bucket); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BucketSpan); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Exemplar); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metric); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_io_prometheus_client_metrics_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetricFamily); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_io_prometheus_client_metrics_proto_rawDesc, - NumEnums: 1, - NumMessages: 12, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_io_prometheus_client_metrics_proto_goTypes, - DependencyIndexes: file_io_prometheus_client_metrics_proto_depIdxs, - EnumInfos: file_io_prometheus_client_metrics_proto_enumTypes, - MessageInfos: file_io_prometheus_client_metrics_proto_msgTypes, - }.Build() - File_io_prometheus_client_metrics_proto = out.File - file_io_prometheus_client_metrics_proto_rawDesc = nil - file_io_prometheus_client_metrics_proto_goTypes = nil - file_io_prometheus_client_metrics_proto_depIdxs = nil -} diff --git a/vendor/github.com/prometheus/common/LICENSE b/vendor/github.com/prometheus/common/LICENSE deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/vendor/github.com/prometheus/common/LICENSE +++ /dev/null @@ -1,201 +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. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/prometheus/common/NOTICE b/vendor/github.com/prometheus/common/NOTICE deleted file mode 100644 index 636a2c1a5e88..000000000000 --- a/vendor/github.com/prometheus/common/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Common libraries shared by Prometheus Go components. -Copyright 2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go deleted file mode 100644 index 8f8dc65d38e1..000000000000 --- a/vendor/github.com/prometheus/common/expfmt/decode.go +++ /dev/null @@ -1,464 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expfmt - -import ( - "bufio" - "fmt" - "io" - "math" - "mime" - "net/http" - - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/encoding/protodelim" - - "github.com/prometheus/common/model" -) - -// Decoder types decode an input stream into metric families. -type Decoder interface { - Decode(*dto.MetricFamily) error -} - -// DecodeOptions contains options used by the Decoder and in sample extraction. -type DecodeOptions struct { - // Timestamp is added to each value from the stream that has no explicit timestamp set. - Timestamp model.Time -} - -// ResponseFormat extracts the correct format from a HTTP response header. -// If no matching format can be found FormatUnknown is returned. -func ResponseFormat(h http.Header) Format { - ct := h.Get(hdrContentType) - - mediatype, params, err := mime.ParseMediaType(ct) - if err != nil { - return FmtUnknown - } - - const textType = "text/plain" - - switch mediatype { - case ProtoType: - if p, ok := params["proto"]; ok && p != ProtoProtocol { - return FmtUnknown - } - if e, ok := params["encoding"]; ok && e != "delimited" { - return FmtUnknown - } - return FmtProtoDelim - - case textType: - if v, ok := params["version"]; ok && v != TextVersion { - return FmtUnknown - } - return FmtText - } - - return FmtUnknown -} - -// NewDecoder returns a new decoder based on the given input format. Metric -// names are validated based on the provided Format -- if the format requires -// escaping, raditional Prometheues validity checking is used. Otherwise, names -// are checked for UTF-8 validity. Supported formats include delimited protobuf -// and Prometheus text format. For historical reasons, this decoder fallbacks -// to classic text decoding for any other format. This decoder does not fully -// support OpenMetrics although it may often succeed due to the similarities -// between the formats. This decoder may not support the latest features of -// Prometheus text format and is not intended for high-performance applications. -// See: https://github.com/prometheus/common/issues/812 -func NewDecoder(r io.Reader, format Format) Decoder { - scheme := model.LegacyValidation - if format.ToEscapingScheme() == model.NoEscaping { - scheme = model.UTF8Validation - } - switch format.FormatType() { - case TypeProtoDelim: - return &protoDecoder{r: bufio.NewReader(r), s: scheme} - case TypeProtoText, TypeProtoCompact: - return &errDecoder{err: fmt.Errorf("format %s not supported for decoding", format)} - } - return &textDecoder{r: r, s: scheme} -} - -// protoDecoder implements the Decoder interface for protocol buffers. -type protoDecoder struct { - r protodelim.Reader - s model.ValidationScheme -} - -// Decode implements the Decoder interface. -func (d *protoDecoder) Decode(v *dto.MetricFamily) error { - opts := protodelim.UnmarshalOptions{ - MaxSize: -1, - } - if err := opts.UnmarshalFrom(d.r, v); err != nil { - return err - } - if !d.s.IsValidMetricName(v.GetName()) { - return fmt.Errorf("invalid metric name %q", v.GetName()) - } - for _, m := range v.GetMetric() { - if m == nil { - continue - } - for _, l := range m.GetLabel() { - if l == nil { - continue - } - if !model.LabelValue(l.GetValue()).IsValid() { - return fmt.Errorf("invalid label value %q", l.GetValue()) - } - if !d.s.IsValidLabelName(l.GetName()) { - return fmt.Errorf("invalid label name %q", l.GetName()) - } - } - } - return nil -} - -// errDecoder is an error-state decoder that always returns the same error. -type errDecoder struct { - err error -} - -func (d *errDecoder) Decode(*dto.MetricFamily) error { - return d.err -} - -// textDecoder implements the Decoder interface for the text protocol. -type textDecoder struct { - r io.Reader - fams map[string]*dto.MetricFamily - s model.ValidationScheme - err error -} - -// Decode implements the Decoder interface. -func (d *textDecoder) Decode(v *dto.MetricFamily) error { - if d.err == nil { - // Read all metrics in one shot. - p := NewTextParser(d.s) - d.fams, d.err = p.TextToMetricFamilies(d.r) - // If we don't get an error, store io.EOF for the end. - if d.err == nil { - d.err = io.EOF - } - } - // Pick off one MetricFamily per Decode until there's nothing left. - for key, fam := range d.fams { - v.Name = fam.Name - v.Help = fam.Help - v.Type = fam.Type - v.Metric = fam.Metric - delete(d.fams, key) - return nil - } - return d.err -} - -// SampleDecoder wraps a Decoder to extract samples from the metric families -// decoded by the wrapped Decoder. -type SampleDecoder struct { - Dec Decoder - Opts *DecodeOptions - - f dto.MetricFamily -} - -// Decode calls the Decode method of the wrapped Decoder and then extracts the -// samples from the decoded MetricFamily into the provided model.Vector. -func (sd *SampleDecoder) Decode(s *model.Vector) error { - err := sd.Dec.Decode(&sd.f) - if err != nil { - return err - } - *s, err = extractSamples(&sd.f, sd.Opts) - return err -} - -// ExtractSamples builds a slice of samples from the provided metric -// families. If an error occurs during sample extraction, it continues to -// extract from the remaining metric families. The returned error is the last -// error that has occurred. -func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) { - var ( - all model.Vector - lastErr error - ) - for _, f := range fams { - some, err := extractSamples(f, o) - if err != nil { - lastErr = err - continue - } - all = append(all, some...) - } - return all, lastErr -} - -func extractSamples(f *dto.MetricFamily, o *DecodeOptions) (model.Vector, error) { - switch f.GetType() { - case dto.MetricType_COUNTER: - return extractCounter(o, f), nil - case dto.MetricType_GAUGE: - return extractGauge(o, f), nil - case dto.MetricType_SUMMARY: - return extractSummary(o, f), nil - case dto.MetricType_UNTYPED: - return extractUntyped(o, f), nil - case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: - return extractHistogram(o, f), nil - } - return nil, fmt.Errorf("expfmt.extractSamples: unknown metric family type %v", f.GetType()) -} - -func extractCounter(o *DecodeOptions, f *dto.MetricFamily) model.Vector { - samples := make(model.Vector, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Counter == nil { - continue - } - - lset := make(model.LabelSet, len(m.Label)+1) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) - - smpl := &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(m.Counter.GetValue()), - } - - if m.TimestampMs != nil { - smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) - } else { - smpl.Timestamp = o.Timestamp - } - - samples = append(samples, smpl) - } - - return samples -} - -func extractGauge(o *DecodeOptions, f *dto.MetricFamily) model.Vector { - samples := make(model.Vector, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Gauge == nil { - continue - } - - lset := make(model.LabelSet, len(m.Label)+1) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) - - smpl := &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(m.Gauge.GetValue()), - } - - if m.TimestampMs != nil { - smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) - } else { - smpl.Timestamp = o.Timestamp - } - - samples = append(samples, smpl) - } - - return samples -} - -func extractUntyped(o *DecodeOptions, f *dto.MetricFamily) model.Vector { - samples := make(model.Vector, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Untyped == nil { - continue - } - - lset := make(model.LabelSet, len(m.Label)+1) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) - - smpl := &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(m.Untyped.GetValue()), - } - - if m.TimestampMs != nil { - smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) - } else { - smpl.Timestamp = o.Timestamp - } - - samples = append(samples, smpl) - } - - return samples -} - -func extractSummary(o *DecodeOptions, f *dto.MetricFamily) model.Vector { - samples := make(model.Vector, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Summary == nil { - continue - } - - timestamp := o.Timestamp - if m.TimestampMs != nil { - timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) - } - - for _, q := range m.Summary.Quantile { - lset := make(model.LabelSet, len(m.Label)+2) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - // BUG(matt): Update other names to "quantile". - lset[model.LabelName(model.QuantileLabel)] = model.LabelValue(fmt.Sprint(q.GetQuantile())) - lset[model.MetricNameLabel] = model.LabelValue(f.GetName()) - - samples = append(samples, &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(q.GetValue()), - Timestamp: timestamp, - }) - } - - lset := make(model.LabelSet, len(m.Label)+1) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum") - - samples = append(samples, &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(m.Summary.GetSampleSum()), - Timestamp: timestamp, - }) - - lset = make(model.LabelSet, len(m.Label)+1) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count") - - samples = append(samples, &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(m.Summary.GetSampleCount()), - Timestamp: timestamp, - }) - } - - return samples -} - -func extractHistogram(o *DecodeOptions, f *dto.MetricFamily) model.Vector { - samples := make(model.Vector, 0, len(f.Metric)) - - for _, m := range f.Metric { - if m.Histogram == nil { - continue - } - - timestamp := o.Timestamp - if m.TimestampMs != nil { - timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000) - } - - infSeen := false - - for _, q := range m.Histogram.Bucket { - lset := make(model.LabelSet, len(m.Label)+2) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.LabelName(model.BucketLabel)] = model.LabelValue(fmt.Sprint(q.GetUpperBound())) - lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket") - - if math.IsInf(q.GetUpperBound(), +1) { - infSeen = true - } - - v := q.GetCumulativeCountFloat() - if v <= 0 { - v = float64(q.GetCumulativeCount()) - } - samples = append(samples, &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(v), - Timestamp: timestamp, - }) - } - - lset := make(model.LabelSet, len(m.Label)+1) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum") - - samples = append(samples, &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(m.Histogram.GetSampleSum()), - Timestamp: timestamp, - }) - - lset = make(model.LabelSet, len(m.Label)+1) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count") - - v := m.Histogram.GetSampleCountFloat() - if v <= 0 { - v = float64(m.Histogram.GetSampleCount()) - } - count := &model.Sample{ - Metric: model.Metric(lset), - Value: model.SampleValue(v), - Timestamp: timestamp, - } - samples = append(samples, count) - - if !infSeen { - // Append an infinity bucket sample. - lset := make(model.LabelSet, len(m.Label)+2) - for _, p := range m.Label { - lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue()) - } - lset[model.LabelName(model.BucketLabel)] = model.LabelValue("+Inf") - lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket") - - samples = append(samples, &model.Sample{ - Metric: model.Metric(lset), - Value: count.Value, - Timestamp: timestamp, - }) - } - } - - return samples -} diff --git a/vendor/github.com/prometheus/common/expfmt/encode.go b/vendor/github.com/prometheus/common/expfmt/encode.go deleted file mode 100644 index 73c24dfbc9cb..000000000000 --- a/vendor/github.com/prometheus/common/expfmt/encode.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expfmt - -import ( - "fmt" - "io" - "net/http" - - "github.com/munnerz/goautoneg" - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/encoding/protodelim" - "google.golang.org/protobuf/encoding/prototext" - - "github.com/prometheus/common/model" -) - -// Encoder types encode metric families into an underlying wire protocol. -type Encoder interface { - Encode(*dto.MetricFamily) error -} - -// Closer is implemented by Encoders that need to be closed to finalize -// encoding. (For example, OpenMetrics needs a final `# EOF` line.) -// -// Note that all Encoder implementations returned from this package implement -// Closer, too, even if the Close call is a no-op. This happens in preparation -// for adding a Close method to the Encoder interface directly in a (mildly -// breaking) release in the future. -type Closer interface { - Close() error -} - -type encoderCloser struct { - encode func(*dto.MetricFamily) error - close func() error -} - -func (ec encoderCloser) Encode(v *dto.MetricFamily) error { - return ec.encode(v) -} - -func (ec encoderCloser) Close() error { - return ec.close() -} - -// Negotiate returns the Content-Type based on the given Accept header. If no -// appropriate accepted type is found, FmtText is returned (which is the -// Prometheus text format). This function will never negotiate FmtOpenMetrics, -// as the support is still experimental. To include the option to negotiate -// FmtOpenMetrics, use NegotiateIncludingOpenMetrics. -func Negotiate(h http.Header) Format { - escapingScheme := Format(fmt.Sprintf("; escaping=%s", Format(model.NameEscapingScheme.String()))) - for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) { - if escapeParam := ac.Params[model.EscapingKey]; escapeParam != "" { - switch Format(escapeParam) { - case model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues: - escapingScheme = Format("; escaping=" + escapeParam) - default: - // If the escaping parameter is unknown, ignore it. - } - } - ver := ac.Params["version"] - if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol { - switch ac.Params["encoding"] { - case "delimited": - return FmtProtoDelim + escapingScheme - case "text": - return FmtProtoText + escapingScheme - case "compact-text": - return FmtProtoCompact + escapingScheme - } - } - if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { - return FmtText + escapingScheme - } - } - return FmtText + escapingScheme -} - -// NegotiateIncludingOpenMetrics works like Negotiate but includes -// FmtOpenMetrics as an option for the result. Note that this function is -// temporary and will disappear once FmtOpenMetrics is fully supported and as -// such may be negotiated by the normal Negotiate function. -func NegotiateIncludingOpenMetrics(h http.Header) Format { - escapingScheme := Format(fmt.Sprintf("; escaping=%s", Format(model.NameEscapingScheme.String()))) - for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) { - if escapeParam := ac.Params[model.EscapingKey]; escapeParam != "" { - switch Format(escapeParam) { - case model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues: - escapingScheme = Format("; escaping=" + escapeParam) - default: - // If the escaping parameter is unknown, ignore it. - } - } - ver := ac.Params["version"] - if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol { - switch ac.Params["encoding"] { - case "delimited": - return FmtProtoDelim + escapingScheme - case "text": - return FmtProtoText + escapingScheme - case "compact-text": - return FmtProtoCompact + escapingScheme - } - } - if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { - return FmtText + escapingScheme - } - if ac.Type+"/"+ac.SubType == OpenMetricsType && (ver == OpenMetricsVersion_0_0_1 || ver == OpenMetricsVersion_1_0_0 || ver == "") { - switch ver { - case OpenMetricsVersion_1_0_0: - return FmtOpenMetrics_1_0_0 + escapingScheme - default: - return FmtOpenMetrics_0_0_1 + escapingScheme - } - } - } - return FmtText + escapingScheme -} - -// NewEncoder returns a new encoder based on content type negotiation. All -// Encoder implementations returned by NewEncoder also implement Closer, and -// callers should always call the Close method. It is currently only required -// for FmtOpenMetrics, but a future (breaking) release will add the Close method -// to the Encoder interface directly. The current version of the Encoder -// interface is kept for backwards compatibility. -// In cases where the Format does not allow for UTF-8 names, the global -// NameEscapingScheme will be applied. -// -// NewEncoder can be called with additional options to customize the OpenMetrics text output. -// For example: -// NewEncoder(w, FmtOpenMetrics_1_0_0, WithCreatedLines()) -// -// Extra options are ignored for all other formats. -func NewEncoder(w io.Writer, format Format, options ...EncoderOption) Encoder { - escapingScheme := format.ToEscapingScheme() - - switch format.FormatType() { - case TypeProtoDelim: - return encoderCloser{ - encode: func(v *dto.MetricFamily) error { - _, err := protodelim.MarshalTo(w, model.EscapeMetricFamily(v, escapingScheme)) - return err - }, - close: func() error { return nil }, - } - case TypeProtoCompact: - return encoderCloser{ - encode: func(v *dto.MetricFamily) error { - _, err := fmt.Fprintln(w, model.EscapeMetricFamily(v, escapingScheme).String()) - return err - }, - close: func() error { return nil }, - } - case TypeProtoText: - return encoderCloser{ - encode: func(v *dto.MetricFamily) error { - _, err := fmt.Fprintln(w, prototext.Format(model.EscapeMetricFamily(v, escapingScheme))) - return err - }, - close: func() error { return nil }, - } - case TypeTextPlain: - return encoderCloser{ - encode: func(v *dto.MetricFamily) error { - _, err := MetricFamilyToText(w, model.EscapeMetricFamily(v, escapingScheme)) - return err - }, - close: func() error { return nil }, - } - case TypeOpenMetrics: - return encoderCloser{ - encode: func(v *dto.MetricFamily) error { - _, err := MetricFamilyToOpenMetrics(w, model.EscapeMetricFamily(v, escapingScheme), options...) - return err - }, - close: func() error { - _, err := FinalizeOpenMetrics(w) - return err - }, - } - } - panic(fmt.Errorf("expfmt.NewEncoder: unknown format %q", format)) -} diff --git a/vendor/github.com/prometheus/common/expfmt/expfmt.go b/vendor/github.com/prometheus/common/expfmt/expfmt.go deleted file mode 100644 index 4e4c13e724c2..000000000000 --- a/vendor/github.com/prometheus/common/expfmt/expfmt.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package expfmt contains tools for reading and writing Prometheus metrics. -package expfmt - -import ( - "errors" - "strings" - - "github.com/prometheus/common/model" -) - -// Format specifies the HTTP content type of the different wire protocols. -type Format string - -// Constants to assemble the Content-Type values for the different wire -// protocols. The Content-Type strings here are all for the legacy exposition -// formats, where valid characters for metric names and label names are limited. -// Support for arbitrary UTF-8 characters in those names is already partially -// implemented in this module (see model.ValidationScheme), but to actually use -// it on the wire, new content-type strings will have to be agreed upon and -// added here. -const ( - TextVersion = "0.0.4" - ProtoType = `application/vnd.google.protobuf` - ProtoProtocol = `io.prometheus.client.MetricFamily` - // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoCompact) instead. - ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" - OpenMetricsType = `application/openmetrics-text` - //nolint:revive // Allow for underscores. - OpenMetricsVersion_0_0_1 = "0.0.1" - //nolint:revive // Allow for underscores. - OpenMetricsVersion_1_0_0 = "1.0.0" - - // The Content-Type values for the different wire protocols. Do not do direct - // comparisons to these constants, instead use the comparison functions. - // - // Deprecated: Use expfmt.NewFormat(expfmt.TypeUnknown) instead. - FmtUnknown Format = `` - // Deprecated: Use expfmt.NewFormat(expfmt.TypeTextPlain) instead. - FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8` - // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoDelim) instead. - FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` - // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoText) instead. - FmtProtoText Format = ProtoFmt + ` encoding=text` - // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoCompact) instead. - FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` - // Deprecated: Use expfmt.NewFormat(expfmt.TypeOpenMetrics) instead. - //nolint:revive // Allow for underscores. - FmtOpenMetrics_1_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_1_0_0 + `; charset=utf-8` - // Deprecated: Use expfmt.NewFormat(expfmt.TypeOpenMetrics) instead. - //nolint:revive // Allow for underscores. - FmtOpenMetrics_0_0_1 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_0_0_1 + `; charset=utf-8` -) - -const ( - hdrContentType = "Content-Type" - hdrAccept = "Accept" -) - -// FormatType is a Go enum representing the overall category for the given -// Format. As the number of Format permutations increases, doing basic string -// comparisons are not feasible, so this enum captures the most useful -// high-level attribute of the Format string. -type FormatType int - -const ( - TypeUnknown FormatType = iota - TypeProtoCompact - TypeProtoDelim - TypeProtoText - TypeTextPlain - TypeOpenMetrics -) - -// NewFormat generates a new Format from the type provided. Mostly used for -// tests, most Formats should be generated as part of content negotiation in -// encode.go. If a type has more than one version, the latest version will be -// returned. -func NewFormat(t FormatType) Format { - switch t { - case TypeProtoCompact: - return FmtProtoCompact - case TypeProtoDelim: - return FmtProtoDelim - case TypeProtoText: - return FmtProtoText - case TypeTextPlain: - return FmtText - case TypeOpenMetrics: - return FmtOpenMetrics_1_0_0 - default: - return FmtUnknown - } -} - -// NewOpenMetricsFormat generates a new OpenMetrics format matching the -// specified version number. -func NewOpenMetricsFormat(version string) (Format, error) { - if version == OpenMetricsVersion_0_0_1 { - return FmtOpenMetrics_0_0_1, nil - } - if version == OpenMetricsVersion_1_0_0 { - return FmtOpenMetrics_1_0_0, nil - } - return FmtUnknown, errors.New("unknown open metrics version string") -} - -// WithEscapingScheme returns a copy of Format with the specified escaping -// scheme appended to the end. If an escaping scheme already exists it is -// removed. -func (f Format) WithEscapingScheme(s model.EscapingScheme) Format { - var terms []string - for _, p := range strings.Split(string(f), ";") { - toks := strings.Split(p, "=") - if len(toks) != 2 { - trimmed := strings.TrimSpace(p) - if len(trimmed) > 0 { - terms = append(terms, trimmed) - } - continue - } - key := strings.TrimSpace(toks[0]) - if key != model.EscapingKey { - terms = append(terms, strings.TrimSpace(p)) - } - } - terms = append(terms, model.EscapingKey+"="+s.String()) - return Format(strings.Join(terms, "; ")) -} - -// FormatType deduces an overall FormatType for the given format. -func (f Format) FormatType() FormatType { - toks := strings.Split(string(f), ";") - params := make(map[string]string) - for i, t := range toks { - if i == 0 { - continue - } - args := strings.Split(t, "=") - if len(args) != 2 { - continue - } - params[strings.TrimSpace(args[0])] = strings.TrimSpace(args[1]) - } - - switch strings.TrimSpace(toks[0]) { - case ProtoType: - if params["proto"] != ProtoProtocol { - return TypeUnknown - } - switch params["encoding"] { - case "delimited": - return TypeProtoDelim - case "text": - return TypeProtoText - case "compact-text": - return TypeProtoCompact - default: - return TypeUnknown - } - case OpenMetricsType: - if params["charset"] != "utf-8" { - return TypeUnknown - } - return TypeOpenMetrics - case "text/plain": - v, ok := params["version"] - if !ok { - return TypeTextPlain - } - if v == TextVersion { - return TypeTextPlain - } - return TypeUnknown - default: - return TypeUnknown - } -} - -// ToEscapingScheme returns an EscapingScheme depending on the Format. Iff the -// Format contains a escaping=allow-utf-8 term, it will select NoEscaping. If a valid -// "escaping" term exists, that will be used. Otherwise, the global default will -// be returned. -func (f Format) ToEscapingScheme() model.EscapingScheme { - for _, p := range strings.Split(string(f), ";") { - toks := strings.Split(p, "=") - if len(toks) != 2 { - continue - } - key, value := strings.TrimSpace(toks[0]), strings.TrimSpace(toks[1]) - if key == model.EscapingKey { - scheme, err := model.ToEscapingScheme(value) - if err != nil { - return model.NameEscapingScheme - } - return scheme - } - } - return model.NameEscapingScheme -} diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go deleted file mode 100644 index 872c0c15b400..000000000000 --- a/vendor/github.com/prometheus/common/expfmt/fuzz.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Build only when actually fuzzing -//go:build gofuzz - -package expfmt - -import ( - "bytes" - - "github.com/prometheus/common/model" -) - -// Fuzz text metric parser with with github.com/dvyukov/go-fuzz: -// -// go-fuzz-build github.com/prometheus/common/expfmt -// go-fuzz -bin expfmt-fuzz.zip -workdir fuzz -// -// Further input samples should go in the folder fuzz/corpus. -func Fuzz(in []byte) int { - parser := NewTextParser(model.UTF8Validation) - _, err := parser.TextToMetricFamilies(bytes.NewReader(in)) - if err != nil { - return 0 - } - - return 1 -} diff --git a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go deleted file mode 100644 index 21b93bca362c..000000000000 --- a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go +++ /dev/null @@ -1,712 +0,0 @@ -// Copyright 2020 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expfmt - -import ( - "bufio" - "bytes" - "fmt" - "io" - "math" - "strconv" - "strings" - - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/types/known/timestamppb" - - "github.com/prometheus/common/model" -) - -type encoderOption struct { - withCreatedLines bool - withUnit bool -} - -type EncoderOption func(*encoderOption) - -// WithCreatedLines is an EncoderOption that configures the OpenMetrics encoder -// to include _created lines (See -// https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1). -// Created timestamps can improve the accuracy of series reset detection, but -// come with a bandwidth cost. -// -// At the time of writing, created timestamp ingestion is still experimental in -// Prometheus and need to be enabled with the feature-flag -// `--feature-flag=created-timestamp-zero-ingestion`, and breaking changes are -// still possible. Therefore, it is recommended to use this feature with caution. -func WithCreatedLines() EncoderOption { - return func(t *encoderOption) { - t.withCreatedLines = true - } -} - -// WithUnit is an EncoderOption enabling a set unit to be written to the output -// and to be added to the metric name, if it's not there already, as a suffix. -// Without opting in this way, the unit will not be added to the metric name and, -// on top of that, the unit will not be passed onto the output, even if it -// were declared in the *dto.MetricFamily struct, i.e. even if in.Unit !=nil. -func WithUnit() EncoderOption { - return func(t *encoderOption) { - t.withUnit = true - } -} - -// MetricFamilyToOpenMetrics converts a MetricFamily proto message into the -// OpenMetrics text format and writes the resulting lines to 'out'. It returns -// the number of bytes written and any error encountered. The output will have -// the same order as the input, no further sorting is performed. Furthermore, -// this function assumes the input is already sanitized and does not perform any -// sanity checks. If the input contains duplicate metrics or invalid metric or -// label names, the conversion will result in invalid text format output. -// -// If metric names conform to the legacy validation pattern, they will be placed -// outside the brackets in the traditional way, like `foo{}`. If the metric name -// fails the legacy validation check, it will be placed quoted inside the -// brackets: `{"foo"}`. As stated above, the input is assumed to be santized and -// no error will be thrown in this case. -// -// Similar to metric names, if label names conform to the legacy validation -// pattern, they will be unquoted as normal, like `foo{bar="baz"}`. If the label -// name fails the legacy validation check, it will be quoted: -// `foo{"bar"="baz"}`. As stated above, the input is assumed to be santized and -// no error will be thrown in this case. -// -// This function fulfills the type 'expfmt.encoder'. -// -// Note that OpenMetrics requires a final `# EOF` line. Since this function acts -// on individual metric families, it is the responsibility of the caller to -// append this line to 'out' once all metric families have been written. -// Conveniently, this can be done by calling FinalizeOpenMetrics. -// -// The output should be fully OpenMetrics compliant. However, there are a few -// missing features and peculiarities to avoid complications when switching from -// Prometheus to OpenMetrics or vice versa: -// -// - Counters are expected to have the `_total` suffix in their metric name. In -// the output, the suffix will be truncated from the `# TYPE`, `# HELP` and `# UNIT` -// lines. A counter with a missing `_total` suffix is not an error. However, -// its type will be set to `unknown` in that case to avoid invalid OpenMetrics -// output. -// -// - According to the OM specs, the `# UNIT` line is optional, but if populated, -// the unit has to be present in the metric name as its suffix: -// (see https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#unit). -// However, in order to accommodate any potential scenario where such a change in the -// metric name is not desirable, the users are here given the choice of either explicitly -// opt in, in case they wish for the unit to be included in the output AND in the metric name -// as a suffix (see the description of the WithUnit function above), -// or not to opt in, in case they don't want for any of that to happen. -// -// - No support for the following (optional) features: info type, -// stateset type, gaugehistogram type. -// -// - The size of exemplar labels is not checked (i.e. it's possible to create -// exemplars that are larger than allowed by the OpenMetrics specification). -// -// - The value of Counters is not checked. (OpenMetrics doesn't allow counters -// with a `NaN` value.) -func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...EncoderOption) (written int, err error) { - toOM := encoderOption{} - for _, option := range options { - option(&toOM) - } - - name := in.GetName() - if name == "" { - return 0, fmt.Errorf("MetricFamily has no name: %s", in) - } - - // Try the interface upgrade. If it doesn't work, we'll use a - // bufio.Writer from the sync.Pool. - w, ok := out.(enhancedWriter) - if !ok { - b := bufPool.Get().(*bufio.Writer) - b.Reset(out) - w = b - defer func() { - bErr := b.Flush() - if err == nil { - err = bErr - } - bufPool.Put(b) - }() - } - - var ( - n int - metricType = in.GetType() - compliantName = name - ) - if metricType == dto.MetricType_COUNTER && strings.HasSuffix(compliantName, "_total") { - compliantName = name[:len(name)-6] - } - if toOM.withUnit && in.Unit != nil && !strings.HasSuffix(compliantName, "_"+*in.Unit) { - compliantName = compliantName + "_" + *in.Unit - } - - // Comments, first HELP, then TYPE. - if in.Help != nil { - n, err = w.WriteString("# HELP ") - written += n - if err != nil { - return written, err - } - n, err = writeName(w, compliantName) - written += n - if err != nil { - return written, err - } - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - n, err = writeEscapedString(w, *in.Help, true) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('\n') - written++ - if err != nil { - return written, err - } - } - n, err = w.WriteString("# TYPE ") - written += n - if err != nil { - return written, err - } - n, err = writeName(w, compliantName) - written += n - if err != nil { - return written, err - } - switch metricType { - case dto.MetricType_COUNTER: - if strings.HasSuffix(name, "_total") { - n, err = w.WriteString(" counter\n") - } else { - n, err = w.WriteString(" unknown\n") - } - case dto.MetricType_GAUGE: - n, err = w.WriteString(" gauge\n") - case dto.MetricType_SUMMARY: - n, err = w.WriteString(" summary\n") - case dto.MetricType_UNTYPED: - n, err = w.WriteString(" unknown\n") - case dto.MetricType_HISTOGRAM: - n, err = w.WriteString(" histogram\n") - case dto.MetricType_GAUGE_HISTOGRAM: - n, err = w.WriteString(" gaugehistogram\n") - default: - return written, fmt.Errorf("unknown metric type %s", metricType.String()) - } - written += n - if err != nil { - return written, err - } - if toOM.withUnit && in.Unit != nil { - n, err = w.WriteString("# UNIT ") - written += n - if err != nil { - return written, err - } - n, err = writeName(w, compliantName) - written += n - if err != nil { - return written, err - } - - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - n, err = writeEscapedString(w, *in.Unit, true) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('\n') - written++ - if err != nil { - return written, err - } - } - - var createdTsBytesWritten int - - // Finally the samples, one line for each. - if metricType == dto.MetricType_COUNTER && strings.HasSuffix(name, "_total") { - compliantName += "_total" - } - for _, metric := range in.Metric { - switch metricType { - case dto.MetricType_COUNTER: - if metric.Counter == nil { - return written, fmt.Errorf( - "expected counter in metric %s %s", compliantName, metric, - ) - } - n, err = writeOpenMetricsSample( - w, compliantName, "", metric, "", 0, - metric.Counter.GetValue(), 0, false, - metric.Counter.Exemplar, - ) - if toOM.withCreatedLines && metric.Counter.CreatedTimestamp != nil { - createdTsBytesWritten, err = writeOpenMetricsCreated(w, compliantName, "_total", metric, "", 0, metric.Counter.GetCreatedTimestamp()) - n += createdTsBytesWritten - } - case dto.MetricType_GAUGE: - if metric.Gauge == nil { - return written, fmt.Errorf( - "expected gauge in metric %s %s", compliantName, metric, - ) - } - n, err = writeOpenMetricsSample( - w, compliantName, "", metric, "", 0, - metric.Gauge.GetValue(), 0, false, - nil, - ) - case dto.MetricType_UNTYPED: - if metric.Untyped == nil { - return written, fmt.Errorf( - "expected untyped in metric %s %s", compliantName, metric, - ) - } - n, err = writeOpenMetricsSample( - w, compliantName, "", metric, "", 0, - metric.Untyped.GetValue(), 0, false, - nil, - ) - case dto.MetricType_SUMMARY: - if metric.Summary == nil { - return written, fmt.Errorf( - "expected summary in metric %s %s", compliantName, metric, - ) - } - for _, q := range metric.Summary.Quantile { - n, err = writeOpenMetricsSample( - w, compliantName, "", metric, - model.QuantileLabel, q.GetQuantile(), - q.GetValue(), 0, false, - nil, - ) - written += n - if err != nil { - return written, err - } - } - n, err = writeOpenMetricsSample( - w, compliantName, "_sum", metric, "", 0, - metric.Summary.GetSampleSum(), 0, false, - nil, - ) - written += n - if err != nil { - return written, err - } - n, err = writeOpenMetricsSample( - w, compliantName, "_count", metric, "", 0, - 0, metric.Summary.GetSampleCount(), true, - nil, - ) - if toOM.withCreatedLines && metric.Summary.CreatedTimestamp != nil { - createdTsBytesWritten, err = writeOpenMetricsCreated(w, compliantName, "", metric, "", 0, metric.Summary.GetCreatedTimestamp()) - n += createdTsBytesWritten - } - case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: - if metric.Histogram == nil { - return written, fmt.Errorf( - "expected histogram in metric %s %s", compliantName, metric, - ) - } - infSeen := false - for _, b := range metric.Histogram.Bucket { - if b.GetCumulativeCountFloat() > 0 { - return written, fmt.Errorf( - "OpenMetrics v1.0 does not support float histogram %s %s", - compliantName, metric, - ) - } - n, err = writeOpenMetricsSample( - w, compliantName, "_bucket", metric, - model.BucketLabel, b.GetUpperBound(), - 0, b.GetCumulativeCount(), true, - b.Exemplar, - ) - written += n - if err != nil { - return written, err - } - if math.IsInf(b.GetUpperBound(), +1) { - infSeen = true - } - } - if !infSeen { - n, err = writeOpenMetricsSample( - w, compliantName, "_bucket", metric, - model.BucketLabel, math.Inf(+1), - 0, metric.Histogram.GetSampleCount(), true, - nil, - ) - // We do not check for a float sample count here - // because we will check for it below (and error - // out if needed). - written += n - if err != nil { - return written, err - } - } - n, err = writeOpenMetricsSample( - w, compliantName, "_sum", metric, "", 0, - metric.Histogram.GetSampleSum(), 0, false, - nil, - ) - written += n - if err != nil { - return written, err - } - if metric.Histogram.GetSampleCountFloat() > 0 { - return written, fmt.Errorf( - "OpenMetrics v1.0 does not support float histogram %s %s", - compliantName, metric, - ) - } - n, err = writeOpenMetricsSample( - w, compliantName, "_count", metric, "", 0, - 0, metric.Histogram.GetSampleCount(), true, - nil, - ) - if toOM.withCreatedLines && metric.Histogram.CreatedTimestamp != nil { - createdTsBytesWritten, err = writeOpenMetricsCreated(w, compliantName, "", metric, "", 0, metric.Histogram.GetCreatedTimestamp()) - n += createdTsBytesWritten - } - default: - return written, fmt.Errorf( - "unexpected type in metric %s %s", compliantName, metric, - ) - } - written += n - if err != nil { - return written, err - } - } - return written, err -} - -// FinalizeOpenMetrics writes the final `# EOF\n` line required by OpenMetrics. -func FinalizeOpenMetrics(w io.Writer) (written int, err error) { - return w.Write([]byte("# EOF\n")) -} - -// writeOpenMetricsSample writes a single sample in OpenMetrics text format to -// w, given the metric name, the metric proto message itself, optionally an -// additional label name with a float64 value (use empty string as label name if -// not required), the value (optionally as float64 or uint64, determined by -// useIntValue), and optionally an exemplar (use nil if not required). The -// function returns the number of bytes written and any error encountered. -func writeOpenMetricsSample( - w enhancedWriter, - name, suffix string, - metric *dto.Metric, - additionalLabelName string, additionalLabelValue float64, - floatValue float64, intValue uint64, useIntValue bool, - exemplar *dto.Exemplar, -) (int, error) { - written := 0 - n, err := writeOpenMetricsNameAndLabelPairs( - w, name+suffix, metric.Label, additionalLabelName, additionalLabelValue, - ) - written += n - if err != nil { - return written, err - } - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - if useIntValue { - n, err = writeUint(w, intValue) - } else { - n, err = writeOpenMetricsFloat(w, floatValue) - } - written += n - if err != nil { - return written, err - } - if metric.TimestampMs != nil { - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - // TODO(beorn7): Format this directly without converting to a float first. - n, err = writeOpenMetricsFloat(w, float64(*metric.TimestampMs)/1000) - written += n - if err != nil { - return written, err - } - } - if exemplar != nil && len(exemplar.Label) > 0 { - n, err = writeExemplar(w, exemplar) - written += n - if err != nil { - return written, err - } - } - err = w.WriteByte('\n') - written++ - if err != nil { - return written, err - } - return written, nil -} - -// writeOpenMetricsNameAndLabelPairs works like writeOpenMetricsSample but -// formats the float in OpenMetrics style. -func writeOpenMetricsNameAndLabelPairs( - w enhancedWriter, - name string, - in []*dto.LabelPair, - additionalLabelName string, additionalLabelValue float64, -) (int, error) { - var ( - written int - separator byte = '{' - metricInsideBraces = false - ) - - if name != "" { - // If the name does not pass the legacy validity check, we must put the - // metric name inside the braces, quoted. - if !model.LegacyValidation.IsValidMetricName(name) { - metricInsideBraces = true - err := w.WriteByte(separator) - written++ - if err != nil { - return written, err - } - separator = ',' - } - - n, err := writeName(w, name) - written += n - if err != nil { - return written, err - } - } - - if len(in) == 0 && additionalLabelName == "" { - if metricInsideBraces { - err := w.WriteByte('}') - written++ - if err != nil { - return written, err - } - } - return written, nil - } - - for _, lp := range in { - err := w.WriteByte(separator) - written++ - if err != nil { - return written, err - } - n, err := writeName(w, lp.GetName()) - written += n - if err != nil { - return written, err - } - n, err = w.WriteString(`="`) - written += n - if err != nil { - return written, err - } - n, err = writeEscapedString(w, lp.GetValue(), true) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('"') - written++ - if err != nil { - return written, err - } - separator = ',' - } - if additionalLabelName != "" { - err := w.WriteByte(separator) - written++ - if err != nil { - return written, err - } - n, err := w.WriteString(additionalLabelName) - written += n - if err != nil { - return written, err - } - n, err = w.WriteString(`="`) - written += n - if err != nil { - return written, err - } - n, err = writeOpenMetricsFloat(w, additionalLabelValue) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('"') - written++ - if err != nil { - return written, err - } - } - err := w.WriteByte('}') - written++ - if err != nil { - return written, err - } - return written, nil -} - -// writeOpenMetricsCreated writes the created timestamp for a single time series -// following OpenMetrics text format to w, given the metric name, the metric proto -// message itself, optionally a suffix to be removed, e.g. '_total' for counters, -// an additional label name with a float64 value (use empty string as label name if -// not required) and the timestamp that represents the created timestamp. -// The function returns the number of bytes written and any error encountered. -func writeOpenMetricsCreated(w enhancedWriter, - name, suffixToTrim string, metric *dto.Metric, - additionalLabelName string, additionalLabelValue float64, - createdTimestamp *timestamppb.Timestamp, -) (int, error) { - written := 0 - n, err := writeOpenMetricsNameAndLabelPairs( - w, strings.TrimSuffix(name, suffixToTrim)+"_created", metric.Label, additionalLabelName, additionalLabelValue, - ) - written += n - if err != nil { - return written, err - } - - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - - // TODO(beorn7): Format this directly from components of ts to - // avoid overflow/underflow and precision issues of the float - // conversion. - n, err = writeOpenMetricsFloat(w, float64(createdTimestamp.AsTime().UnixNano())/1e9) - written += n - if err != nil { - return written, err - } - - err = w.WriteByte('\n') - written++ - if err != nil { - return written, err - } - return written, nil -} - -// writeExemplar writes the provided exemplar in OpenMetrics format to w. The -// function returns the number of bytes written and any error encountered. -func writeExemplar(w enhancedWriter, e *dto.Exemplar) (int, error) { - written := 0 - n, err := w.WriteString(" # ") - written += n - if err != nil { - return written, err - } - n, err = writeOpenMetricsNameAndLabelPairs(w, "", e.Label, "", 0) - written += n - if err != nil { - return written, err - } - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - n, err = writeOpenMetricsFloat(w, e.GetValue()) - written += n - if err != nil { - return written, err - } - if e.Timestamp != nil { - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - err = e.Timestamp.CheckValid() - if err != nil { - return written, err - } - ts := e.Timestamp.AsTime() - // TODO(beorn7): Format this directly from components of ts to - // avoid overflow/underflow and precision issues of the float - // conversion. - n, err = writeOpenMetricsFloat(w, float64(ts.UnixNano())/1e9) - written += n - if err != nil { - return written, err - } - } - return written, nil -} - -// writeOpenMetricsFloat works like writeFloat but appends ".0" if the resulting -// number would otherwise contain neither a "." nor an "e". -func writeOpenMetricsFloat(w enhancedWriter, f float64) (int, error) { - switch { - case f == 1: - return w.WriteString("1.0") - case f == 0: - return w.WriteString("0.0") - case f == -1: - return w.WriteString("-1.0") - case math.IsNaN(f): - return w.WriteString("NaN") - case math.IsInf(f, +1): - return w.WriteString("+Inf") - case math.IsInf(f, -1): - return w.WriteString("-Inf") - default: - bp := numBufPool.Get().(*[]byte) - *bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64) - if !bytes.ContainsAny(*bp, "e.") { - *bp = append(*bp, '.', '0') - } - written, err := w.Write(*bp) - numBufPool.Put(bp) - return written, err - } -} - -// writeUint is like writeInt just for uint64. -func writeUint(w enhancedWriter, u uint64) (int, error) { - bp := numBufPool.Get().(*[]byte) - *bp = strconv.AppendUint((*bp)[:0], u, 10) - written, err := w.Write(*bp) - numBufPool.Put(bp) - return written, err -} diff --git a/vendor/github.com/prometheus/common/expfmt/text_create.go b/vendor/github.com/prometheus/common/expfmt/text_create.go deleted file mode 100644 index 6b897814564a..000000000000 --- a/vendor/github.com/prometheus/common/expfmt/text_create.go +++ /dev/null @@ -1,532 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expfmt - -import ( - "bufio" - "fmt" - "io" - "math" - "strconv" - "strings" - "sync" - - dto "github.com/prometheus/client_model/go" - - "github.com/prometheus/common/model" -) - -// enhancedWriter has all the enhanced write functions needed here. bufio.Writer -// implements it. -type enhancedWriter interface { - io.Writer - WriteRune(r rune) (n int, err error) - WriteString(s string) (n int, err error) - WriteByte(c byte) error -} - -const ( - initialNumBufSize = 24 -) - -var ( - bufPool = sync.Pool{ - New: func() interface{} { - return bufio.NewWriter(io.Discard) - }, - } - numBufPool = sync.Pool{ - New: func() interface{} { - b := make([]byte, 0, initialNumBufSize) - return &b - }, - } -) - -// MetricFamilyToText converts a MetricFamily proto message into text format and -// writes the resulting lines to 'out'. It returns the number of bytes written -// and any error encountered. The output will have the same order as the input, -// no further sorting is performed. Furthermore, this function assumes the input -// is already sanitized and does not perform any sanity checks. If the input -// contains duplicate metrics or invalid metric or label names, the conversion -// will result in invalid text format output. -// -// If metric names conform to the legacy validation pattern, they will be placed -// outside the brackets in the traditional way, like `foo{}`. If the metric name -// fails the legacy validation check, it will be placed quoted inside the -// brackets: `{"foo"}`. As stated above, the input is assumed to be santized and -// no error will be thrown in this case. -// -// Similar to metric names, if label names conform to the legacy validation -// pattern, they will be unquoted as normal, like `foo{bar="baz"}`. If the label -// name fails the legacy validation check, it will be quoted: -// `foo{"bar"="baz"}`. As stated above, the input is assumed to be santized and -// no error will be thrown in this case. -// -// This method fulfills the type 'prometheus.encoder'. -func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) { - // Fail-fast checks. - if len(in.Metric) == 0 { - return 0, fmt.Errorf("MetricFamily has no metrics: %s", in) - } - name := in.GetName() - if name == "" { - return 0, fmt.Errorf("MetricFamily has no name: %s", in) - } - - // Try the interface upgrade. If it doesn't work, we'll use a - // bufio.Writer from the sync.Pool. - w, ok := out.(enhancedWriter) - if !ok { - b := bufPool.Get().(*bufio.Writer) - b.Reset(out) - w = b - defer func() { - bErr := b.Flush() - if err == nil { - err = bErr - } - bufPool.Put(b) - }() - } - - var n int - - // Comments, first HELP, then TYPE. - if in.Help != nil { - n, err = w.WriteString("# HELP ") - written += n - if err != nil { - return written, err - } - n, err = writeName(w, name) - written += n - if err != nil { - return written, err - } - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - n, err = writeEscapedString(w, *in.Help, false) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('\n') - written++ - if err != nil { - return written, err - } - } - n, err = w.WriteString("# TYPE ") - written += n - if err != nil { - return written, err - } - n, err = writeName(w, name) - written += n - if err != nil { - return written, err - } - metricType := in.GetType() - switch metricType { - case dto.MetricType_COUNTER: - n, err = w.WriteString(" counter\n") - case dto.MetricType_GAUGE: - n, err = w.WriteString(" gauge\n") - case dto.MetricType_SUMMARY: - n, err = w.WriteString(" summary\n") - case dto.MetricType_UNTYPED: - n, err = w.WriteString(" untyped\n") - case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: - // The classic Prometheus text format has no notion of a gauge - // histogram. We render a gauge histogram in the same way as a - // regular histogram. - n, err = w.WriteString(" histogram\n") - default: - return written, fmt.Errorf("unknown metric type %s", metricType.String()) - } - written += n - if err != nil { - return written, err - } - - // Finally the samples, one line for each. - for _, metric := range in.Metric { - switch metricType { - case dto.MetricType_COUNTER: - if metric.Counter == nil { - return written, fmt.Errorf( - "expected counter in metric %s %s", name, metric, - ) - } - n, err = writeSample( - w, name, "", metric, "", 0, - metric.Counter.GetValue(), - ) - case dto.MetricType_GAUGE: - if metric.Gauge == nil { - return written, fmt.Errorf( - "expected gauge in metric %s %s", name, metric, - ) - } - n, err = writeSample( - w, name, "", metric, "", 0, - metric.Gauge.GetValue(), - ) - case dto.MetricType_UNTYPED: - if metric.Untyped == nil { - return written, fmt.Errorf( - "expected untyped in metric %s %s", name, metric, - ) - } - n, err = writeSample( - w, name, "", metric, "", 0, - metric.Untyped.GetValue(), - ) - case dto.MetricType_SUMMARY: - if metric.Summary == nil { - return written, fmt.Errorf( - "expected summary in metric %s %s", name, metric, - ) - } - for _, q := range metric.Summary.Quantile { - n, err = writeSample( - w, name, "", metric, - model.QuantileLabel, q.GetQuantile(), - q.GetValue(), - ) - written += n - if err != nil { - return written, err - } - } - n, err = writeSample( - w, name, "_sum", metric, "", 0, - metric.Summary.GetSampleSum(), - ) - written += n - if err != nil { - return written, err - } - n, err = writeSample( - w, name, "_count", metric, "", 0, - float64(metric.Summary.GetSampleCount()), - ) - case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: - if metric.Histogram == nil { - return written, fmt.Errorf( - "expected histogram in metric %s %s", name, metric, - ) - } - infSeen := false - for _, b := range metric.Histogram.Bucket { - v := b.GetCumulativeCountFloat() - if v == 0 { - v = float64(b.GetCumulativeCount()) - } - n, err = writeSample( - w, name, "_bucket", metric, - model.BucketLabel, b.GetUpperBound(), - v, - ) - written += n - if err != nil { - return written, err - } - if math.IsInf(b.GetUpperBound(), +1) { - infSeen = true - } - } - if !infSeen { - v := metric.Histogram.GetSampleCountFloat() - if v == 0 { - v = float64(metric.Histogram.GetSampleCount()) - } - n, err = writeSample( - w, name, "_bucket", metric, - model.BucketLabel, math.Inf(+1), - v, - ) - written += n - if err != nil { - return written, err - } - } - n, err = writeSample( - w, name, "_sum", metric, "", 0, - metric.Histogram.GetSampleSum(), - ) - written += n - if err != nil { - return written, err - } - v := metric.Histogram.GetSampleCountFloat() - if v == 0 { - v = float64(metric.Histogram.GetSampleCount()) - } - n, err = writeSample(w, name, "_count", metric, "", 0, v) - default: - return written, fmt.Errorf( - "unexpected type in metric %s %s", name, metric, - ) - } - written += n - if err != nil { - return written, err - } - } - return written, err -} - -// writeSample writes a single sample in text format to w, given the metric -// name, the metric proto message itself, optionally an additional label name -// with a float64 value (use empty string as label name if not required), and -// the value. The function returns the number of bytes written and any error -// encountered. -func writeSample( - w enhancedWriter, - name, suffix string, - metric *dto.Metric, - additionalLabelName string, additionalLabelValue float64, - value float64, -) (int, error) { - written := 0 - n, err := writeNameAndLabelPairs( - w, name+suffix, metric.Label, additionalLabelName, additionalLabelValue, - ) - written += n - if err != nil { - return written, err - } - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - n, err = writeFloat(w, value) - written += n - if err != nil { - return written, err - } - if metric.TimestampMs != nil { - err = w.WriteByte(' ') - written++ - if err != nil { - return written, err - } - n, err = writeInt(w, *metric.TimestampMs) - written += n - if err != nil { - return written, err - } - } - err = w.WriteByte('\n') - written++ - if err != nil { - return written, err - } - return written, nil -} - -// writeNameAndLabelPairs converts a slice of LabelPair proto messages plus the -// explicitly given metric name and additional label pair into text formatted as -// required by the text format and writes it to 'w'. An empty slice in -// combination with an empty string 'additionalLabelName' results in nothing -// being written. Otherwise, the label pairs are written, escaped as required by -// the text format, and enclosed in '{...}'. The function returns the number of -// bytes written and any error encountered. If the metric name is not -// legacy-valid, it will be put inside the brackets as well. Legacy-invalid -// label names will also be quoted. -func writeNameAndLabelPairs( - w enhancedWriter, - name string, - in []*dto.LabelPair, - additionalLabelName string, additionalLabelValue float64, -) (int, error) { - var ( - written int - separator byte = '{' - metricInsideBraces = false - ) - - if name != "" { - // If the name does not pass the legacy validity check, we must put the - // metric name inside the braces. - if !model.LegacyValidation.IsValidMetricName(name) { - metricInsideBraces = true - err := w.WriteByte(separator) - written++ - if err != nil { - return written, err - } - separator = ',' - } - n, err := writeName(w, name) - written += n - if err != nil { - return written, err - } - } - - if len(in) == 0 && additionalLabelName == "" { - if metricInsideBraces { - err := w.WriteByte('}') - written++ - if err != nil { - return written, err - } - } - return written, nil - } - - for _, lp := range in { - err := w.WriteByte(separator) - written++ - if err != nil { - return written, err - } - n, err := writeName(w, lp.GetName()) - written += n - if err != nil { - return written, err - } - n, err = w.WriteString(`="`) - written += n - if err != nil { - return written, err - } - n, err = writeEscapedString(w, lp.GetValue(), true) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('"') - written++ - if err != nil { - return written, err - } - separator = ',' - } - if additionalLabelName != "" { - err := w.WriteByte(separator) - written++ - if err != nil { - return written, err - } - n, err := w.WriteString(additionalLabelName) - written += n - if err != nil { - return written, err - } - n, err = w.WriteString(`="`) - written += n - if err != nil { - return written, err - } - n, err = writeFloat(w, additionalLabelValue) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('"') - written++ - if err != nil { - return written, err - } - } - err := w.WriteByte('}') - written++ - if err != nil { - return written, err - } - return written, nil -} - -// writeEscapedString replaces '\' by '\\', new line character by '\n', and - if -// includeDoubleQuote is true - '"' by '\"'. -var ( - escaper = strings.NewReplacer("\\", `\\`, "\n", `\n`) - quotedEscaper = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`) -) - -func writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (int, error) { - if includeDoubleQuote { - return quotedEscaper.WriteString(w, v) - } - return escaper.WriteString(w, v) -} - -// writeFloat is equivalent to fmt.Fprint with a float64 argument but hardcodes -// a few common cases for increased efficiency. For non-hardcoded cases, it uses -// strconv.AppendFloat to avoid allocations, similar to writeInt. -func writeFloat(w enhancedWriter, f float64) (int, error) { - switch { - case f == 1: - return 1, w.WriteByte('1') - case f == 0: - return 1, w.WriteByte('0') - case f == -1: - return w.WriteString("-1") - case math.IsNaN(f): - return w.WriteString("NaN") - case math.IsInf(f, +1): - return w.WriteString("+Inf") - case math.IsInf(f, -1): - return w.WriteString("-Inf") - default: - bp := numBufPool.Get().(*[]byte) - *bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64) - written, err := w.Write(*bp) - numBufPool.Put(bp) - return written, err - } -} - -// writeInt is equivalent to fmt.Fprint with an int64 argument but uses -// strconv.AppendInt with a byte slice taken from a sync.Pool to avoid -// allocations. -func writeInt(w enhancedWriter, i int64) (int, error) { - bp := numBufPool.Get().(*[]byte) - *bp = strconv.AppendInt((*bp)[:0], i, 10) - written, err := w.Write(*bp) - numBufPool.Put(bp) - return written, err -} - -// writeName writes a string as-is if it complies with the legacy naming -// scheme, or escapes it in double quotes if not. -func writeName(w enhancedWriter, name string) (int, error) { - if model.LegacyValidation.IsValidMetricName(name) { - return w.WriteString(name) - } - var written int - var err error - err = w.WriteByte('"') - written++ - if err != nil { - return written, err - } - var n int - n, err = writeEscapedString(w, name, true) - written += n - if err != nil { - return written, err - } - err = w.WriteByte('"') - written++ - return written, err -} diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go deleted file mode 100644 index 00c8841a1089..000000000000 --- a/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ /dev/null @@ -1,997 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expfmt - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "math" - "strconv" - "strings" - "unicode/utf8" - - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/proto" - - "github.com/prometheus/common/model" -) - -// A stateFn is a function that represents a state in a state machine. By -// executing it, the state is progressed to the next state. The stateFn returns -// another stateFn, which represents the new state. The end state is represented -// by nil. -type stateFn func() stateFn - -// ParseError signals errors while parsing the simple and flat text-based -// exchange format. -type ParseError struct { - Line int - Msg string -} - -// Error implements the error interface. -func (e ParseError) Error() string { - return fmt.Sprintf("text format parsing error in line %d: %s", e.Line, e.Msg) -} - -// TextParser is used to parse the simple and flat text-based exchange format. -// -// TextParser instances must be created with NewTextParser, the zero value of -// TextParser is invalid. -type TextParser struct { - metricFamiliesByName map[string]*dto.MetricFamily - buf *bufio.Reader // Where the parsed input is read through. - err error // Most recent error. - lineCount int // Tracks the line count for error messages. - currentByte byte // The most recent byte read. - currentToken bytes.Buffer // Re-used each time a token has to be gathered from multiple bytes. - currentMF *dto.MetricFamily - currentMetric *dto.Metric - currentLabelPair *dto.LabelPair - currentLabelPairs []*dto.LabelPair // Temporarily stores label pairs while parsing a metric line. - - // The remaining member variables are only used for summaries/histograms. - currentLabels map[string]string // All labels including '__name__' but excluding 'quantile'/'le' - // Summary specific. - summaries map[uint64]*dto.Metric // Key is created with LabelsToSignature. - currentQuantile float64 - // Histogram specific. - histograms map[uint64]*dto.Metric // Key is created with LabelsToSignature. - currentBucket float64 - // These tell us if the currently processed line ends on '_count' or - // '_sum' respectively and belong to a summary/histogram, representing the sample - // count and sum of that summary/histogram. - currentIsSummaryCount, currentIsSummarySum bool - currentIsHistogramCount, currentIsHistogramSum bool - // These indicate if the metric name from the current line being parsed is inside - // braces and if that metric name was found respectively. - currentMetricIsInsideBraces, currentMetricInsideBracesIsPresent bool - // scheme sets the desired ValidationScheme for names. Defaults to the invalid - // UnsetValidation. - scheme model.ValidationScheme -} - -// NewTextParser returns a new TextParser with the provided nameValidationScheme. -func NewTextParser(nameValidationScheme model.ValidationScheme) TextParser { - return TextParser{scheme: nameValidationScheme} -} - -// TextToMetricFamilies reads 'in' as the simple and flat text-based exchange -// format and creates MetricFamily proto messages. It returns the MetricFamily -// proto messages in a map where the metric names are the keys, along with any -// error encountered. -// -// If the input contains duplicate metrics (i.e. lines with the same metric name -// and exactly the same label set), the resulting MetricFamily will contain -// duplicate Metric proto messages. Similar is true for duplicate label -// names. Checks for duplicates have to be performed separately, if required. -// Also note that neither the metrics within each MetricFamily are sorted nor -// the label pairs within each Metric. Sorting is not required for the most -// frequent use of this method, which is sample ingestion in the Prometheus -// server. However, for presentation purposes, you might want to sort the -// metrics, and in some cases, you must sort the labels, e.g. for consumption by -// the metric family injection hook of the Prometheus registry. -// -// Summaries and histograms are rather special beasts. You would probably not -// use them in the simple text format anyway. This method can deal with -// summaries and histograms if they are presented in exactly the way the -// text.Create function creates them. -// -// This method must not be called concurrently. If you want to parse different -// input concurrently, instantiate a separate Parser for each goroutine. -func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) { - p.reset(in) - for nextState := p.startOfLine; nextState != nil; nextState = nextState() { - // Magic happens here... - } - // Get rid of empty metric families. - for k, mf := range p.metricFamiliesByName { - if len(mf.GetMetric()) == 0 { - delete(p.metricFamiliesByName, k) - } - } - // If p.err is io.EOF now, we have run into a premature end of the input - // stream. Turn this error into something nicer and more - // meaningful. (io.EOF is often used as a signal for the legitimate end - // of an input stream.) - if p.err != nil && errors.Is(p.err, io.EOF) { - p.parseError("unexpected end of input stream") - } - for _, histogramMetric := range p.histograms { - normalizeHistogram(histogramMetric.GetHistogram()) - } - return p.metricFamiliesByName, p.err -} - -// normalizeHistogram makes sure that all the buckets and the count in each -// histogram is either completely float or completely integer. -func normalizeHistogram(histogram *dto.Histogram) { - if histogram == nil { - return - } - anyFloats := false - if histogram.GetSampleCountFloat() != 0 { - anyFloats = true - } else { - for _, b := range histogram.GetBucket() { - if b.GetCumulativeCountFloat() != 0 { - anyFloats = true - break - } - } - } - if !anyFloats { - return - } - if histogram.GetSampleCountFloat() == 0 { - histogram.SampleCountFloat = proto.Float64(float64(histogram.GetSampleCount())) - histogram.SampleCount = nil - } - for _, b := range histogram.GetBucket() { - if b.GetCumulativeCountFloat() == 0 { - b.CumulativeCountFloat = proto.Float64(float64(b.GetCumulativeCount())) - b.CumulativeCount = nil - } - } -} - -func (p *TextParser) reset(in io.Reader) { - p.metricFamiliesByName = map[string]*dto.MetricFamily{} - p.currentLabelPairs = nil - if p.buf == nil { - p.buf = bufio.NewReader(in) - } else { - p.buf.Reset(in) - } - p.err = nil - p.lineCount = 0 - if p.summaries == nil || len(p.summaries) > 0 { - p.summaries = map[uint64]*dto.Metric{} - } - if p.histograms == nil || len(p.histograms) > 0 { - p.histograms = map[uint64]*dto.Metric{} - } - p.currentQuantile = math.NaN() - p.currentBucket = math.NaN() - p.currentMF = nil -} - -// startOfLine represents the state where the next byte read from p.buf is the -// start of a line (or whitespace leading up to it). -func (p *TextParser) startOfLine() stateFn { - p.lineCount++ - p.currentMetricIsInsideBraces = false - p.currentMetricInsideBracesIsPresent = false - if p.skipBlankTab(); p.err != nil { - // This is the only place that we expect to see io.EOF, - // which is not an error but the signal that we are done. - // Any other error that happens to align with the start of - // a line is still an error. - if errors.Is(p.err, io.EOF) { - p.err = nil - } - return nil - } - switch p.currentByte { - case '#': - return p.startComment - case '\n': - return p.startOfLine // Empty line, start the next one. - case '{': - p.currentMetricIsInsideBraces = true - return p.readingLabels - } - return p.readingMetricName -} - -// startComment represents the state where the next byte read from p.buf is the -// start of a comment (or whitespace leading up to it). -func (p *TextParser) startComment() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '\n' { - return p.startOfLine - } - if p.readTokenUntilWhitespace(); p.err != nil { - return nil // Unexpected end of input. - } - // If we have hit the end of line already, there is nothing left - // to do. This is not considered a syntax error. - if p.currentByte == '\n' { - return p.startOfLine - } - keyword := p.currentToken.String() - if keyword != "HELP" && keyword != "TYPE" { - // Generic comment, ignore by fast forwarding to end of line. - for p.currentByte != '\n' { - if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil { - return nil // Unexpected end of input. - } - } - return p.startOfLine - } - // There is something. Next has to be a metric name. - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.readTokenAsMetricName(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '\n' { - // At the end of the line already. - // Again, this is not considered a syntax error. - return p.startOfLine - } - if !isBlankOrTab(p.currentByte) { - p.parseError("invalid metric name in comment") - return nil - } - p.setOrCreateCurrentMF() - if p.err != nil { - return nil - } - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '\n' { - // At the end of the line already. - // Again, this is not considered a syntax error. - return p.startOfLine - } - switch keyword { - case "HELP": - return p.readingHelp - case "TYPE": - return p.readingType - } - panic(fmt.Sprintf("code error: unexpected keyword %q", keyword)) -} - -// readingMetricName represents the state where the last byte read (now in -// p.currentByte) is the first byte of a metric name. -func (p *TextParser) readingMetricName() stateFn { - if p.readTokenAsMetricName(); p.err != nil { - return nil - } - if p.currentToken.Len() == 0 { - p.parseError("invalid metric name") - return nil - } - p.setOrCreateCurrentMF() - if p.err != nil { - return nil - } - // Now is the time to fix the type if it hasn't happened yet. - if p.currentMF.Type == nil { - p.currentMF.Type = dto.MetricType_UNTYPED.Enum() - } - p.currentMetric = &dto.Metric{} - // Do not append the newly created currentMetric to - // currentMF.Metric right now. First wait if this is a summary, - // and the metric exists already, which we can only know after - // having read all the labels. - if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - return p.readingLabels -} - -// readingLabels represents the state where the last byte read (now in -// p.currentByte) is either the first byte of the label set (i.e. a '{'), or the -// first byte of the value (otherwise). -func (p *TextParser) readingLabels() stateFn { - // Summaries/histograms are special. We have to reset the - // currentLabels map, currentQuantile and currentBucket before starting to - // read labels. - if p.currentMF.GetType() == dto.MetricType_SUMMARY || - p.currentMF.GetType() == dto.MetricType_HISTOGRAM || - p.currentMF.GetType() == dto.MetricType_GAUGE_HISTOGRAM { - p.currentLabels = map[string]string{} - p.currentLabels[string(model.MetricNameLabel)] = p.currentMF.GetName() - p.currentQuantile = math.NaN() - p.currentBucket = math.NaN() - } - if p.currentByte != '{' { - return p.readingValue - } - return p.startLabelName -} - -// startLabelName represents the state where the next byte read from p.buf is -// the start of a label name (or whitespace leading up to it). -func (p *TextParser) startLabelName() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte == '}' { - p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) - p.currentLabelPairs = nil - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - return p.readingValue - } - if p.readTokenAsLabelName(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentToken.Len() == 0 { - p.parseError(fmt.Sprintf("invalid label name for metric %q", p.currentMF.GetName())) - return nil - } - if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte != '=' { - if p.currentMetricIsInsideBraces { - if p.currentMetricInsideBracesIsPresent { - p.parseError(fmt.Sprintf("multiple metric names for metric %q", p.currentMF.GetName())) - return nil - } - switch p.currentByte { - case ',': - p.setOrCreateCurrentMF() - if p.err != nil { - return nil - } - if p.currentMF.Type == nil { - p.currentMF.Type = dto.MetricType_UNTYPED.Enum() - } - p.currentMetric = &dto.Metric{} - p.currentMetricInsideBracesIsPresent = true - return p.startLabelName - case '}': - p.setOrCreateCurrentMF() - if p.err != nil { - p.currentLabelPairs = nil - return nil - } - if p.currentMF.Type == nil { - p.currentMF.Type = dto.MetricType_UNTYPED.Enum() - } - p.currentMetric = &dto.Metric{} - p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) - p.currentLabelPairs = nil - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - return p.readingValue - default: - p.parseError(fmt.Sprintf("unexpected end of metric name %q", p.currentByte)) - return nil - } - } - p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte)) - p.currentLabelPairs = nil - return nil - } - p.currentLabelPair = &dto.LabelPair{Name: proto.String(p.currentToken.String())} - if p.currentLabelPair.GetName() == string(model.MetricNameLabel) { - p.parseError(fmt.Sprintf("label name %q is reserved", model.MetricNameLabel)) - p.currentLabelPairs = nil - return nil - } - if !p.scheme.IsValidLabelName(p.currentLabelPair.GetName()) { - p.parseError(fmt.Sprintf("invalid label name %q", p.currentLabelPair.GetName())) - p.currentLabelPairs = nil - return nil - } - // Special summary/histogram treatment. Don't add 'quantile' and 'le' - // labels to 'real' labels. - if (p.currentMF.GetType() != dto.MetricType_SUMMARY || p.currentLabelPair.GetName() != model.QuantileLabel) && - ((p.currentMF.GetType() != dto.MetricType_HISTOGRAM && - p.currentMF.GetType() != dto.MetricType_GAUGE_HISTOGRAM) || - p.currentLabelPair.GetName() != model.BucketLabel) { - p.currentLabelPairs = append(p.currentLabelPairs, p.currentLabelPair) - } - // Check for duplicate label names. - labels := make(map[string]struct{}) - for _, l := range p.currentLabelPairs { - lName := l.GetName() - if _, exists := labels[lName]; exists { - p.parseError(fmt.Sprintf("duplicate label names for metric %q", p.currentMF.GetName())) - p.currentLabelPairs = nil - return nil - } - labels[lName] = struct{}{} - } - return p.startLabelValue -} - -// startLabelValue represents the state where the next byte read from p.buf is -// the start of a (quoted) label value (or whitespace leading up to it). -func (p *TextParser) startLabelValue() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte != '"' { - p.parseError(fmt.Sprintf("expected '\"' at start of label value, found %q", p.currentByte)) - return nil - } - if p.readTokenAsLabelValue(); p.err != nil { - return nil - } - if !model.LabelValue(p.currentToken.String()).IsValid() { - p.parseError(fmt.Sprintf("invalid label value %q", p.currentToken.String())) - return nil - } - p.currentLabelPair.Value = proto.String(p.currentToken.String()) - // Special treatment of summaries: - // - Quantile labels are special, will result in dto.Quantile later. - // - Other labels have to be added to currentLabels for signature calculation. - if p.currentMF.GetType() == dto.MetricType_SUMMARY { - if p.currentLabelPair.GetName() == model.QuantileLabel { - if p.currentQuantile, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected float as value for 'quantile' label, got %q", p.currentLabelPair.GetValue())) - p.currentLabelPairs = nil - return nil - } - } else { - p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue() - } - } - // Similar special treatment of histograms. - if p.currentMF.GetType() == dto.MetricType_HISTOGRAM || p.currentMF.GetType() == dto.MetricType_GAUGE_HISTOGRAM { - if p.currentLabelPair.GetName() == model.BucketLabel { - if p.currentBucket, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected float as value for 'le' label, got %q", p.currentLabelPair.GetValue())) - return nil - } - } else { - p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue() - } - } - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - switch p.currentByte { - case ',': - return p.startLabelName - - case '}': - if p.currentMF == nil { - p.parseError("invalid metric name") - return nil - } - p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) - p.currentLabelPairs = nil - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - return p.readingValue - default: - p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.GetValue())) - p.currentLabelPairs = nil - return nil - } -} - -// readingValue represents the state where the last byte read (now in -// p.currentByte) is the first byte of the sample value (i.e. a float). -func (p *TextParser) readingValue() stateFn { - // When we are here, we have read all the labels, so for the - // special case of a summary/histogram, we can finally find out - // if the metric already exists. - switch p.currentMF.GetType() { - case dto.MetricType_SUMMARY: - signature := model.LabelsToSignature(p.currentLabels) - if summary := p.summaries[signature]; summary != nil { - p.currentMetric = summary - } else { - p.summaries[signature] = p.currentMetric - p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) - } - case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: - signature := model.LabelsToSignature(p.currentLabels) - if histogram := p.histograms[signature]; histogram != nil { - p.currentMetric = histogram - } else { - p.histograms[signature] = p.currentMetric - p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) - } - default: - p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric) - } - if p.readTokenUntilWhitespace(); p.err != nil { - return nil // Unexpected end of input. - } - value, err := parseFloat(p.currentToken.String()) - if err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected float as value, got %q", p.currentToken.String())) - return nil - } - switch p.currentMF.GetType() { - case dto.MetricType_COUNTER: - p.currentMetric.Counter = &dto.Counter{Value: proto.Float64(value)} - case dto.MetricType_GAUGE: - p.currentMetric.Gauge = &dto.Gauge{Value: proto.Float64(value)} - case dto.MetricType_UNTYPED: - p.currentMetric.Untyped = &dto.Untyped{Value: proto.Float64(value)} - case dto.MetricType_SUMMARY: - // *sigh* - if p.currentMetric.Summary == nil { - p.currentMetric.Summary = &dto.Summary{} - } - switch { - case p.currentIsSummaryCount: - p.currentMetric.Summary.SampleCount = proto.Uint64(uint64(value)) - case p.currentIsSummarySum: - p.currentMetric.Summary.SampleSum = proto.Float64(value) - case !math.IsNaN(p.currentQuantile): - p.currentMetric.Summary.Quantile = append( - p.currentMetric.Summary.Quantile, - &dto.Quantile{ - Quantile: proto.Float64(p.currentQuantile), - Value: proto.Float64(value), - }, - ) - } - case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: - // *sigh* - if p.currentMetric.Histogram == nil { - p.currentMetric.Histogram = &dto.Histogram{} - } - switch { - case p.currentIsHistogramCount: - if uintValue := uint64(value); value == float64(uintValue) { - p.currentMetric.Histogram.SampleCount = proto.Uint64(uintValue) - } else { - if value < 0 { - p.parseError(fmt.Sprintf("negative count for histogram %q", p.currentMF.GetName())) - return nil - } - p.currentMetric.Histogram.SampleCountFloat = proto.Float64(value) - } - case p.currentIsHistogramSum: - p.currentMetric.Histogram.SampleSum = proto.Float64(value) - case !math.IsNaN(p.currentBucket): - b := &dto.Bucket{ - UpperBound: proto.Float64(p.currentBucket), - } - if uintValue := uint64(value); value == float64(uintValue) { - b.CumulativeCount = proto.Uint64(uintValue) - } else { - if value < 0 { - p.parseError(fmt.Sprintf("negative bucket population for histogram %q", p.currentMF.GetName())) - return nil - } - b.CumulativeCountFloat = proto.Float64(value) - } - p.currentMetric.Histogram.Bucket = append(p.currentMetric.Histogram.Bucket, b) - } - default: - p.err = fmt.Errorf("unexpected type for metric name %q", p.currentMF.GetName()) - } - if p.currentByte == '\n' { - return p.startOfLine - } - return p.startTimestamp -} - -// startTimestamp represents the state where the next byte read from p.buf is -// the start of the timestamp (or whitespace leading up to it). -func (p *TextParser) startTimestamp() stateFn { - if p.skipBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.readTokenUntilWhitespace(); p.err != nil { - return nil // Unexpected end of input. - } - timestamp, err := strconv.ParseInt(p.currentToken.String(), 10, 64) - if err != nil { - // Create a more helpful error message. - p.parseError(fmt.Sprintf("expected integer as timestamp, got %q", p.currentToken.String())) - return nil - } - p.currentMetric.TimestampMs = proto.Int64(timestamp) - if p.readTokenUntilNewline(false); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentToken.Len() > 0 { - p.parseError(fmt.Sprintf("spurious string after timestamp: %q", p.currentToken.String())) - return nil - } - return p.startOfLine -} - -// readingHelp represents the state where the last byte read (now in -// p.currentByte) is the first byte of the docstring after 'HELP'. -func (p *TextParser) readingHelp() stateFn { - if p.currentMF.Help != nil { - p.parseError(fmt.Sprintf("second HELP line for metric name %q", p.currentMF.GetName())) - return nil - } - // Rest of line is the docstring. - if p.readTokenUntilNewline(true); p.err != nil { - return nil // Unexpected end of input. - } - p.currentMF.Help = proto.String(p.currentToken.String()) - return p.startOfLine -} - -// readingType represents the state where the last byte read (now in -// p.currentByte) is the first byte of the type hint after 'HELP'. -func (p *TextParser) readingType() stateFn { - if p.currentMF.Type != nil { - p.parseError(fmt.Sprintf("second TYPE line for metric name %q, or TYPE reported after samples", p.currentMF.GetName())) - return nil - } - // Rest of line is the type. - if p.readTokenUntilNewline(false); p.err != nil { - return nil // Unexpected end of input. - } - typ := strings.ToUpper(p.currentToken.String()) // Tolerate any combination of upper and lower case. - metricType, ok := dto.MetricType_value[typ] // Tolerate "gauge_histogram" (not originally part of the text format). - if !ok { - // We also want to tolerate "gaugehistogram" to mark a gauge - // histogram, because that string is used in OpenMetrics. Note, - // however, that gauge histograms do not officially exist in the - // classic text format. - if typ != "GAUGEHISTOGRAM" { - p.parseError(fmt.Sprintf("unknown metric type %q", p.currentToken.String())) - return nil - } - metricType = int32(dto.MetricType_GAUGE_HISTOGRAM) - } - p.currentMF.Type = dto.MetricType(metricType).Enum() - return p.startOfLine -} - -// parseError sets p.err to a ParseError at the current line with the given -// message. -func (p *TextParser) parseError(msg string) { - p.err = ParseError{ - Line: p.lineCount, - Msg: msg, - } -} - -// skipBlankTab reads (and discards) bytes from p.buf until it encounters a byte -// that is neither ' ' nor '\t'. That byte is left in p.currentByte. -func (p *TextParser) skipBlankTab() { - for { - if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil || !isBlankOrTab(p.currentByte) { - return - } - } -} - -// skipBlankTabIfCurrentBlankTab works exactly as skipBlankTab but doesn't do -// anything if p.currentByte is neither ' ' nor '\t'. -func (p *TextParser) skipBlankTabIfCurrentBlankTab() { - if isBlankOrTab(p.currentByte) { - p.skipBlankTab() - } -} - -// readTokenUntilWhitespace copies bytes from p.buf into p.currentToken. The -// first byte considered is the byte already read (now in p.currentByte). The -// first whitespace byte encountered is still copied into p.currentByte, but not -// into p.currentToken. -func (p *TextParser) readTokenUntilWhitespace() { - p.currentToken.Reset() - for p.err == nil && !isBlankOrTab(p.currentByte) && p.currentByte != '\n' { - p.currentToken.WriteByte(p.currentByte) - p.currentByte, p.err = p.buf.ReadByte() - } -} - -// readTokenUntilNewline copies bytes from p.buf into p.currentToken. The first -// byte considered is the byte already read (now in p.currentByte). The first -// newline byte encountered is still copied into p.currentByte, but not into -// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are -// recognized: '\\' translates into '\', and '\n' into a line-feed character. -// All other escape sequences are invalid and cause an error. -func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) { - p.currentToken.Reset() - escaped := false - for p.err == nil { - if recognizeEscapeSequence && escaped { - switch p.currentByte { - case '\\': - p.currentToken.WriteByte(p.currentByte) - case 'n': - p.currentToken.WriteByte('\n') - case '"': - p.currentToken.WriteByte('"') - default: - p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) - return - } - escaped = false - } else { - switch p.currentByte { - case '\n': - return - case '\\': - escaped = true - default: - p.currentToken.WriteByte(p.currentByte) - } - } - p.currentByte, p.err = p.buf.ReadByte() - } -} - -// readTokenAsMetricName copies a metric name from p.buf into p.currentToken. -// The first byte considered is the byte already read (now in p.currentByte). -// The first byte not part of a metric name is still copied into p.currentByte, -// but not into p.currentToken. -func (p *TextParser) readTokenAsMetricName() { - p.currentToken.Reset() - // A UTF-8 metric name must be quoted and may have escaped characters. - quoted := false - escaped := false - if !isValidMetricNameStart(p.currentByte) { - return - } - for p.err == nil { - if escaped { - switch p.currentByte { - case '\\': - p.currentToken.WriteByte(p.currentByte) - case 'n': - p.currentToken.WriteByte('\n') - case '"': - p.currentToken.WriteByte('"') - default: - p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) - return - } - escaped = false - } else { - switch p.currentByte { - case '"': - quoted = !quoted - if !quoted { - p.currentByte, p.err = p.buf.ReadByte() - return - } - case '\n': - p.parseError(fmt.Sprintf("metric name %q contains unescaped new-line", p.currentToken.String())) - return - case '\\': - escaped = true - default: - p.currentToken.WriteByte(p.currentByte) - } - } - p.currentByte, p.err = p.buf.ReadByte() - if !isValidMetricNameContinuation(p.currentByte, quoted) || (!quoted && p.currentByte == ' ') { - return - } - } -} - -// readTokenAsLabelName copies a label name from p.buf into p.currentToken. -// The first byte considered is the byte already read (now in p.currentByte). -// The first byte not part of a label name is still copied into p.currentByte, -// but not into p.currentToken. -func (p *TextParser) readTokenAsLabelName() { - p.currentToken.Reset() - // A UTF-8 label name must be quoted and may have escaped characters. - quoted := false - escaped := false - if !isValidLabelNameStart(p.currentByte) { - return - } - for p.err == nil { - if escaped { - switch p.currentByte { - case '\\': - p.currentToken.WriteByte(p.currentByte) - case 'n': - p.currentToken.WriteByte('\n') - case '"': - p.currentToken.WriteByte('"') - default: - p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) - return - } - escaped = false - } else { - switch p.currentByte { - case '"': - quoted = !quoted - if !quoted { - p.currentByte, p.err = p.buf.ReadByte() - return - } - case '\n': - p.parseError(fmt.Sprintf("label name %q contains unescaped new-line", p.currentToken.String())) - return - case '\\': - escaped = true - default: - p.currentToken.WriteByte(p.currentByte) - } - } - p.currentByte, p.err = p.buf.ReadByte() - if !isValidLabelNameContinuation(p.currentByte, quoted) || (!quoted && p.currentByte == '=') { - return - } - } -} - -// readTokenAsLabelValue copies a label value from p.buf into p.currentToken. -// In contrast to the other 'readTokenAs...' functions, which start with the -// last read byte in p.currentByte, this method ignores p.currentByte and starts -// with reading a new byte from p.buf. The first byte not part of a label value -// is still copied into p.currentByte, but not into p.currentToken. -func (p *TextParser) readTokenAsLabelValue() { - p.currentToken.Reset() - escaped := false - for { - if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil { - return - } - if escaped { - switch p.currentByte { - case '"', '\\': - p.currentToken.WriteByte(p.currentByte) - case 'n': - p.currentToken.WriteByte('\n') - default: - p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) - p.currentLabelPairs = nil - return - } - escaped = false - continue - } - switch p.currentByte { - case '"': - return - case '\n': - p.parseError(fmt.Sprintf("label value %q contains unescaped new-line", p.currentToken.String())) - return - case '\\': - escaped = true - default: - p.currentToken.WriteByte(p.currentByte) - } - } -} - -func (p *TextParser) setOrCreateCurrentMF() { - p.currentIsSummaryCount = false - p.currentIsSummarySum = false - p.currentIsHistogramCount = false - p.currentIsHistogramSum = false - name := p.currentToken.String() - if !p.scheme.IsValidMetricName(name) { - p.parseError(fmt.Sprintf("invalid metric name %q", name)) - return - } - if p.currentMF = p.metricFamiliesByName[name]; p.currentMF != nil { - return - } - // Try out if this is a _sum or _count for a summary/histogram. - summaryName := summaryMetricName(name) - if p.currentMF = p.metricFamiliesByName[summaryName]; p.currentMF != nil { - if p.currentMF.GetType() == dto.MetricType_SUMMARY { - if isCount(name) { - p.currentIsSummaryCount = true - } - if isSum(name) { - p.currentIsSummarySum = true - } - return - } - } - histogramName := histogramMetricName(name) - if p.currentMF = p.metricFamiliesByName[histogramName]; p.currentMF != nil { - if p.currentMF.GetType() == dto.MetricType_HISTOGRAM || - p.currentMF.GetType() == dto.MetricType_GAUGE_HISTOGRAM { - if isCount(name) { - p.currentIsHistogramCount = true - } - if isSum(name) { - p.currentIsHistogramSum = true - } - return - } - } - p.currentMF = &dto.MetricFamily{Name: proto.String(name)} - p.metricFamiliesByName[name] = p.currentMF -} - -func isValidLabelNameStart(b byte) bool { - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == '"' -} - -func isValidLabelNameContinuation(b byte, quoted bool) bool { - return isValidLabelNameStart(b) || (b >= '0' && b <= '9') || (quoted && utf8.ValidString(string(b))) -} - -func isValidMetricNameStart(b byte) bool { - return isValidLabelNameStart(b) || b == ':' -} - -func isValidMetricNameContinuation(b byte, quoted bool) bool { - return isValidLabelNameContinuation(b, quoted) || b == ':' -} - -func isBlankOrTab(b byte) bool { - return b == ' ' || b == '\t' -} - -func isCount(name string) bool { - return len(name) > 6 && name[len(name)-6:] == "_count" -} - -func isSum(name string) bool { - return len(name) > 4 && name[len(name)-4:] == "_sum" -} - -func isBucket(name string) bool { - return len(name) > 7 && name[len(name)-7:] == "_bucket" -} - -func summaryMetricName(name string) string { - switch { - case isCount(name): - return name[:len(name)-6] - case isSum(name): - return name[:len(name)-4] - default: - return name - } -} - -func histogramMetricName(name string) string { - switch { - case isCount(name): - return name[:len(name)-6] - case isSum(name): - return name[:len(name)-4] - case isBucket(name): - return name[:len(name)-7] - default: - return name - } -} - -func parseFloat(s string) (float64, error) { - if strings.ContainsAny(s, "pP_") { - return 0, errors.New("unsupported character in float") - } - return strconv.ParseFloat(s, 64) -} diff --git a/vendor/github.com/prometheus/common/model/alert.go b/vendor/github.com/prometheus/common/model/alert.go deleted file mode 100644 index 460f554f2945..000000000000 --- a/vendor/github.com/prometheus/common/model/alert.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "errors" - "fmt" - "time" -) - -type AlertStatus string - -const ( - AlertFiring AlertStatus = "firing" - AlertResolved AlertStatus = "resolved" -) - -// Alert is a generic representation of an alert in the Prometheus eco-system. -type Alert struct { - // Label value pairs for purpose of aggregation, matching, and disposition - // dispatching. This must minimally include an "alertname" label. - Labels LabelSet `json:"labels"` - - // Extra key/value information which does not define alert identity. - Annotations LabelSet `json:"annotations"` - - // The known time range for this alert. Both ends are optional. - StartsAt time.Time `json:"startsAt,omitempty"` - EndsAt time.Time `json:"endsAt,omitempty"` - GeneratorURL string `json:"generatorURL"` -} - -// Name returns the name of the alert. It is equivalent to the "alertname" label. -func (a *Alert) Name() string { - return string(a.Labels[AlertNameLabel]) -} - -// Fingerprint returns a unique hash for the alert. It is equivalent to -// the fingerprint of the alert's label set. -func (a *Alert) Fingerprint() Fingerprint { - return a.Labels.Fingerprint() -} - -func (a *Alert) String() string { - s := fmt.Sprintf("%s[%s]", a.Name(), a.Fingerprint().String()[:7]) - if a.Resolved() { - return s + "[resolved]" - } - return s + "[active]" -} - -// Resolved returns true iff the activity interval ended in the past. -func (a *Alert) Resolved() bool { - return a.ResolvedAt(time.Now()) -} - -// ResolvedAt returns true iff the activity interval ended before -// the given timestamp. -func (a *Alert) ResolvedAt(ts time.Time) bool { - if a.EndsAt.IsZero() { - return false - } - return !a.EndsAt.After(ts) -} - -// Status returns the status of the alert. -func (a *Alert) Status() AlertStatus { - return a.StatusAt(time.Now()) -} - -// StatusAt returns the status of the alert at the given timestamp. -func (a *Alert) StatusAt(ts time.Time) AlertStatus { - if a.ResolvedAt(ts) { - return AlertResolved - } - return AlertFiring -} - -// Validate checks whether the alert data is inconsistent. -func (a *Alert) Validate() error { - if a.StartsAt.IsZero() { - return errors.New("start time missing") - } - if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) { - return errors.New("start time must be before end time") - } - if err := a.Labels.Validate(); err != nil { - return fmt.Errorf("invalid label set: %w", err) - } - if len(a.Labels) == 0 { - return errors.New("at least one label pair required") - } - if err := a.Annotations.Validate(); err != nil { - return fmt.Errorf("invalid annotations: %w", err) - } - return nil -} - -// Alert is a list of alerts that can be sorted in chronological order. -type Alerts []*Alert - -func (as Alerts) Len() int { return len(as) } -func (as Alerts) Swap(i, j int) { as[i], as[j] = as[j], as[i] } - -func (as Alerts) Less(i, j int) bool { - if as[i].StartsAt.Before(as[j].StartsAt) { - return true - } - if as[i].EndsAt.Before(as[j].EndsAt) { - return true - } - return as[i].Fingerprint() < as[j].Fingerprint() -} - -// HasFiring returns true iff one of the alerts is not resolved. -func (as Alerts) HasFiring() bool { - for _, a := range as { - if !a.Resolved() { - return true - } - } - return false -} - -// HasFiringAt returns true iff one of the alerts is not resolved -// at the time ts. -func (as Alerts) HasFiringAt(ts time.Time) bool { - for _, a := range as { - if !a.ResolvedAt(ts) { - return true - } - } - return false -} - -// Status returns StatusFiring iff at least one of the alerts is firing. -func (as Alerts) Status() AlertStatus { - if as.HasFiring() { - return AlertFiring - } - return AlertResolved -} - -// StatusAt returns StatusFiring iff at least one of the alerts is firing -// at the time ts. -func (as Alerts) StatusAt(ts time.Time) AlertStatus { - if as.HasFiringAt(ts) { - return AlertFiring - } - return AlertResolved -} diff --git a/vendor/github.com/prometheus/common/model/fingerprinting.go b/vendor/github.com/prometheus/common/model/fingerprinting.go deleted file mode 100644 index fc4de4106e85..000000000000 --- a/vendor/github.com/prometheus/common/model/fingerprinting.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "fmt" - "strconv" -) - -// Fingerprint provides a hash-capable representation of a Metric. -// For our purposes, FNV-1A 64-bit is used. -type Fingerprint uint64 - -// FingerprintFromString transforms a string representation into a Fingerprint. -func FingerprintFromString(s string) (Fingerprint, error) { - num, err := strconv.ParseUint(s, 16, 64) - return Fingerprint(num), err -} - -// ParseFingerprint parses the input string into a fingerprint. -func ParseFingerprint(s string) (Fingerprint, error) { - num, err := strconv.ParseUint(s, 16, 64) - if err != nil { - return 0, err - } - return Fingerprint(num), nil -} - -func (f Fingerprint) String() string { - return fmt.Sprintf("%016x", uint64(f)) -} - -// Fingerprints represents a collection of Fingerprint subject to a given -// natural sorting scheme. It implements sort.Interface. -type Fingerprints []Fingerprint - -// Len implements sort.Interface. -func (f Fingerprints) Len() int { - return len(f) -} - -// Less implements sort.Interface. -func (f Fingerprints) Less(i, j int) bool { - return f[i] < f[j] -} - -// Swap implements sort.Interface. -func (f Fingerprints) Swap(i, j int) { - f[i], f[j] = f[j], f[i] -} - -// FingerprintSet is a set of Fingerprints. -type FingerprintSet map[Fingerprint]struct{} - -// Equal returns true if both sets contain the same elements (and not more). -func (s FingerprintSet) Equal(o FingerprintSet) bool { - if len(s) != len(o) { - return false - } - - for k := range s { - if _, ok := o[k]; !ok { - return false - } - } - - return true -} - -// Intersection returns the elements contained in both sets. -func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet { - myLength, otherLength := len(s), len(o) - if myLength == 0 || otherLength == 0 { - return FingerprintSet{} - } - - subSet := s - superSet := o - - if otherLength < myLength { - subSet = o - superSet = s - } - - out := FingerprintSet{} - - for k := range subSet { - if _, ok := superSet[k]; ok { - out[k] = struct{}{} - } - } - - return out -} diff --git a/vendor/github.com/prometheus/common/model/fnv.go b/vendor/github.com/prometheus/common/model/fnv.go deleted file mode 100644 index 367afecd30e6..000000000000 --- a/vendor/github.com/prometheus/common/model/fnv.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -// Inline and byte-free variant of hash/fnv's fnv64a. - -const ( - offset64 = 14695981039346656037 - prime64 = 1099511628211 -) - -// hashNew initializes a new fnv64a hash value. -func hashNew() uint64 { - return offset64 -} - -// hashAdd adds a string to a fnv64a hash value, returning the updated hash. -func hashAdd(h uint64, s string) uint64 { - for i := 0; i < len(s); i++ { - h ^= uint64(s[i]) - h *= prime64 - } - return h -} - -// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. -func hashAddByte(h uint64, b byte) uint64 { - h ^= uint64(b) - h *= prime64 - return h -} diff --git a/vendor/github.com/prometheus/common/model/labels.go b/vendor/github.com/prometheus/common/model/labels.go deleted file mode 100644 index dfeb34be5f3a..000000000000 --- a/vendor/github.com/prometheus/common/model/labels.go +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "fmt" - "regexp" - "strings" - "unicode/utf8" -) - -const ( - // AlertNameLabel is the name of the label containing the alert's name. - AlertNameLabel = "alertname" - - // ExportedLabelPrefix is the prefix to prepend to the label names present in - // exported metrics if a label of the same name is added by the server. - ExportedLabelPrefix = "exported_" - - // MetricNameLabel is the label name indicating the metric name of a - // timeseries. - MetricNameLabel = "__name__" - // MetricTypeLabel is the label name indicating the metric type of - // timeseries as per the PROM-39 proposal. - MetricTypeLabel = "__type__" - // MetricUnitLabel is the label name indicating the metric unit of - // timeseries as per the PROM-39 proposal. - MetricUnitLabel = "__unit__" - - // SchemeLabel is the name of the label that holds the scheme on which to - // scrape a target. - SchemeLabel = "__scheme__" - - // AddressLabel is the name of the label that holds the address of - // a scrape target. - AddressLabel = "__address__" - - // MetricsPathLabel is the name of the label that holds the path on which to - // scrape a target. - MetricsPathLabel = "__metrics_path__" - - // ScrapeIntervalLabel is the name of the label that holds the scrape interval - // used to scrape a target. - ScrapeIntervalLabel = "__scrape_interval__" - - // ScrapeTimeoutLabel is the name of the label that holds the scrape - // timeout used to scrape a target. - ScrapeTimeoutLabel = "__scrape_timeout__" - - // ReservedLabelPrefix is a prefix which is not legal in user-supplied - // label names. - ReservedLabelPrefix = "__" - - // MetaLabelPrefix is a prefix for labels that provide meta information. - // Labels with this prefix are used for intermediate label processing and - // will not be attached to time series. - MetaLabelPrefix = "__meta_" - - // TmpLabelPrefix is a prefix for temporary labels as part of relabelling. - // Labels with this prefix are used for intermediate label processing and - // will not be attached to time series. This is reserved for use in - // Prometheus configuration files by users. - TmpLabelPrefix = "__tmp_" - - // ParamLabelPrefix is a prefix for labels that provide URL parameters - // used to scrape a target. - ParamLabelPrefix = "__param_" - - // JobLabel is the label name indicating the job from which a timeseries - // was scraped. - JobLabel = "job" - - // InstanceLabel is the label name used for the instance label. - InstanceLabel = "instance" - - // BucketLabel is used for the label that defines the upper bound of a - // bucket of a histogram ("le" -> "less or equal"). - BucketLabel = "le" - - // QuantileLabel is used for the label that defines the quantile in a - // summary. - QuantileLabel = "quantile" -) - -// LabelNameRE is a regular expression matching valid label names. Note that the -// IsValid method of LabelName performs the same check but faster than a match -// with this regular expression. -var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") - -// A LabelName is a key for a LabelSet or Metric. It has a value associated -// therewith. -type LabelName string - -// IsValid returns true iff the name matches the pattern of LabelNameRE when -// NameValidationScheme is set to LegacyValidation, or valid UTF-8 if -// NameValidationScheme is set to UTF8Validation. -// -// Deprecated: This method should not be used and may be removed in the future. -// Use [ValidationScheme.IsValidLabelName] instead. -func (ln LabelName) IsValid() bool { - return NameValidationScheme.IsValidLabelName(string(ln)) -} - -// IsValidLegacy returns true iff name matches the pattern of LabelNameRE for -// legacy names. It does not use LabelNameRE for the check but a much faster -// hardcoded implementation. -// -// Deprecated: This method should not be used and may be removed in the future. -// Use [LegacyValidation.IsValidLabelName] instead. -func (ln LabelName) IsValidLegacy() bool { - return LegacyValidation.IsValidLabelName(string(ln)) -} - -// UnmarshalYAML implements the yaml.Unmarshaler interface. -func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { - var s string - if err := unmarshal(&s); err != nil { - return err - } - if !LabelName(s).IsValid() { - return fmt.Errorf("%q is not a valid label name", s) - } - *ln = LabelName(s) - return nil -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (ln *LabelName) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - if !LabelName(s).IsValid() { - return fmt.Errorf("%q is not a valid label name", s) - } - *ln = LabelName(s) - return nil -} - -// LabelNames is a sortable LabelName slice. In implements sort.Interface. -type LabelNames []LabelName - -func (l LabelNames) Len() int { - return len(l) -} - -func (l LabelNames) Less(i, j int) bool { - return l[i] < l[j] -} - -func (l LabelNames) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} - -func (l LabelNames) String() string { - labelStrings := make([]string, 0, len(l)) - for _, label := range l { - labelStrings = append(labelStrings, string(label)) - } - return strings.Join(labelStrings, ", ") -} - -// A LabelValue is an associated value for a LabelName. -type LabelValue string - -// IsValid returns true iff the string is a valid UTF-8. -func (lv LabelValue) IsValid() bool { - return utf8.ValidString(string(lv)) -} - -// LabelValues is a sortable LabelValue slice. It implements sort.Interface. -type LabelValues []LabelValue - -func (l LabelValues) Len() int { - return len(l) -} - -func (l LabelValues) Less(i, j int) bool { - return string(l[i]) < string(l[j]) -} - -func (l LabelValues) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} - -// LabelPair pairs a name with a value. -type LabelPair struct { - Name LabelName - Value LabelValue -} - -// LabelPairs is a sortable slice of LabelPair pointers. It implements -// sort.Interface. -type LabelPairs []*LabelPair - -func (l LabelPairs) Len() int { - return len(l) -} - -func (l LabelPairs) Less(i, j int) bool { - switch { - case l[i].Name > l[j].Name: - return false - case l[i].Name < l[j].Name: - return true - case l[i].Value > l[j].Value: - return false - case l[i].Value < l[j].Value: - return true - default: - return false - } -} - -func (l LabelPairs) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} diff --git a/vendor/github.com/prometheus/common/model/labelset.go b/vendor/github.com/prometheus/common/model/labelset.go deleted file mode 100644 index 9de47b2568ee..000000000000 --- a/vendor/github.com/prometheus/common/model/labelset.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "fmt" - "sort" -) - -// A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet -// may be fully-qualified down to the point where it may resolve to a single -// Metric in the data store or not. All operations that occur within the realm -// of a LabelSet can emit a vector of Metric entities to which the LabelSet may -// match. -type LabelSet map[LabelName]LabelValue - -// Validate checks whether all names and values in the label set -// are valid. -func (ls LabelSet) Validate() error { - for ln, lv := range ls { - if !ln.IsValid() { - return fmt.Errorf("invalid name %q", ln) - } - if !lv.IsValid() { - return fmt.Errorf("invalid value %q", lv) - } - } - return nil -} - -// Equal returns true iff both label sets have exactly the same key/value pairs. -func (ls LabelSet) Equal(o LabelSet) bool { - if len(ls) != len(o) { - return false - } - for ln, lv := range ls { - olv, ok := o[ln] - if !ok { - return false - } - if olv != lv { - return false - } - } - return true -} - -// Before compares the metrics, using the following criteria: -// -// If m has fewer labels than o, it is before o. If it has more, it is not. -// -// If the number of labels is the same, the superset of all label names is -// sorted alphanumerically. The first differing label pair found in that order -// determines the outcome: If the label does not exist at all in m, then m is -// before o, and vice versa. Otherwise the label value is compared -// alphanumerically. -// -// If m and o are equal, the method returns false. -func (ls LabelSet) Before(o LabelSet) bool { - if len(ls) < len(o) { - return true - } - if len(ls) > len(o) { - return false - } - - lns := make(LabelNames, 0, len(ls)+len(o)) - for ln := range ls { - lns = append(lns, ln) - } - for ln := range o { - lns = append(lns, ln) - } - // It's probably not worth it to de-dup lns. - sort.Sort(lns) - for _, ln := range lns { - mlv, ok := ls[ln] - if !ok { - return true - } - olv, ok := o[ln] - if !ok { - return false - } - if mlv < olv { - return true - } - if mlv > olv { - return false - } - } - return false -} - -// Clone returns a copy of the label set. -func (ls LabelSet) Clone() LabelSet { - lsn := make(LabelSet, len(ls)) - for ln, lv := range ls { - lsn[ln] = lv - } - return lsn -} - -// Merge is a helper function to non-destructively merge two label sets. -func (ls LabelSet) Merge(other LabelSet) LabelSet { - result := make(LabelSet, len(ls)) - - for k, v := range ls { - result[k] = v - } - - for k, v := range other { - result[k] = v - } - - return result -} - -// Fingerprint returns the LabelSet's fingerprint. -func (ls LabelSet) Fingerprint() Fingerprint { - return labelSetToFingerprint(ls) -} - -// FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing -// algorithm, which is, however, more susceptible to hash collisions. -func (ls LabelSet) FastFingerprint() Fingerprint { - return labelSetToFastFingerprint(ls) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (ls *LabelSet) UnmarshalJSON(b []byte) error { - var m map[LabelName]LabelValue - if err := json.Unmarshal(b, &m); err != nil { - return err - } - // encoding/json only unmarshals maps of the form map[string]T. It treats - // LabelName as a string and does not call its UnmarshalJSON method. - // Thus, we have to replicate the behavior here. - for ln := range m { - if !ln.IsValid() { - return fmt.Errorf("%q is not a valid label name", ln) - } - } - *ls = LabelSet(m) - return nil -} diff --git a/vendor/github.com/prometheus/common/model/labelset_string.go b/vendor/github.com/prometheus/common/model/labelset_string.go deleted file mode 100644 index abb2c9001831..000000000000 --- a/vendor/github.com/prometheus/common/model/labelset_string.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "bytes" - "slices" - "strconv" -) - -// String will look like `{foo="bar", more="less"}`. Names are sorted alphabetically. -func (l LabelSet) String() string { - var lna [32]string // On stack to avoid memory allocation for sorting names. - labelNames := lna[:0] - for name := range l { - labelNames = append(labelNames, string(name)) - } - slices.Sort(labelNames) - var bytea [1024]byte // On stack to avoid memory allocation while building the output. - b := bytes.NewBuffer(bytea[:0]) - b.WriteByte('{') - for i, name := range labelNames { - if i > 0 { - b.WriteString(", ") - } - b.WriteString(name) - b.WriteByte('=') - b.Write(strconv.AppendQuote(b.AvailableBuffer(), string(l[LabelName(name)]))) - } - b.WriteByte('}') - return b.String() -} diff --git a/vendor/github.com/prometheus/common/model/metadata.go b/vendor/github.com/prometheus/common/model/metadata.go deleted file mode 100644 index 447ab8ad635b..000000000000 --- a/vendor/github.com/prometheus/common/model/metadata.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2023 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -// MetricType represents metric type values. -type MetricType string - -const ( - MetricTypeCounter = MetricType("counter") - MetricTypeGauge = MetricType("gauge") - MetricTypeHistogram = MetricType("histogram") - MetricTypeGaugeHistogram = MetricType("gaugehistogram") - MetricTypeSummary = MetricType("summary") - MetricTypeInfo = MetricType("info") - MetricTypeStateset = MetricType("stateset") - MetricTypeUnknown = MetricType("unknown") -) diff --git a/vendor/github.com/prometheus/common/model/metric.go b/vendor/github.com/prometheus/common/model/metric.go deleted file mode 100644 index 3feebf328ae6..000000000000 --- a/vendor/github.com/prometheus/common/model/metric.go +++ /dev/null @@ -1,593 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "errors" - "fmt" - "regexp" - "sort" - "strconv" - "strings" - "unicode/utf8" - - dto "github.com/prometheus/client_model/go" - "go.yaml.in/yaml/v2" - "google.golang.org/protobuf/proto" -) - -var ( - // NameValidationScheme determines the global default method of the name - // validation to be used by all calls to IsValidMetricName() and LabelName - // IsValid(). - // - // Deprecated: This variable should not be used and might be removed in the - // far future. If you wish to stick to the legacy name validation use - // `IsValidLegacyMetricName()` and `LabelName.IsValidLegacy()` methods - // instead. This variable is here as an escape hatch for emergency cases, - // given the recent change from `LegacyValidation` to `UTF8Validation`, e.g., - // to delay UTF-8 migrations in time or aid in debugging unforeseen results of - // the change. In such a case, a temporary assignment to `LegacyValidation` - // value in the `init()` function in your main.go or so, could be considered. - // - // Historically we opted for a global variable for feature gating different - // validation schemes in operations that were not otherwise easily adjustable - // (e.g. Labels yaml unmarshaling). That could have been a mistake, a separate - // Labels structure or package might have been a better choice. Given the - // change was made and many upgraded the common already, we live this as-is - // with this warning and learning for the future. - NameValidationScheme = UTF8Validation - - // NameEscapingScheme defines the default way that names will be escaped when - // presented to systems that do not support UTF-8 names. If the Content-Type - // "escaping" term is specified, that will override this value. - // NameEscapingScheme should not be set to the NoEscaping value. That string - // is used in content negotiation to indicate that a system supports UTF-8 and - // has that feature enabled. - NameEscapingScheme = UnderscoreEscaping -) - -// ValidationScheme is a Go enum for determining how metric and label names will -// be validated by this library. -type ValidationScheme int - -const ( - // UnsetValidation represents an undefined ValidationScheme. - // Should not be used in practice. - UnsetValidation ValidationScheme = iota - - // LegacyValidation is a setting that requires that all metric and label names - // conform to the original Prometheus character requirements described by - // MetricNameRE and LabelNameRE. - LegacyValidation - - // UTF8Validation only requires that metric and label names be valid UTF-8 - // strings. - UTF8Validation -) - -var _ interface { - yaml.Marshaler - yaml.Unmarshaler - json.Marshaler - json.Unmarshaler - fmt.Stringer -} = new(ValidationScheme) - -// String returns the string representation of s. -func (s ValidationScheme) String() string { - switch s { - case UnsetValidation: - return "unset" - case LegacyValidation: - return "legacy" - case UTF8Validation: - return "utf8" - default: - panic(fmt.Errorf("unhandled ValidationScheme: %d", s)) - } -} - -// MarshalYAML implements the yaml.Marshaler interface. -func (s ValidationScheme) MarshalYAML() (any, error) { - switch s { - case UnsetValidation: - return "", nil - case LegacyValidation, UTF8Validation: - return s.String(), nil - default: - panic(fmt.Errorf("unhandled ValidationScheme: %d", s)) - } -} - -// UnmarshalYAML implements the yaml.Unmarshaler interface. -func (s *ValidationScheme) UnmarshalYAML(unmarshal func(any) error) error { - var scheme string - if err := unmarshal(&scheme); err != nil { - return err - } - return s.Set(scheme) -} - -// MarshalJSON implements the json.Marshaler interface. -func (s ValidationScheme) MarshalJSON() ([]byte, error) { - switch s { - case UnsetValidation: - return json.Marshal("") - case UTF8Validation, LegacyValidation: - return json.Marshal(s.String()) - default: - return nil, fmt.Errorf("unhandled ValidationScheme: %d", s) - } -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (s *ValidationScheme) UnmarshalJSON(bytes []byte) error { - var repr string - if err := json.Unmarshal(bytes, &repr); err != nil { - return err - } - return s.Set(repr) -} - -// Set implements the pflag.Value interface. -func (s *ValidationScheme) Set(text string) error { - switch text { - case "": - // Don't change the value. - case LegacyValidation.String(): - *s = LegacyValidation - case UTF8Validation.String(): - *s = UTF8Validation - default: - return fmt.Errorf("unrecognized ValidationScheme: %q", text) - } - return nil -} - -// IsValidMetricName returns whether metricName is valid according to s. -func (s ValidationScheme) IsValidMetricName(metricName string) bool { - switch s { - case LegacyValidation: - if len(metricName) == 0 { - return false - } - for i, b := range metricName { - if !isValidLegacyRune(b, i) { - return false - } - } - return true - case UTF8Validation: - if len(metricName) == 0 { - return false - } - return utf8.ValidString(metricName) - default: - panic(fmt.Sprintf("Invalid name validation scheme requested: %s", s.String())) - } -} - -// IsValidLabelName returns whether labelName is valid according to s. -func (s ValidationScheme) IsValidLabelName(labelName string) bool { - switch s { - case LegacyValidation: - if len(labelName) == 0 { - return false - } - for i, b := range labelName { - // TODO: Apply De Morgan's law. Make sure there are tests for this. - if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { //nolint:staticcheck - return false - } - } - return true - case UTF8Validation: - if len(labelName) == 0 { - return false - } - return utf8.ValidString(labelName) - default: - panic(fmt.Sprintf("Invalid name validation scheme requested: %s", s)) - } -} - -// Type implements the pflag.Value interface. -func (ValidationScheme) Type() string { - return "validationScheme" -} - -type EscapingScheme int - -const ( - // NoEscaping indicates that a name will not be escaped. Unescaped names that - // do not conform to the legacy validity check will use a new exposition - // format syntax that will be officially standardized in future versions. - NoEscaping EscapingScheme = iota - - // UnderscoreEscaping replaces all legacy-invalid characters with underscores. - UnderscoreEscaping - - // DotsEscaping is similar to UnderscoreEscaping, except that dots are - // converted to `_dot_` and pre-existing underscores are converted to `__`. - DotsEscaping - - // ValueEncodingEscaping prepends the name with `U__` and replaces all invalid - // characters with the unicode value, surrounded by underscores. Single - // underscores are replaced with double underscores. - ValueEncodingEscaping -) - -const ( - // EscapingKey is the key in an Accept or Content-Type header that defines how - // metric and label names that do not conform to the legacy character - // requirements should be escaped when being scraped by a legacy prometheus - // system. If a system does not explicitly pass an escaping parameter in the - // Accept header, the default NameEscapingScheme will be used. - EscapingKey = "escaping" - - // Possible values for Escaping Key. - AllowUTF8 = "allow-utf-8" // No escaping required. - EscapeUnderscores = "underscores" - EscapeDots = "dots" - EscapeValues = "values" -) - -// MetricNameRE is a regular expression matching valid metric -// names. Note that the IsValidMetricName function performs the same -// check but faster than a match with this regular expression. -var MetricNameRE = regexp.MustCompile(`^[a-zA-Z_:][a-zA-Z0-9_:]*$`) - -// A Metric is similar to a LabelSet, but the key difference is that a Metric is -// a singleton and refers to one and only one stream of samples. -type Metric LabelSet - -// Equal compares the metrics. -func (m Metric) Equal(o Metric) bool { - return LabelSet(m).Equal(LabelSet(o)) -} - -// Before compares the metrics' underlying label sets. -func (m Metric) Before(o Metric) bool { - return LabelSet(m).Before(LabelSet(o)) -} - -// Clone returns a copy of the Metric. -func (m Metric) Clone() Metric { - clone := make(Metric, len(m)) - for k, v := range m { - clone[k] = v - } - return clone -} - -func (m Metric) String() string { - metricName, hasName := m[MetricNameLabel] - numLabels := len(m) - 1 - if !hasName { - numLabels = len(m) - } - labelStrings := make([]string, 0, numLabels) - for label, value := range m { - if label != MetricNameLabel { - labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value)) - } - } - - switch numLabels { - case 0: - if hasName { - return string(metricName) - } - return "{}" - default: - sort.Strings(labelStrings) - return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", ")) - } -} - -// Fingerprint returns a Metric's Fingerprint. -func (m Metric) Fingerprint() Fingerprint { - return LabelSet(m).Fingerprint() -} - -// FastFingerprint returns a Metric's Fingerprint calculated by a faster hashing -// algorithm, which is, however, more susceptible to hash collisions. -func (m Metric) FastFingerprint() Fingerprint { - return LabelSet(m).FastFingerprint() -} - -// IsValidMetricName returns true iff name matches the pattern of MetricNameRE -// for legacy names, and iff it's valid UTF-8 if the UTF8Validation scheme is -// selected. -// -// Deprecated: This function should not be used and might be removed in the future. -// Use [ValidationScheme.IsValidMetricName] instead. -func IsValidMetricName(n LabelValue) bool { - return NameValidationScheme.IsValidMetricName(string(n)) -} - -// IsValidLegacyMetricName is similar to IsValidMetricName but always uses the -// legacy validation scheme regardless of the value of NameValidationScheme. -// This function, however, does not use MetricNameRE for the check but a much -// faster hardcoded implementation. -// -// Deprecated: This function should not be used and might be removed in the future. -// Use [LegacyValidation.IsValidMetricName] instead. -func IsValidLegacyMetricName(n string) bool { - return LegacyValidation.IsValidMetricName(n) -} - -// EscapeMetricFamily escapes the given metric names and labels with the given -// escaping scheme. Returns a new object that uses the same pointers to fields -// when possible and creates new escaped versions so as not to mutate the -// input. -func EscapeMetricFamily(v *dto.MetricFamily, scheme EscapingScheme) *dto.MetricFamily { - if v == nil { - return nil - } - - if scheme == NoEscaping { - return v - } - - out := &dto.MetricFamily{ - Help: v.Help, - Type: v.Type, - Unit: v.Unit, - } - - // If the name is nil, copy as-is, don't try to escape. - if v.Name == nil || IsValidLegacyMetricName(v.GetName()) { - out.Name = v.Name - } else { - out.Name = proto.String(EscapeName(v.GetName(), scheme)) - } - for _, m := range v.Metric { - if !metricNeedsEscaping(m) { - out.Metric = append(out.Metric, m) - continue - } - - escaped := &dto.Metric{ - Gauge: m.Gauge, - Counter: m.Counter, - Summary: m.Summary, - Untyped: m.Untyped, - Histogram: m.Histogram, - TimestampMs: m.TimestampMs, - } - - for _, l := range m.Label { - if l.GetName() == MetricNameLabel { - if l.Value == nil || IsValidLegacyMetricName(l.GetValue()) { - escaped.Label = append(escaped.Label, l) - continue - } - escaped.Label = append(escaped.Label, &dto.LabelPair{ - Name: proto.String(MetricNameLabel), - Value: proto.String(EscapeName(l.GetValue(), scheme)), - }) - continue - } - if l.Name == nil || IsValidLegacyMetricName(l.GetName()) { - escaped.Label = append(escaped.Label, l) - continue - } - escaped.Label = append(escaped.Label, &dto.LabelPair{ - Name: proto.String(EscapeName(l.GetName(), scheme)), - Value: l.Value, - }) - } - out.Metric = append(out.Metric, escaped) - } - return out -} - -func metricNeedsEscaping(m *dto.Metric) bool { - for _, l := range m.Label { - if l.GetName() == MetricNameLabel && !IsValidLegacyMetricName(l.GetValue()) { - return true - } - if !IsValidLegacyMetricName(l.GetName()) { - return true - } - } - return false -} - -// EscapeName escapes the incoming name according to the provided escaping -// scheme. Depending on the rules of escaping, this may cause no change in the -// string that is returned. (Especially NoEscaping, which by definition is a -// noop). This function does not do any validation of the name. -func EscapeName(name string, scheme EscapingScheme) string { - if len(name) == 0 { - return name - } - var escaped strings.Builder - switch scheme { - case NoEscaping: - return name - case UnderscoreEscaping: - if IsValidLegacyMetricName(name) { - return name - } - for i, b := range name { - if isValidLegacyRune(b, i) { - escaped.WriteRune(b) - } else { - escaped.WriteRune('_') - } - } - return escaped.String() - case DotsEscaping: - // Do not early return for legacy valid names, we still escape underscores. - for i, b := range name { - switch { - case b == '_': - escaped.WriteString("__") - case b == '.': - escaped.WriteString("_dot_") - case isValidLegacyRune(b, i): - escaped.WriteRune(b) - default: - escaped.WriteString("__") - } - } - return escaped.String() - case ValueEncodingEscaping: - if IsValidLegacyMetricName(name) { - return name - } - escaped.WriteString("U__") - for i, b := range name { - switch { - case b == '_': - escaped.WriteString("__") - case isValidLegacyRune(b, i): - escaped.WriteRune(b) - case !utf8.ValidRune(b): - escaped.WriteString("_FFFD_") - default: - escaped.WriteRune('_') - escaped.WriteString(strconv.FormatInt(int64(b), 16)) - escaped.WriteRune('_') - } - } - return escaped.String() - default: - panic(fmt.Sprintf("invalid escaping scheme %d", scheme)) - } -} - -// lower function taken from strconv.atoi. -func lower(c byte) byte { - return c | ('x' - 'X') -} - -// UnescapeName unescapes the incoming name according to the provided escaping -// scheme if possible. Some schemes are partially or totally non-roundtripable. -// If any error is enountered, returns the original input. -func UnescapeName(name string, scheme EscapingScheme) string { - if len(name) == 0 { - return name - } - switch scheme { - case NoEscaping: - return name - case UnderscoreEscaping: - // It is not possible to unescape from underscore replacement. - return name - case DotsEscaping: - name = strings.ReplaceAll(name, "_dot_", ".") - name = strings.ReplaceAll(name, "__", "_") - return name - case ValueEncodingEscaping: - escapedName, found := strings.CutPrefix(name, "U__") - if !found { - return name - } - - var unescaped strings.Builder - TOP: - for i := 0; i < len(escapedName); i++ { - // All non-underscores are treated normally. - if escapedName[i] != '_' { - unescaped.WriteByte(escapedName[i]) - continue - } - i++ - if i >= len(escapedName) { - return name - } - // A double underscore is a single underscore. - if escapedName[i] == '_' { - unescaped.WriteByte('_') - continue - } - // We think we are in a UTF-8 code, process it. - var utf8Val uint - for j := 0; i < len(escapedName); j++ { - // This is too many characters for a utf8 value based on the MaxRune - // value of '\U0010FFFF'. - if j >= 6 { - return name - } - // Found a closing underscore, convert to a rune, check validity, and append. - if escapedName[i] == '_' { - utf8Rune := rune(utf8Val) - if !utf8.ValidRune(utf8Rune) { - return name - } - unescaped.WriteRune(utf8Rune) - continue TOP - } - r := lower(escapedName[i]) - utf8Val *= 16 - switch { - case r >= '0' && r <= '9': - utf8Val += uint(r) - '0' - case r >= 'a' && r <= 'f': - utf8Val += uint(r) - 'a' + 10 - default: - return name - } - i++ - } - // Didn't find closing underscore, invalid. - return name - } - return unescaped.String() - default: - panic(fmt.Sprintf("invalid escaping scheme %d", scheme)) - } -} - -func isValidLegacyRune(b rune, i int) bool { - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0) -} - -func (e EscapingScheme) String() string { - switch e { - case NoEscaping: - return AllowUTF8 - case UnderscoreEscaping: - return EscapeUnderscores - case DotsEscaping: - return EscapeDots - case ValueEncodingEscaping: - return EscapeValues - default: - panic(fmt.Sprintf("unknown format scheme %d", e)) - } -} - -func ToEscapingScheme(s string) (EscapingScheme, error) { - if s == "" { - return NoEscaping, errors.New("got empty string instead of escaping scheme") - } - switch s { - case AllowUTF8: - return NoEscaping, nil - case EscapeUnderscores: - return UnderscoreEscaping, nil - case EscapeDots: - return DotsEscaping, nil - case EscapeValues: - return ValueEncodingEscaping, nil - default: - return NoEscaping, fmt.Errorf("unknown format scheme %s", s) - } -} diff --git a/vendor/github.com/prometheus/common/model/model.go b/vendor/github.com/prometheus/common/model/model.go deleted file mode 100644 index a7b9691707e8..000000000000 --- a/vendor/github.com/prometheus/common/model/model.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package model contains common data structures that are shared across -// Prometheus components and libraries. -package model diff --git a/vendor/github.com/prometheus/common/model/signature.go b/vendor/github.com/prometheus/common/model/signature.go deleted file mode 100644 index dc8a0026c484..000000000000 --- a/vendor/github.com/prometheus/common/model/signature.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2014 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "sort" -) - -// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is -// used to separate label names, label values, and other strings from each other -// when calculating their combined hash value (aka signature aka fingerprint). -const SeparatorByte byte = 255 - -// cache the signature of an empty label set. -var emptyLabelSignature = hashNew() - -// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a -// given label set. (Collisions are possible but unlikely if the number of label -// sets the function is applied to is small.) -func LabelsToSignature(labels map[string]string) uint64 { - if len(labels) == 0 { - return emptyLabelSignature - } - - labelNames := make([]string, 0, len(labels)) - for labelName := range labels { - labelNames = append(labelNames, labelName) - } - sort.Strings(labelNames) - - sum := hashNew() - for _, labelName := range labelNames { - sum = hashAdd(sum, labelName) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, labels[labelName]) - sum = hashAddByte(sum, SeparatorByte) - } - return sum -} - -// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as -// parameter (rather than a label map) and returns a Fingerprint. -func labelSetToFingerprint(ls LabelSet) Fingerprint { - if len(ls) == 0 { - return Fingerprint(emptyLabelSignature) - } - - labelNames := make(LabelNames, 0, len(ls)) - for labelName := range ls { - labelNames = append(labelNames, labelName) - } - sort.Sort(labelNames) - - sum := hashNew() - for _, labelName := range labelNames { - sum = hashAdd(sum, string(labelName)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(ls[labelName])) - sum = hashAddByte(sum, SeparatorByte) - } - return Fingerprint(sum) -} - -// labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a -// faster and less allocation-heavy hash function, which is more susceptible to -// create hash collisions. Therefore, collision detection should be applied. -func labelSetToFastFingerprint(ls LabelSet) Fingerprint { - if len(ls) == 0 { - return Fingerprint(emptyLabelSignature) - } - - var result uint64 - for labelName, labelValue := range ls { - sum := hashNew() - sum = hashAdd(sum, string(labelName)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(labelValue)) - result ^= sum - } - return Fingerprint(result) -} - -// SignatureForLabels works like LabelsToSignature but takes a Metric as -// parameter (rather than a label map) and only includes the labels with the -// specified LabelNames into the signature calculation. The labels passed in -// will be sorted by this function. -func SignatureForLabels(m Metric, labels ...LabelName) uint64 { - if len(labels) == 0 { - return emptyLabelSignature - } - - sort.Sort(LabelNames(labels)) - - sum := hashNew() - for _, label := range labels { - sum = hashAdd(sum, string(label)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(m[label])) - sum = hashAddByte(sum, SeparatorByte) - } - return sum -} - -// SignatureWithoutLabels works like LabelsToSignature but takes a Metric as -// parameter (rather than a label map) and excludes the labels with any of the -// specified LabelNames from the signature calculation. -func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { - if len(m) == 0 { - return emptyLabelSignature - } - - labelNames := make(LabelNames, 0, len(m)) - for labelName := range m { - if _, exclude := labels[labelName]; !exclude { - labelNames = append(labelNames, labelName) - } - } - if len(labelNames) == 0 { - return emptyLabelSignature - } - sort.Sort(labelNames) - - sum := hashNew() - for _, labelName := range labelNames { - sum = hashAdd(sum, string(labelName)) - sum = hashAddByte(sum, SeparatorByte) - sum = hashAdd(sum, string(m[labelName])) - sum = hashAddByte(sum, SeparatorByte) - } - return sum -} diff --git a/vendor/github.com/prometheus/common/model/silence.go b/vendor/github.com/prometheus/common/model/silence.go deleted file mode 100644 index 8f91a9702e0c..000000000000 --- a/vendor/github.com/prometheus/common/model/silence.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "errors" - "fmt" - "regexp" - "time" -) - -// Matcher describes a matches the value of a given label. -type Matcher struct { - Name LabelName `json:"name"` - Value string `json:"value"` - IsRegex bool `json:"isRegex"` -} - -func (m *Matcher) UnmarshalJSON(b []byte) error { - type plain Matcher - if err := json.Unmarshal(b, (*plain)(m)); err != nil { - return err - } - - if len(m.Name) == 0 { - return errors.New("label name in matcher must not be empty") - } - if m.IsRegex { - if _, err := regexp.Compile(m.Value); err != nil { - return err - } - } - return nil -} - -// Validate returns true iff all fields of the matcher have valid values. -func (m *Matcher) Validate() error { - if !m.Name.IsValid() { - return fmt.Errorf("invalid name %q", m.Name) - } - if m.IsRegex { - if _, err := regexp.Compile(m.Value); err != nil { - return fmt.Errorf("invalid regular expression %q", m.Value) - } - } else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 { - return fmt.Errorf("invalid value %q", m.Value) - } - return nil -} - -// Silence defines the representation of a silence definition in the Prometheus -// eco-system. -type Silence struct { - ID uint64 `json:"id,omitempty"` - - Matchers []*Matcher `json:"matchers"` - - StartsAt time.Time `json:"startsAt"` - EndsAt time.Time `json:"endsAt"` - - CreatedAt time.Time `json:"createdAt,omitempty"` - CreatedBy string `json:"createdBy"` - Comment string `json:"comment,omitempty"` -} - -// Validate returns true iff all fields of the silence have valid values. -func (s *Silence) Validate() error { - if len(s.Matchers) == 0 { - return errors.New("at least one matcher required") - } - for _, m := range s.Matchers { - if err := m.Validate(); err != nil { - return fmt.Errorf("invalid matcher: %w", err) - } - } - if s.StartsAt.IsZero() { - return errors.New("start time missing") - } - if s.EndsAt.IsZero() { - return errors.New("end time missing") - } - if s.EndsAt.Before(s.StartsAt) { - return errors.New("start time must be before end time") - } - if s.CreatedBy == "" { - return errors.New("creator information missing") - } - if s.Comment == "" { - return errors.New("comment missing") - } - if s.CreatedAt.IsZero() { - return errors.New("creation timestamp missing") - } - return nil -} diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go deleted file mode 100644 index 1730b0fdc121..000000000000 --- a/vendor/github.com/prometheus/common/model/time.go +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "errors" - "fmt" - "math" - "strconv" - "strings" - "time" -) - -const ( - // MinimumTick is the minimum supported time resolution. This has to be - // at least time.Second in order for the code below to work. - minimumTick = time.Millisecond - // second is the Time duration equivalent to one second. - second = int64(time.Second / minimumTick) - // The number of nanoseconds per minimum tick. - nanosPerTick = int64(minimumTick / time.Nanosecond) - - // Earliest is the earliest Time representable. Handy for - // initializing a high watermark. - Earliest = Time(math.MinInt64) - // Latest is the latest Time representable. Handy for initializing - // a low watermark. - Latest = Time(math.MaxInt64) -) - -// Time is the number of milliseconds since the epoch -// (1970-01-01 00:00 UTC) excluding leap seconds. -type Time int64 - -// Interval describes an interval between two timestamps. -type Interval struct { - Start, End Time -} - -// Now returns the current time as a Time. -func Now() Time { - return TimeFromUnixNano(time.Now().UnixNano()) -} - -// TimeFromUnix returns the Time equivalent to the Unix Time t -// provided in seconds. -func TimeFromUnix(t int64) Time { - return Time(t * second) -} - -// TimeFromUnixNano returns the Time equivalent to the Unix Time -// t provided in nanoseconds. -func TimeFromUnixNano(t int64) Time { - return Time(t / nanosPerTick) -} - -// Equal reports whether two Times represent the same instant. -func (t Time) Equal(o Time) bool { - return t == o -} - -// Before reports whether the Time t is before o. -func (t Time) Before(o Time) bool { - return t < o -} - -// After reports whether the Time t is after o. -func (t Time) After(o Time) bool { - return t > o -} - -// Add returns the Time t + d. -func (t Time) Add(d time.Duration) Time { - return t + Time(d/minimumTick) -} - -// Sub returns the Duration t - o. -func (t Time) Sub(o Time) time.Duration { - return time.Duration(t-o) * minimumTick -} - -// Time returns the time.Time representation of t. -func (t Time) Time() time.Time { - return time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick) -} - -// Unix returns t as a Unix time, the number of seconds elapsed -// since January 1, 1970 UTC. -func (t Time) Unix() int64 { - return int64(t) / second -} - -// UnixNano returns t as a Unix time, the number of nanoseconds elapsed -// since January 1, 1970 UTC. -func (t Time) UnixNano() int64 { - return int64(t) * nanosPerTick -} - -// The number of digits after the dot. -var dotPrecision = int(math.Log10(float64(second))) - -// String returns a string representation of the Time. -func (t Time) String() string { - return strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64) -} - -// MarshalJSON implements the json.Marshaler interface. -func (t Time) MarshalJSON() ([]byte, error) { - return []byte(t.String()), nil -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (t *Time) UnmarshalJSON(b []byte) error { - p := strings.Split(string(b), ".") - switch len(p) { - case 1: - v, err := strconv.ParseInt(p[0], 10, 64) - if err != nil { - return err - } - *t = Time(v * second) - - case 2: - v, err := strconv.ParseInt(p[0], 10, 64) - if err != nil { - return err - } - v *= second - - prec := dotPrecision - len(p[1]) - if prec < 0 { - p[1] = p[1][:dotPrecision] - } else if prec > 0 { - p[1] += strings.Repeat("0", prec) - } - - va, err := strconv.ParseInt(p[1], 10, 32) - if err != nil { - return err - } - - // If the value was something like -0.1 the negative is lost in the - // parsing because of the leading zero, this ensures that we capture it. - if len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 { - *t = Time(v+va) * -1 - } else { - *t = Time(v + va) - } - - default: - return fmt.Errorf("invalid time %q", string(b)) - } - return nil -} - -// Duration wraps time.Duration. It is used to parse the custom duration format -// from YAML. -// This type should not propagate beyond the scope of input/output processing. -type Duration time.Duration - -// Set implements pflag/flag.Value. -func (d *Duration) Set(s string) error { - var err error - *d, err = ParseDuration(s) - return err -} - -// Type implements pflag.Value. -func (*Duration) Type() string { - return "duration" -} - -func isdigit(c byte) bool { return c >= '0' && c <= '9' } - -// Units are required to go in order from biggest to smallest. -// This guards against confusion from "1m1d" being 1 minute + 1 day, not 1 month + 1 day. -var unitMap = map[string]struct { - pos int - mult uint64 -}{ - "ms": {7, uint64(time.Millisecond)}, - "s": {6, uint64(time.Second)}, - "m": {5, uint64(time.Minute)}, - "h": {4, uint64(time.Hour)}, - "d": {3, uint64(24 * time.Hour)}, - "w": {2, uint64(7 * 24 * time.Hour)}, - "y": {1, uint64(365 * 24 * time.Hour)}, -} - -// ParseDuration parses a string into a time.Duration, assuming that a year -// always has 365d, a week always has 7d, and a day always has 24h. -// Negative durations are not supported. -func ParseDuration(s string) (Duration, error) { - switch s { - case "0": - // Allow 0 without a unit. - return 0, nil - case "": - return 0, errors.New("empty duration string") - } - - orig := s - var dur uint64 - lastUnitPos := 0 - - for s != "" { - if !isdigit(s[0]) { - return 0, fmt.Errorf("not a valid duration string: %q", orig) - } - // Consume [0-9]* - i := 0 - for ; i < len(s) && isdigit(s[i]); i++ { - } - v, err := strconv.ParseUint(s[:i], 10, 0) - if err != nil { - return 0, fmt.Errorf("not a valid duration string: %q", orig) - } - s = s[i:] - - // Consume unit. - for i = 0; i < len(s) && !isdigit(s[i]); i++ { - } - if i == 0 { - return 0, fmt.Errorf("not a valid duration string: %q", orig) - } - u := s[:i] - s = s[i:] - unit, ok := unitMap[u] - if !ok { - return 0, fmt.Errorf("unknown unit %q in duration %q", u, orig) - } - if unit.pos <= lastUnitPos { // Units must go in order from biggest to smallest. - return 0, fmt.Errorf("not a valid duration string: %q", orig) - } - lastUnitPos = unit.pos - // Check if the provided duration overflows time.Duration (> ~ 290years). - if v > 1<<63/unit.mult { - return 0, errors.New("duration out of range") - } - dur += v * unit.mult - if dur > 1<<63-1 { - return 0, errors.New("duration out of range") - } - } - - return Duration(dur), nil -} - -// ParseDurationAllowNegative is like ParseDuration but also accepts negative durations. -func ParseDurationAllowNegative(s string) (Duration, error) { - if s == "" || s[0] != '-' { - return ParseDuration(s) - } - - d, err := ParseDuration(s[1:]) - - return -d, err -} - -func (d Duration) String() string { - var ( - ms = int64(time.Duration(d) / time.Millisecond) - r = "" - sign = "" - ) - - if ms == 0 { - return "0s" - } - - if ms < 0 { - sign, ms = "-", -ms - } - - f := func(unit string, mult int64, exact bool) { - if exact && ms%mult != 0 { - return - } - if v := ms / mult; v > 0 { - r += fmt.Sprintf("%d%s", v, unit) - ms -= v * mult - } - } - - // Only format years and weeks if the remainder is zero, as it is often - // easier to read 90d than 12w6d. - f("y", 1000*60*60*24*365, true) - f("w", 1000*60*60*24*7, true) - - f("d", 1000*60*60*24, false) - f("h", 1000*60*60, false) - f("m", 1000*60, false) - f("s", 1000, false) - f("ms", 1, false) - - return sign + r -} - -// MarshalJSON implements the json.Marshaler interface. -func (d Duration) MarshalJSON() ([]byte, error) { - return json.Marshal(d.String()) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (d *Duration) UnmarshalJSON(bytes []byte) error { - var s string - if err := json.Unmarshal(bytes, &s); err != nil { - return err - } - dur, err := ParseDuration(s) - if err != nil { - return err - } - *d = dur - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (d *Duration) MarshalText() ([]byte, error) { - return []byte(d.String()), nil -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (d *Duration) UnmarshalText(text []byte) error { - var err error - *d, err = ParseDuration(string(text)) - return err -} - -// MarshalYAML implements the yaml.Marshaler interface. -func (d Duration) MarshalYAML() (interface{}, error) { - return d.String(), nil -} - -// UnmarshalYAML implements the yaml.Unmarshaler interface. -func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { - var s string - if err := unmarshal(&s); err != nil { - return err - } - dur, err := ParseDuration(s) - if err != nil { - return err - } - *d = dur - return nil -} diff --git a/vendor/github.com/prometheus/common/model/value.go b/vendor/github.com/prometheus/common/model/value.go deleted file mode 100644 index a9995a37eeea..000000000000 --- a/vendor/github.com/prometheus/common/model/value.go +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "fmt" - "sort" - "strconv" - "strings" -) - -// ZeroSample is the pseudo zero-value of Sample used to signal a -// non-existing sample. It is a Sample with timestamp Earliest, value 0.0, -// and metric nil. Note that the natural zero value of Sample has a timestamp -// of 0, which is possible to appear in a real Sample and thus not suitable -// to signal a non-existing Sample. -var ZeroSample = Sample{Timestamp: Earliest} - -// Sample is a sample pair associated with a metric. A single sample must either -// define Value or Histogram but not both. Histogram == nil implies the Value -// field is used, otherwise it should be ignored. -type Sample struct { - Metric Metric `json:"metric"` - Value SampleValue `json:"value"` - Timestamp Time `json:"timestamp"` - Histogram *SampleHistogram `json:"histogram"` -} - -// Equal compares first the metrics, then the timestamp, then the value. The -// semantics of value equality is defined by SampleValue.Equal. -func (s *Sample) Equal(o *Sample) bool { - if s == o { - return true - } - - if !s.Metric.Equal(o.Metric) { - return false - } - if !s.Timestamp.Equal(o.Timestamp) { - return false - } - if s.Histogram != nil { - return s.Histogram.Equal(o.Histogram) - } - return s.Value.Equal(o.Value) -} - -func (s Sample) String() string { - if s.Histogram != nil { - return fmt.Sprintf("%s => %s", s.Metric, SampleHistogramPair{ - Timestamp: s.Timestamp, - Histogram: s.Histogram, - }) - } - return fmt.Sprintf("%s => %s", s.Metric, SamplePair{ - Timestamp: s.Timestamp, - Value: s.Value, - }) -} - -// MarshalJSON implements json.Marshaler. -func (s Sample) MarshalJSON() ([]byte, error) { - if s.Histogram != nil { - v := struct { - Metric Metric `json:"metric"` - Histogram SampleHistogramPair `json:"histogram"` - }{ - Metric: s.Metric, - Histogram: SampleHistogramPair{ - Timestamp: s.Timestamp, - Histogram: s.Histogram, - }, - } - return json.Marshal(&v) - } - v := struct { - Metric Metric `json:"metric"` - Value SamplePair `json:"value"` - }{ - Metric: s.Metric, - Value: SamplePair{ - Timestamp: s.Timestamp, - Value: s.Value, - }, - } - return json.Marshal(&v) -} - -// UnmarshalJSON implements json.Unmarshaler. -func (s *Sample) UnmarshalJSON(b []byte) error { - v := struct { - Metric Metric `json:"metric"` - Value SamplePair `json:"value"` - Histogram SampleHistogramPair `json:"histogram"` - }{ - Metric: s.Metric, - Value: SamplePair{ - Timestamp: s.Timestamp, - Value: s.Value, - }, - Histogram: SampleHistogramPair{ - Timestamp: s.Timestamp, - Histogram: s.Histogram, - }, - } - - if err := json.Unmarshal(b, &v); err != nil { - return err - } - - s.Metric = v.Metric - if v.Histogram.Histogram != nil { - s.Timestamp = v.Histogram.Timestamp - s.Histogram = v.Histogram.Histogram - } else { - s.Timestamp = v.Value.Timestamp - s.Value = v.Value.Value - } - - return nil -} - -// Samples is a sortable Sample slice. It implements sort.Interface. -type Samples []*Sample - -func (s Samples) Len() int { - return len(s) -} - -// Less compares first the metrics, then the timestamp. -func (s Samples) Less(i, j int) bool { - switch { - case s[i].Metric.Before(s[j].Metric): - return true - case s[j].Metric.Before(s[i].Metric): - return false - case s[i].Timestamp.Before(s[j].Timestamp): - return true - default: - return false - } -} - -func (s Samples) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// Equal compares two sets of samples and returns true if they are equal. -func (s Samples) Equal(o Samples) bool { - if len(s) != len(o) { - return false - } - - for i, sample := range s { - if !sample.Equal(o[i]) { - return false - } - } - return true -} - -// SampleStream is a stream of Values belonging to an attached COWMetric. -type SampleStream struct { - Metric Metric `json:"metric"` - Values []SamplePair `json:"values"` - Histograms []SampleHistogramPair `json:"histograms"` -} - -func (ss SampleStream) String() string { - valuesLength := len(ss.Values) - vals := make([]string, valuesLength+len(ss.Histograms)) - for i, v := range ss.Values { - vals[i] = v.String() - } - for i, v := range ss.Histograms { - vals[i+valuesLength] = v.String() - } - return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n")) -} - -func (ss SampleStream) MarshalJSON() ([]byte, error) { - switch { - case len(ss.Histograms) > 0 && len(ss.Values) > 0: - v := struct { - Metric Metric `json:"metric"` - Values []SamplePair `json:"values"` - Histograms []SampleHistogramPair `json:"histograms"` - }{ - Metric: ss.Metric, - Values: ss.Values, - Histograms: ss.Histograms, - } - return json.Marshal(&v) - case len(ss.Histograms) > 0: - v := struct { - Metric Metric `json:"metric"` - Histograms []SampleHistogramPair `json:"histograms"` - }{ - Metric: ss.Metric, - Histograms: ss.Histograms, - } - return json.Marshal(&v) - default: - v := struct { - Metric Metric `json:"metric"` - Values []SamplePair `json:"values"` - }{ - Metric: ss.Metric, - Values: ss.Values, - } - return json.Marshal(&v) - } -} - -func (ss *SampleStream) UnmarshalJSON(b []byte) error { - v := struct { - Metric Metric `json:"metric"` - Values []SamplePair `json:"values"` - Histograms []SampleHistogramPair `json:"histograms"` - }{ - Metric: ss.Metric, - Values: ss.Values, - Histograms: ss.Histograms, - } - - if err := json.Unmarshal(b, &v); err != nil { - return err - } - - ss.Metric = v.Metric - ss.Values = v.Values - ss.Histograms = v.Histograms - - return nil -} - -// Scalar is a scalar value evaluated at the set timestamp. -type Scalar struct { - Value SampleValue `json:"value"` - Timestamp Time `json:"timestamp"` -} - -func (s Scalar) String() string { - return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp) -} - -// MarshalJSON implements json.Marshaler. -func (s Scalar) MarshalJSON() ([]byte, error) { - v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64) - return json.Marshal([...]interface{}{s.Timestamp, v}) -} - -// UnmarshalJSON implements json.Unmarshaler. -func (s *Scalar) UnmarshalJSON(b []byte) error { - var f string - v := [...]interface{}{&s.Timestamp, &f} - - if err := json.Unmarshal(b, &v); err != nil { - return err - } - - value, err := strconv.ParseFloat(f, 64) - if err != nil { - return fmt.Errorf("error parsing sample value: %w", err) - } - s.Value = SampleValue(value) - return nil -} - -// String is a string value evaluated at the set timestamp. -type String struct { - Value string `json:"value"` - Timestamp Time `json:"timestamp"` -} - -func (s *String) String() string { - return s.Value -} - -// MarshalJSON implements json.Marshaler. -func (s String) MarshalJSON() ([]byte, error) { - return json.Marshal([]interface{}{s.Timestamp, s.Value}) -} - -// UnmarshalJSON implements json.Unmarshaler. -func (s *String) UnmarshalJSON(b []byte) error { - v := [...]interface{}{&s.Timestamp, &s.Value} - return json.Unmarshal(b, &v) -} - -// Vector is basically only an alias for Samples, but the -// contract is that in a Vector, all Samples have the same timestamp. -type Vector []*Sample - -func (vec Vector) String() string { - entries := make([]string, len(vec)) - for i, s := range vec { - entries[i] = s.String() - } - return strings.Join(entries, "\n") -} - -func (vec Vector) Len() int { return len(vec) } -func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] } - -// Less compares first the metrics, then the timestamp. -func (vec Vector) Less(i, j int) bool { - switch { - case vec[i].Metric.Before(vec[j].Metric): - return true - case vec[j].Metric.Before(vec[i].Metric): - return false - case vec[i].Timestamp.Before(vec[j].Timestamp): - return true - default: - return false - } -} - -// Equal compares two sets of samples and returns true if they are equal. -func (vec Vector) Equal(o Vector) bool { - if len(vec) != len(o) { - return false - } - - for i, sample := range vec { - if !sample.Equal(o[i]) { - return false - } - } - return true -} - -// Matrix is a list of time series. -type Matrix []*SampleStream - -func (m Matrix) Len() int { return len(m) } -func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) } -func (m Matrix) Swap(i, j int) { m[i], m[j] = m[j], m[i] } - -func (m Matrix) String() string { - matCp := make(Matrix, len(m)) - copy(matCp, m) - sort.Sort(matCp) - - strs := make([]string, len(matCp)) - - for i, ss := range matCp { - strs[i] = ss.String() - } - - return strings.Join(strs, "\n") -} diff --git a/vendor/github.com/prometheus/common/model/value_float.go b/vendor/github.com/prometheus/common/model/value_float.go deleted file mode 100644 index 6bfc757d18b0..000000000000 --- a/vendor/github.com/prometheus/common/model/value_float.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "errors" - "fmt" - "math" - "strconv" -) - -// ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a -// non-existing sample pair. It is a SamplePair with timestamp Earliest and -// value 0.0. Note that the natural zero value of SamplePair has a timestamp -// of 0, which is possible to appear in a real SamplePair and thus not -// suitable to signal a non-existing SamplePair. -var ZeroSamplePair = SamplePair{Timestamp: Earliest} - -// A SampleValue is a representation of a value for a given sample at a given -// time. -type SampleValue float64 - -// MarshalJSON implements json.Marshaler. -func (v SampleValue) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalJSON implements json.Unmarshaler. -func (v *SampleValue) UnmarshalJSON(b []byte) error { - if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { - return errors.New("sample value must be a quoted string") - } - f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) - if err != nil { - return err - } - *v = SampleValue(f) - return nil -} - -// Equal returns true if the value of v and o is equal or if both are NaN. Note -// that v==o is false if both are NaN. If you want the conventional float -// behavior, use == to compare two SampleValues. -func (v SampleValue) Equal(o SampleValue) bool { - if v == o { - return true - } - return math.IsNaN(float64(v)) && math.IsNaN(float64(o)) -} - -func (v SampleValue) String() string { - return strconv.FormatFloat(float64(v), 'f', -1, 64) -} - -// SamplePair pairs a SampleValue with a Timestamp. -type SamplePair struct { - Timestamp Time - Value SampleValue -} - -func (s SamplePair) MarshalJSON() ([]byte, error) { - t, err := json.Marshal(s.Timestamp) - if err != nil { - return nil, err - } - v, err := json.Marshal(s.Value) - if err != nil { - return nil, err - } - return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (s *SamplePair) UnmarshalJSON(b []byte) error { - v := [...]json.Unmarshaler{&s.Timestamp, &s.Value} - return json.Unmarshal(b, &v) -} - -// Equal returns true if this SamplePair and o have equal Values and equal -// Timestamps. The semantics of Value equality is defined by SampleValue.Equal. -func (s *SamplePair) Equal(o *SamplePair) bool { - return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp)) -} - -func (s SamplePair) String() string { - return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp) -} diff --git a/vendor/github.com/prometheus/common/model/value_histogram.go b/vendor/github.com/prometheus/common/model/value_histogram.go deleted file mode 100644 index 91ce5b7a45c2..000000000000 --- a/vendor/github.com/prometheus/common/model/value_histogram.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "errors" - "fmt" - "strconv" - "strings" -) - -type FloatString float64 - -func (v FloatString) String() string { - return strconv.FormatFloat(float64(v), 'f', -1, 64) -} - -func (v FloatString) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -func (v *FloatString) UnmarshalJSON(b []byte) error { - if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { - return errors.New("float value must be a quoted string") - } - f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) - if err != nil { - return err - } - *v = FloatString(f) - return nil -} - -type HistogramBucket struct { - Boundaries int32 - Lower FloatString - Upper FloatString - Count FloatString -} - -func (s HistogramBucket) MarshalJSON() ([]byte, error) { - b, err := json.Marshal(s.Boundaries) - if err != nil { - return nil, err - } - l, err := json.Marshal(s.Lower) - if err != nil { - return nil, err - } - u, err := json.Marshal(s.Upper) - if err != nil { - return nil, err - } - c, err := json.Marshal(s.Count) - if err != nil { - return nil, err - } - return []byte(fmt.Sprintf("[%s,%s,%s,%s]", b, l, u, c)), nil -} - -func (s *HistogramBucket) UnmarshalJSON(buf []byte) error { - tmp := []interface{}{&s.Boundaries, &s.Lower, &s.Upper, &s.Count} - wantLen := len(tmp) - if err := json.Unmarshal(buf, &tmp); err != nil { - return err - } - if gotLen := len(tmp); gotLen != wantLen { - return fmt.Errorf("wrong number of fields: %d != %d", gotLen, wantLen) - } - return nil -} - -func (s *HistogramBucket) Equal(o *HistogramBucket) bool { - return s == o || (s.Boundaries == o.Boundaries && s.Lower == o.Lower && s.Upper == o.Upper && s.Count == o.Count) -} - -func (s HistogramBucket) String() string { - var sb strings.Builder - lowerInclusive := s.Boundaries == 1 || s.Boundaries == 3 - upperInclusive := s.Boundaries == 0 || s.Boundaries == 3 - if lowerInclusive { - sb.WriteRune('[') - } else { - sb.WriteRune('(') - } - fmt.Fprintf(&sb, "%g,%g", s.Lower, s.Upper) - if upperInclusive { - sb.WriteRune(']') - } else { - sb.WriteRune(')') - } - fmt.Fprintf(&sb, ":%v", s.Count) - return sb.String() -} - -type HistogramBuckets []*HistogramBucket - -func (s HistogramBuckets) Equal(o HistogramBuckets) bool { - if len(s) != len(o) { - return false - } - - for i, bucket := range s { - if !bucket.Equal(o[i]) { - return false - } - } - return true -} - -type SampleHistogram struct { - Count FloatString `json:"count"` - Sum FloatString `json:"sum"` - Buckets HistogramBuckets `json:"buckets"` -} - -func (s SampleHistogram) String() string { - return fmt.Sprintf("Count: %f, Sum: %f, Buckets: %v", s.Count, s.Sum, s.Buckets) -} - -func (s *SampleHistogram) Equal(o *SampleHistogram) bool { - return s == o || (s.Count == o.Count && s.Sum == o.Sum && s.Buckets.Equal(o.Buckets)) -} - -type SampleHistogramPair struct { - Timestamp Time - // Histogram should never be nil, it's only stored as pointer for efficiency. - Histogram *SampleHistogram -} - -func (s SampleHistogramPair) MarshalJSON() ([]byte, error) { - if s.Histogram == nil { - return nil, errors.New("histogram is nil") - } - t, err := json.Marshal(s.Timestamp) - if err != nil { - return nil, err - } - v, err := json.Marshal(s.Histogram) - if err != nil { - return nil, err - } - return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil -} - -func (s *SampleHistogramPair) UnmarshalJSON(buf []byte) error { - tmp := []interface{}{&s.Timestamp, &s.Histogram} - wantLen := len(tmp) - if err := json.Unmarshal(buf, &tmp); err != nil { - return err - } - if gotLen := len(tmp); gotLen != wantLen { - return fmt.Errorf("wrong number of fields: %d != %d", gotLen, wantLen) - } - if s.Histogram == nil { - return errors.New("histogram is null") - } - return nil -} - -func (s SampleHistogramPair) String() string { - return fmt.Sprintf("%s @[%s]", s.Histogram, s.Timestamp) -} - -func (s *SampleHistogramPair) Equal(o *SampleHistogramPair) bool { - return s == o || (s.Histogram.Equal(o.Histogram) && s.Timestamp.Equal(o.Timestamp)) -} diff --git a/vendor/github.com/prometheus/common/model/value_type.go b/vendor/github.com/prometheus/common/model/value_type.go deleted file mode 100644 index 078910f46b73..000000000000 --- a/vendor/github.com/prometheus/common/model/value_type.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package model - -import ( - "encoding/json" - "fmt" -) - -// Value is a generic interface for values resulting from a query evaluation. -type Value interface { - Type() ValueType - String() string -} - -func (Matrix) Type() ValueType { return ValMatrix } -func (Vector) Type() ValueType { return ValVector } -func (*Scalar) Type() ValueType { return ValScalar } -func (*String) Type() ValueType { return ValString } - -type ValueType int - -const ( - ValNone ValueType = iota - ValScalar - ValVector - ValMatrix - ValString -) - -// MarshalJSON implements json.Marshaler. -func (et ValueType) MarshalJSON() ([]byte, error) { - return json.Marshal(et.String()) -} - -func (et *ValueType) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - switch s { - case "": - *et = ValNone - case "scalar": - *et = ValScalar - case "vector": - *et = ValVector - case "matrix": - *et = ValMatrix - case "string": - *et = ValString - default: - return fmt.Errorf("unknown value type %q", s) - } - return nil -} - -func (et ValueType) String() string { - switch et { - case ValNone: - return "" - case ValScalar: - return "scalar" - case ValVector: - return "vector" - case ValMatrix: - return "matrix" - case ValString: - return "string" - } - panic("ValueType.String: unhandled value type") -} diff --git a/vendor/github.com/prometheus/procfs/.gitignore b/vendor/github.com/prometheus/procfs/.gitignore deleted file mode 100644 index 7cc33ae4a704..000000000000 --- a/vendor/github.com/prometheus/procfs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/testdata/fixtures/ -/fixtures diff --git a/vendor/github.com/prometheus/procfs/.golangci.yml b/vendor/github.com/prometheus/procfs/.golangci.yml deleted file mode 100644 index eac920ba804e..000000000000 --- a/vendor/github.com/prometheus/procfs/.golangci.yml +++ /dev/null @@ -1,59 +0,0 @@ -version: "2" -linters: - enable: - - errorlint - - forbidigo - - gocritic - - godot - - misspell - - revive - - testifylint - settings: - forbidigo: - forbid: - - pattern: ^fmt\.Print.*$ - msg: Do not commit print statements. - gocritic: - enable-all: true - disabled-checks: - - commentFormatting - - commentedOutCode - - deferInLoop - - filepathJoin - - hugeParam - - importShadow - - paramTypeCombine - - rangeValCopy - - tooManyResultsChecker - - unnamedResult - - whyNoLint - godot: - exclude: - # Ignore "See: URL". - - 'See:' - capital: true - misspell: - locale: US - revive: - rules: - - name: var-naming - # TODO(SuperQ): See: https://github.com/prometheus/prometheus/issues/17766 - arguments: - - [] - - [] - - - skip-package-name-checks: true - exclusions: - presets: - - comments - - common-false-positives - - legacy - - std-error-handling - warn-unused: true -formatters: - enable: - - gofmt - - goimports - settings: - goimports: - local-prefixes: - - github.com/prometheus/procfs diff --git a/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md b/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md deleted file mode 100644 index d325872bdfad..000000000000 --- a/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,3 +0,0 @@ -# Prometheus Community Code of Conduct - -Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md b/vendor/github.com/prometheus/procfs/CONTRIBUTING.md deleted file mode 100644 index 853eb9d49b8b..000000000000 --- a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md +++ /dev/null @@ -1,121 +0,0 @@ -# Contributing - -Prometheus uses GitHub to manage reviews of pull requests. - -* If you are a new contributor see: [Steps to Contribute](#steps-to-contribute) - -* If you have a trivial fix or improvement, go ahead and create a pull request, - addressing (with `@...`) a suitable maintainer of this repository (see - [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request. - -* If you plan to do something more involved, first discuss your ideas - on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers). - This will avoid unnecessary work and surely give you and us a good deal - of inspiration. Also please see our [non-goals issue](https://github.com/prometheus/docs/issues/149) on areas that the Prometheus community doesn't plan to work on. - -* Relevant coding style guidelines are the [Go Code Review - Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments) - and the _Formatting and style_ section of Peter Bourgon's [Go: Best - Practices for Production - Environments](https://peter.bourgon.org/go-in-production/#formatting-and-style). - -* Be sure to sign off on the [DCO](https://github.com/probot/dco#how-it-works) - -## Steps to Contribute - -Should you wish to work on an issue, please claim it first by commenting on the GitHub issue that you want to work on it. This is to prevent duplicated efforts from contributors on the same issue. - -Please check the [`help-wanted`](https://github.com/prometheus/procfs/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) label to find issues that are good for getting started. If you have questions about one of the issues, with or without the tag, please comment on them and one of the maintainers will clarify it. For a quicker response, contact us over [IRC](https://prometheus.io/community). - -For quickly compiling and testing your changes do: -``` -make test # Make sure all the tests pass before you commit and push :) -``` - -We use [`golangci-lint`](https://github.com/golangci/golangci-lint) for linting the code. If it reports an issue and you think that the warning needs to be disregarded or is a false-positive, you can add a special comment `//nolint:linter1[,linter2,...]` before the offending line. Use this sparingly though, fixing the code to comply with the linter's recommendation is in general the preferred course of action. - -## Pull Request Checklist - -* Branch from the master branch and, if needed, rebase to the current master branch before submitting your pull request. If it doesn't merge cleanly with master you may be asked to rebase your changes. - -* Commits should be as small as possible, while ensuring that each commit is correct independently (i.e., each commit should compile and pass tests). - -* If your patch is not getting reviewed or you need a specific person to review it, you can @-reply a reviewer asking for a review in the pull request or a comment, or you can ask for a review on IRC channel [#prometheus](https://webchat.freenode.net/?channels=#prometheus) on irc.freenode.net (for the easiest start, [join via Riot](https://riot.im/app/#/room/#prometheus:matrix.org)). - -* Add tests relevant to the fixed bug or new feature. - -## Dependency management - -The Prometheus project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.12 or greater installed. - -All dependencies are vendored in the `vendor/` directory. - -To add or update a new dependency, use the `go get` command: - -```bash -# Pick the latest tagged release. -go get example.com/some/module/pkg - -# Pick a specific version. -go get example.com/some/module/pkg@vX.Y.Z -``` - -Tidy up the `go.mod` and `go.sum` files and copy the new/updated dependency to the `vendor/` directory: - - -```bash -# The GO111MODULE variable can be omitted when the code isn't located in GOPATH. -GO111MODULE=on go mod tidy - -GO111MODULE=on go mod vendor -``` - -You have to commit the changes to `go.mod`, `go.sum` and the `vendor/` directory before submitting the pull request. - - -## API Implementation Guidelines - -### Naming and Documentation - -Public functions and structs should normally be named according to the file(s) being read and parsed. For example, -the `fs.BuddyInfo()` function reads the file `/proc/buddyinfo`. In addition, the godoc for each public function -should contain the path to the file(s) being read and a URL of the linux kernel documentation describing the file(s). - -### Reading vs. Parsing - -Most functionality in this library consists of reading files and then parsing the text into structured data. In most -cases reading and parsing should be separated into different functions/methods with a public `fs.Thing()` method and -a private `parseThing(r Reader)` function. This provides a logical separation and allows parsing to be tested -directly without the need to read from the filesystem. Using a `Reader` argument is preferred over other data types -such as `string` or `*File` because it provides the most flexibility regarding the data source. When a set of files -in a directory needs to be parsed, then a `path` string parameter to the parse function can be used instead. - -### /proc and /sys filesystem I/O - -The `proc` and `sys` filesystems are pseudo file systems and work a bit differently from standard disk I/O. -Many of the files are changing continuously and the data being read can in some cases change between subsequent -reads in the same file. Also, most of the files are relatively small (less than a few KBs), and system calls -to the `stat` function will often return the wrong size. Therefore, for most files it's recommended to read the -full file in a single operation using an internal utility function called `util.ReadFileNoStat`. -This function is similar to `os.ReadFile`, but it avoids the system call to `stat` to get the current size of -the file. - -Note that parsing the file's contents can still be performed one line at a time. This is done by first reading -the full file, and then using a scanner on the `[]byte` or `string` containing the data. - -``` - data, err := util.ReadFileNoStat("/proc/cpuinfo") - if err != nil { - return err - } - reader := bytes.NewReader(data) - scanner := bufio.NewScanner(reader) -``` - -The `/sys` filesystem contains many very small files which contain only a single numeric or text value. These files -can be read using an internal function called `util.SysReadFile` which is similar to `os.ReadFile` but does -not bother to check the size of the file before reading. -``` - data, err := util.SysReadFile("/sys/class/power_supply/BAT0/capacity") -``` - diff --git a/vendor/github.com/prometheus/procfs/LICENSE b/vendor/github.com/prometheus/procfs/LICENSE deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/vendor/github.com/prometheus/procfs/LICENSE +++ /dev/null @@ -1,201 +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. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/prometheus/procfs/MAINTAINERS.md b/vendor/github.com/prometheus/procfs/MAINTAINERS.md deleted file mode 100644 index e00f3b365b62..000000000000 --- a/vendor/github.com/prometheus/procfs/MAINTAINERS.md +++ /dev/null @@ -1,3 +0,0 @@ -* Johannes 'fish' Ziemke @discordianfish -* Paul Gier @pgier -* Ben Kochie @SuperQ diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile deleted file mode 100644 index bce50a19c504..000000000000 --- a/vendor/github.com/prometheus/procfs/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright The Prometheus Authors -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -include Makefile.common - -%/.unpacked: %.ttar - @echo ">> extracting fixtures $*" - ./ttar -C $(dir $*) -x -f $*.ttar - touch $@ - -fixtures: testdata/fixtures/.unpacked - -update_fixtures: - rm -vf testdata/fixtures/.unpacked - ./ttar -c -f testdata/fixtures.ttar -C testdata/ fixtures/ - -.PHONY: build -build: - -.PHONY: test -test: testdata/fixtures/.unpacked common-test diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common deleted file mode 100644 index cce3ef1d165b..000000000000 --- a/vendor/github.com/prometheus/procfs/Makefile.common +++ /dev/null @@ -1,503 +0,0 @@ -# Copyright The Prometheus Authors -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# A common Makefile that includes rules to be reused in different prometheus projects. -# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository! - -# Example usage : -# Create the main Makefile in the root project directory. -# include Makefile.common -# customTarget: -# @echo ">> Running customTarget" -# - -# Ensure GOBIN is not set during build so that promu is installed to the correct path -unexport GOBIN - -GO ?= go -GOFMT ?= $(GO)fmt -FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) -GOOPTS ?= -GOHOSTOS ?= $(shell $(GO) env GOHOSTOS) -GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH) - -GO_VERSION ?= $(shell $(GO) version) -GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) -PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') - -PROMU := $(FIRST_GOPATH)/bin/promu -pkgs = ./... - -ifeq (arm, $(GOHOSTARCH)) - GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM) - GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM) -else - GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH) -endif - -GOTEST := $(GO) test -GOTEST_DIR := -ifneq ($(CIRCLE_JOB),) -ifneq ($(shell command -v gotestsum 2> /dev/null),) - GOTEST_DIR := test-results - GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml -- -endif -endif - -PROMU_VERSION ?= 0.18.0 -PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz - -SKIP_GOLANGCI_LINT := -GOLANGCI_LINT := -GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v2.10.1 -GOLANGCI_FMT_OPTS ?= -# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. -# windows isn't included here because of the path separator being different. -ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) - ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64)) - # If we're in CI and there is an Actions file, that means the linter - # is being run in Actions, so we don't need to run it here. - ifneq (,$(SKIP_GOLANGCI_LINT)) - GOLANGCI_LINT := - else ifeq (,$(CIRCLE_JOB)) - GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint - else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) - GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint - endif - endif -endif - -PREFIX ?= $(shell pwd) -BIN_DIR ?= $(shell pwd) -DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) -DOCKERBUILD_CONTEXT ?= ./ -DOCKER_REPO ?= prom - -# Check if deprecated DOCKERFILE_PATH is set -ifdef DOCKERFILE_PATH -$(error DOCKERFILE_PATH is deprecated. Use DOCKERFILE_VARIANTS ?= $(DOCKERFILE_PATH) in the Makefile) -endif - -DOCKER_ARCHS ?= amd64 -DOCKERFILE_VARIANTS ?= Dockerfile $(wildcard Dockerfile.*) - -# Function to extract variant from Dockerfile label. -# Returns the variant name from io.prometheus.image.variant label, or "default" if not found. -define dockerfile_variant -$(strip $(or $(shell sed -n 's/.*io\.prometheus\.image\.variant="\([^"]*\)".*/\1/p' $(1)),default)) -endef - -# Check for duplicate variant names (including default for Dockerfiles without labels). -DOCKERFILE_VARIANT_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df))) -DOCKERFILE_VARIANT_NAMES_SORTED := $(sort $(DOCKERFILE_VARIANT_NAMES)) -ifneq ($(words $(DOCKERFILE_VARIANT_NAMES)),$(words $(DOCKERFILE_VARIANT_NAMES_SORTED))) -$(error Duplicate variant names found. Each Dockerfile must have a unique io.prometheus.image.variant label, and only one can be without a label (default)) -endif - -# Build variant:dockerfile pairs for shell iteration. -DOCKERFILE_VARIANTS_WITH_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)):$(df)) - -# Shell helper to check whether a dockerfile/arch pair is excluded. -define dockerfile_arch_is_excluded -case " $(DOCKERFILE_ARCH_EXCLUSIONS) " in \ - *" $$dockerfile:$(1) "*) true ;; \ - *) false ;; \ -esac -endef - -# Shell helper to check whether a registry/arch pair is excluded. -# Extracts registry from DOCKER_REPO (e.g., quay.io/prometheus -> quay.io) -define registry_arch_is_excluded -registry=$$(echo "$(DOCKER_REPO)" | cut -d'/' -f1); \ -case " $(DOCKER_REGISTRY_ARCH_EXCLUSIONS) " in \ - *" $$registry:$(1) "*) true ;; \ - *) false ;; \ -esac -endef - -BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) -PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) -TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) - -SANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG)) - -ifeq ($(GOHOSTARCH),amd64) - ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) - # Only supported on amd64 - test-flags := -race - endif -endif - -# This rule is used to forward a target like "build" to "common-build". This -# allows a new "build" target to be defined in a Makefile which includes this -# one and override "common-build" without override warnings. -%: common-% ; - -.PHONY: common-all -common-all: precheck style check_license lint yamllint unused build test - -.PHONY: common-style -common-style: - @echo ">> checking code style" - @fmtRes=$$($(GOFMT) -d $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -name '*.go' -print)); \ - if [ -n "$${fmtRes}" ]; then \ - echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \ - echo "Please ensure you are using $$($(GO) version) for formatting code."; \ - exit 1; \ - fi - -.PHONY: common-check_license -common-check_license: - @echo ">> checking license header" - @licRes=$$(for file in $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -type f -iname '*.go' -print) ; do \ - awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \ - done); \ - if [ -n "$${licRes}" ]; then \ - echo "license header checking failed:"; echo "$${licRes}"; \ - exit 1; \ - fi - @echo ">> checking for copyright years 2026 or later" - @futureYearRes=$$(git grep -E 'Copyright (202[6-9]|20[3-9][0-9])' -- '*.go' ':!:vendor/*' || true); \ - if [ -n "$${futureYearRes}" ]; then \ - echo "Files with copyright year 2026 or later found (should use 'Copyright The Prometheus Authors'):"; echo "$${futureYearRes}"; \ - exit 1; \ - fi - -.PHONY: common-deps -common-deps: - @echo ">> getting dependencies" - $(GO) mod download - -.PHONY: update-go-deps -update-go-deps: - @echo ">> updating Go dependencies" - @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ - $(GO) get $$m; \ - done - $(GO) mod tidy - -.PHONY: common-test-short -common-test-short: $(GOTEST_DIR) - @echo ">> running short tests" - $(GOTEST) -short $(GOOPTS) $(pkgs) - -.PHONY: common-test -common-test: $(GOTEST_DIR) - @echo ">> running all tests" - $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) - -$(GOTEST_DIR): - @mkdir -p $@ - -.PHONY: common-format -common-format: $(GOLANGCI_LINT) - @echo ">> formatting code" - $(GO) fmt $(pkgs) -ifdef GOLANGCI_LINT - @echo ">> formatting code with golangci-lint" - $(GOLANGCI_LINT) fmt $(GOLANGCI_FMT_OPTS) -endif - -.PHONY: common-vet -common-vet: - @echo ">> vetting code" - $(GO) vet $(GOOPTS) $(pkgs) - -.PHONY: common-lint -common-lint: $(GOLANGCI_LINT) -ifdef GOLANGCI_LINT - @echo ">> running golangci-lint" - $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) -endif - -.PHONY: common-lint-fix -common-lint-fix: $(GOLANGCI_LINT) -ifdef GOLANGCI_LINT - @echo ">> running golangci-lint fix" - $(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs) -endif - -.PHONY: common-yamllint -common-yamllint: - @echo ">> running yamllint on all YAML files in the repository" -ifeq (, $(shell command -v yamllint 2> /dev/null)) - @echo "yamllint not installed so skipping" -else - yamllint . -endif - -# For backward-compatibility. -.PHONY: common-staticcheck -common-staticcheck: lint - -.PHONY: common-unused -common-unused: - @echo ">> running check for unused/missing packages in go.mod" - $(GO) mod tidy - @git diff --exit-code -- go.sum go.mod - -.PHONY: common-build -common-build: promu - @echo ">> building binaries" - $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) - -.PHONY: common-tarball -common-tarball: promu - @echo ">> building release tarball" - $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) - -.PHONY: common-docker-repo-name -common-docker-repo-name: - @echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)" - -.PHONY: common-docker $(BUILD_DOCKER_ARCHS) -common-docker: $(BUILD_DOCKER_ARCHS) -$(BUILD_DOCKER_ARCHS): common-docker-%: - @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ - dockerfile=$${variant#*:}; \ - variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping $$variant_name variant for linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - distroless_arch="$*"; \ - if [ "$*" = "armv7" ]; then \ - distroless_arch="arm"; \ - fi; \ - if [ "$$dockerfile" = "Dockerfile" ]; then \ - echo "Building default variant ($$variant_name) for linux-$* using $$dockerfile"; \ - docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \ - -f $$dockerfile \ - --build-arg ARCH="$*" \ - --build-arg OS="linux" \ - --build-arg DISTROLESS_ARCH="$$distroless_arch" \ - $(DOCKERBUILD_CONTEXT); \ - if [ "$$variant_name" != "default" ]; then \ - echo "Tagging default variant with $$variant_name suffix"; \ - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \ - "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ - fi; \ - else \ - echo "Building $$variant_name variant for linux-$* using $$dockerfile"; \ - docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" \ - -f $$dockerfile \ - --build-arg ARCH="$*" \ - --build-arg OS="linux" \ - --build-arg DISTROLESS_ARCH="$$distroless_arch" \ - $(DOCKERBUILD_CONTEXT); \ - fi; \ - done - -.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS) -common-docker-publish: $(PUBLISH_DOCKER_ARCHS) -$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: - @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ - dockerfile=$${variant#*:}; \ - variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping push for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$*); then \ - echo "Skipping push for $$variant_name variant on linux-$* to $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ - echo "Pushing $$variant_name variant for linux-$*"; \ - docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ - fi; \ - if [ "$$dockerfile" = "Dockerfile" ]; then \ - echo "Pushing default variant ($$variant_name) for linux-$*"; \ - docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)"; \ - fi; \ - if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \ - if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ - echo "Pushing $$variant_name variant version tags for linux-$*"; \ - docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \ - fi; \ - if [ "$$dockerfile" = "Dockerfile" ]; then \ - echo "Pushing default variant version tag for linux-$*"; \ - docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \ - fi; \ - fi; \ - done - -DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) -.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) -common-docker-tag-latest: $(TAG_DOCKER_ARCHS) -$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: - @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ - dockerfile=$${variant#*:}; \ - variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping tag for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$*); then \ - echo "Skipping tag for $$variant_name variant on linux-$* for $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ - echo "Tagging $$variant_name variant for linux-$* as latest"; \ - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest-$$variant_name"; \ - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \ - fi; \ - if [ "$$dockerfile" = "Dockerfile" ]; then \ - echo "Tagging default variant ($$variant_name) for linux-$* as latest"; \ - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"; \ - docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \ - fi; \ - done - -.PHONY: common-docker-manifest -common-docker-manifest: - @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ - dockerfile=$${variant#*:}; \ - variant_name=$${variant%%:*}; \ - if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ - echo "Creating manifest for $$variant_name variant"; \ - refs=""; \ - for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ - done; \ - if [ -z "$$refs" ]; then \ - echo "Skipping manifest for $$variant_name variant (no supported architectures)"; \ - continue; \ - fi; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" $$refs; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ - fi; \ - if [ "$$dockerfile" = "Dockerfile" ]; then \ - echo "Creating default variant ($$variant_name) manifest"; \ - refs=""; \ - for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)"; \ - done; \ - if [ -z "$$refs" ]; then \ - echo "Skipping default variant manifest (no supported architectures)"; \ - continue; \ - fi; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $$refs; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)"; \ - fi; \ - if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \ - if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ - echo "Creating manifest for $$variant_name variant version tag"; \ - refs=""; \ - for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \ - done; \ - if [ -z "$$refs" ]; then \ - echo "Skipping version-tag manifest for $$variant_name variant (no supported architectures)"; \ - continue; \ - fi; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name" $$refs; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \ - fi; \ - if [ "$$dockerfile" = "Dockerfile" ]; then \ - echo "Creating default variant version tag manifest"; \ - refs=""; \ - for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)"; \ - done; \ - if [ -z "$$refs" ]; then \ - echo "Skipping default variant version-tag manifest (no supported architectures)"; \ - continue; \ - fi; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)" $$refs; \ - DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)"; \ - fi; \ - fi; \ - done - -.PHONY: promu -promu: $(PROMU) - -$(PROMU): - $(eval PROMU_TMP := $(shell mktemp -d)) - curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP) - mkdir -p $(FIRST_GOPATH)/bin - cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu - rm -r $(PROMU_TMP) - -.PHONY: common-proto -common-proto: - @echo ">> generating code from proto files" - @./scripts/genproto.sh - -ifdef GOLANGCI_LINT -$(GOLANGCI_LINT): - mkdir -p $(FIRST_GOPATH)/bin - curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \ - | sed -e '/install -d/d' \ - | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) -endif - -.PHONY: common-print-golangci-lint-version -common-print-golangci-lint-version: - @echo $(GOLANGCI_LINT_VERSION) - -.PHONY: precheck -precheck:: - -define PRECHECK_COMMAND_template = -precheck:: $(1)_precheck - -PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1))) -.PHONY: $(1)_precheck -$(1)_precheck: - @if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \ - echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \ - exit 1; \ - fi -endef - -govulncheck: install-govulncheck - govulncheck ./... - -install-govulncheck: - command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest diff --git a/vendor/github.com/prometheus/procfs/NOTICE b/vendor/github.com/prometheus/procfs/NOTICE deleted file mode 100644 index 53c5e9aa1112..000000000000 --- a/vendor/github.com/prometheus/procfs/NOTICE +++ /dev/null @@ -1,7 +0,0 @@ -procfs provides functions to retrieve system, kernel and process -metrics from the pseudo-filesystem proc. - -Copyright 2014-2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). diff --git a/vendor/github.com/prometheus/procfs/README.md b/vendor/github.com/prometheus/procfs/README.md deleted file mode 100644 index 0718239cf19a..000000000000 --- a/vendor/github.com/prometheus/procfs/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# procfs - -This package provides functions to retrieve system, kernel, and process -metrics from the pseudo-filesystems /proc and /sys. - -*WARNING*: This package is a work in progress. Its API may still break in -backwards-incompatible ways without warnings. Use it at your own risk. - -[![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/procfs.svg)](https://pkg.go.dev/github.com/prometheus/procfs) -[![CircleCI](https://circleci.com/gh/prometheus/procfs/tree/master.svg?style=svg)](https://circleci.com/gh/prometheus/procfs/tree/master) -[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs) - -## Usage - -The procfs library is organized by packages based on whether the gathered data is coming from -/proc, /sys, or both. Each package contains an `FS` type which represents the path to either /proc, -/sys, or both. For example, cpu statistics are gathered from -`/proc/stat` and are available via the root procfs package. First, the proc filesystem mount -point is initialized, and then the stat information is read. - -```go -fs, err := procfs.NewFS("/proc") -stats, err := fs.Stat() -``` - -Some sub-packages such as `blockdevice`, require access to both the proc and sys filesystems. - -```go - fs, err := blockdevice.NewFS("/proc", "/sys") - stats, err := fs.ProcDiskstats() -``` - -## Package Organization - -The packages in this project are organized according to (1) whether the data comes from the `/proc` or -`/sys` filesystem and (2) the type of information being retrieved. For example, most process information -can be gathered from the functions in the root `procfs` package. Information about block devices such as disk drives -is available in the `blockdevices` sub-package. - -## Building and Testing - -The procfs library is intended to be built as part of another application, so there are no distributable binaries. -However, most of the API includes unit tests which can be run with `make test`. - -### Updating Test Fixtures - -The procfs library includes a set of test fixtures which include many example files from -the `/proc` and `/sys` filesystems. These fixtures are included as a [ttar](https://github.com/ideaship/ttar) file -which is extracted automatically during testing. To add/update the test fixtures, first -ensure the `testdata/fixtures` directory is up to date by removing the existing directory and then -extracting the ttar file using `make testdata/fixtures/.unpacked` or just `make test`. - -```bash -rm -rf testdata/fixtures -make test -``` - -Next, make the required changes to the extracted files in the `testdata/fixtures` directory. When -the changes are complete, run `make update_fixtures` to create a new `fixtures.ttar` file -based on the updated `fixtures` directory. And finally, verify the changes using -`git diff testdata/fixtures.ttar`. diff --git a/vendor/github.com/prometheus/procfs/SECURITY.md b/vendor/github.com/prometheus/procfs/SECURITY.md deleted file mode 100644 index fed02d85c79e..000000000000 --- a/vendor/github.com/prometheus/procfs/SECURITY.md +++ /dev/null @@ -1,6 +0,0 @@ -# Reporting a security issue - -The Prometheus security policy, including how to report vulnerabilities, can be -found here: - - diff --git a/vendor/github.com/prometheus/procfs/arp.go b/vendor/github.com/prometheus/procfs/arp.go deleted file mode 100644 index 716bdef10909..000000000000 --- a/vendor/github.com/prometheus/procfs/arp.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "fmt" - "net" - "os" - "strconv" - "strings" -) - -// Learned from include/uapi/linux/if_arp.h. -const ( - // Completed entry (ha valid). - ATFComplete = 0x02 - // Permanent entry. - ATFPermanent = 0x04 - // Publish entry. - ATFPublish = 0x08 - // Has requested trailers. - ATFUseTrailers = 0x10 - // Obsoleted: Want to use a netmask (only for proxy entries). - ATFNetmask = 0x20 - // Don't answer this addresses. - ATFDontPublish = 0x40 -) - -// ARPEntry contains a single row of the columnar data represented in -// /proc/net/arp. -type ARPEntry struct { - // IP address - IPAddr net.IP - // MAC address - HWAddr net.HardwareAddr - // Name of the device - Device string - // Flags - Flags byte -} - -// GatherARPEntries retrieves all the ARP entries, parse the relevant columns, -// and then return a slice of ARPEntry's. -func (fs FS) GatherARPEntries() ([]ARPEntry, error) { - data, err := os.ReadFile(fs.proc.Path("net/arp")) - if err != nil { - return nil, fmt.Errorf("%w: error reading arp %s: %w", ErrFileRead, fs.proc.Path("net/arp"), err) - } - - return parseARPEntries(data) -} - -func parseARPEntries(data []byte) ([]ARPEntry, error) { - lines := strings.Split(string(data), "\n") - entries := make([]ARPEntry, 0) - var err error - const ( - expectedDataWidth = 6 - expectedHeaderWidth = 9 - ) - for _, line := range lines { - columns := strings.Fields(line) - width := len(columns) - - switch width { - case expectedHeaderWidth, 0: - continue - case expectedDataWidth: - entry, err := parseARPEntry(columns) - if err != nil { - return []ARPEntry{}, fmt.Errorf("%w: Failed to parse ARP entry: %v: %w", ErrFileParse, entry, err) - } - entries = append(entries, entry) - default: - return []ARPEntry{}, fmt.Errorf("%w: %d columns found, but expected %d: %w", ErrFileParse, width, expectedDataWidth, err) - } - - } - - return entries, err -} - -func parseARPEntry(columns []string) (ARPEntry, error) { - entry := ARPEntry{Device: columns[5]} - ip := net.ParseIP(columns[0]) - entry.IPAddr = ip - - if mac, err := net.ParseMAC(columns[3]); err == nil { - entry.HWAddr = mac - } else { - return ARPEntry{}, err - } - - if flags, err := strconv.ParseUint(columns[2], 0, 8); err == nil { - entry.Flags = byte(flags) - } else { - return ARPEntry{}, err - } - - return entry, nil -} - -// IsComplete returns true if ARP entry is marked with complete flag. -func (entry *ARPEntry) IsComplete() bool { - return entry.Flags&ATFComplete != 0 -} diff --git a/vendor/github.com/prometheus/procfs/buddyinfo.go b/vendor/github.com/prometheus/procfs/buddyinfo.go deleted file mode 100644 index 53243e687583..000000000000 --- a/vendor/github.com/prometheus/procfs/buddyinfo.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "fmt" - "io" - "os" - "strconv" - "strings" -) - -// A BuddyInfo is the details parsed from /proc/buddyinfo. -// The data is comprised of an array of free fragments of each size. -// The sizes are 2^n*PAGE_SIZE, where n is the array index. -type BuddyInfo struct { - Node string - Zone string - Sizes []float64 -} - -// BuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem. -func (fs FS) BuddyInfo() ([]BuddyInfo, error) { - file, err := os.Open(fs.proc.Path("buddyinfo")) - if err != nil { - return nil, err - } - defer file.Close() - - return parseBuddyInfo(file) -} - -func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) { - var ( - buddyInfo = []BuddyInfo{} - scanner = bufio.NewScanner(r) - bucketCount = -1 - ) - - for scanner.Scan() { - var err error - line := scanner.Text() - parts := strings.Fields(line) - - if len(parts) < 4 { - return nil, fmt.Errorf("%w: Invalid number of fields, found: %v", ErrFileParse, parts) - } - - node := strings.TrimSuffix(parts[1], ",") - zone := strings.TrimSuffix(parts[3], ",") - arraySize := len(parts[4:]) - - if bucketCount == -1 { - bucketCount = arraySize - } else if bucketCount != arraySize { - return nil, fmt.Errorf("%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d", ErrFileParse, bucketCount, arraySize) - } - - sizes := make([]float64, arraySize) - for i := range arraySize { - sizes[i], err = strconv.ParseFloat(parts[i+4], 64) - if err != nil { - return nil, fmt.Errorf("%w: Invalid valid in buddyinfo: %f: %w", ErrFileParse, sizes[i], err) - } - } - - buddyInfo = append(buddyInfo, BuddyInfo{node, zone, sizes}) - } - - return buddyInfo, scanner.Err() -} diff --git a/vendor/github.com/prometheus/procfs/cmdline.go b/vendor/github.com/prometheus/procfs/cmdline.go deleted file mode 100644 index 4f1cac1f0ac7..000000000000 --- a/vendor/github.com/prometheus/procfs/cmdline.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// CmdLine returns the command line of the kernel. -func (fs FS) CmdLine() ([]string, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("cmdline")) - if err != nil { - return nil, err - } - - return strings.Fields(string(data)), nil -} diff --git a/vendor/github.com/prometheus/procfs/cpuinfo.go b/vendor/github.com/prometheus/procfs/cpuinfo.go deleted file mode 100644 index 4b23d8d6b5bc..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo.go +++ /dev/null @@ -1,518 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux - -package procfs - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "regexp" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// CPUInfo contains general information about a system CPU found in /proc/cpuinfo. -type CPUInfo struct { - Processor uint - VendorID string - CPUFamily string - Model string - ModelName string - Stepping string - Microcode string - CPUMHz float64 - CacheSize string - PhysicalID string - Siblings uint - CoreID string - CPUCores uint - APICID string - InitialAPICID string - FPU string - FPUException string - CPUIDLevel uint - WP string - Flags []string - Bugs []string - BogoMips float64 - CLFlushSize uint - CacheAlignment uint - AddressSizes string - PowerManagement string -} - -var ( - cpuinfoClockRegexp = regexp.MustCompile(`([\d.]+)`) - cpuinfoS390XProcessorRegexp = regexp.MustCompile(`^processor\s+(\d+):.*`) -) - -// CPUInfo returns information about current system CPUs. -// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt -func (fs FS) CPUInfo() ([]CPUInfo, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("cpuinfo")) - if err != nil { - return nil, err - } - return parseCPUInfo(data) -} - -func parseCPUInfoX86(info []byte) ([]CPUInfo, error) { - scanner := bufio.NewScanner(bytes.NewReader(info)) - - // find the first "processor" line - firstLine := firstNonEmptyLine(scanner) - if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") { - return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, firstLine) - } - field := strings.SplitN(firstLine, ": ", 2) - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - firstcpu := CPUInfo{Processor: uint(v)} - cpuinfo := []CPUInfo{firstcpu} - i := 0 - - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "processor": - cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor - i++ - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].Processor = uint(v) - case "vendor", "vendor_id": - cpuinfo[i].VendorID = field[1] - case "cpu family": - cpuinfo[i].CPUFamily = field[1] - case "model": - cpuinfo[i].Model = field[1] - case "model name": - cpuinfo[i].ModelName = field[1] - case "stepping": - cpuinfo[i].Stepping = field[1] - case "microcode": - cpuinfo[i].Microcode = field[1] - case "cpu MHz": - v, err := strconv.ParseFloat(field[1], 64) - if err != nil { - return nil, err - } - cpuinfo[i].CPUMHz = v - case "cache size": - cpuinfo[i].CacheSize = field[1] - case "physical id": - cpuinfo[i].PhysicalID = field[1] - case "siblings": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].Siblings = uint(v) - case "core id": - cpuinfo[i].CoreID = field[1] - case "cpu cores": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].CPUCores = uint(v) - case "apicid": - cpuinfo[i].APICID = field[1] - case "initial apicid": - cpuinfo[i].InitialAPICID = field[1] - case "fpu": - cpuinfo[i].FPU = field[1] - case "fpu_exception": - cpuinfo[i].FPUException = field[1] - case "cpuid level": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].CPUIDLevel = uint(v) - case "wp": - cpuinfo[i].WP = field[1] - case "flags": - cpuinfo[i].Flags = strings.Fields(field[1]) - case "bugs": - cpuinfo[i].Bugs = strings.Fields(field[1]) - case "bogomips": - v, err := strconv.ParseFloat(field[1], 64) - if err != nil { - return nil, err - } - cpuinfo[i].BogoMips = v - case "clflush size": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].CLFlushSize = uint(v) - case "cache_alignment": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].CacheAlignment = uint(v) - case "address sizes": - cpuinfo[i].AddressSizes = field[1] - case "power management": - cpuinfo[i].PowerManagement = field[1] - } - } - return cpuinfo, nil -} - -func parseCPUInfoARM(info []byte) ([]CPUInfo, error) { - scanner := bufio.NewScanner(bytes.NewReader(info)) - - firstLine := firstNonEmptyLine(scanner) - match, err := regexp.MatchString("^[Pp]rocessor", firstLine) - if !match || !strings.Contains(firstLine, ":") { - return nil, fmt.Errorf("%w: Cannot parse line: %q: %w", ErrFileParse, firstLine, err) - - } - field := strings.SplitN(firstLine, ": ", 2) - cpuinfo := []CPUInfo{} - featuresLine := "" - commonCPUInfo := CPUInfo{} - i := 0 - if strings.TrimSpace(field[0]) == "Processor" { - commonCPUInfo = CPUInfo{ModelName: field[1]} - i = -1 - } else { - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - firstcpu := CPUInfo{Processor: uint(v)} - cpuinfo = []CPUInfo{firstcpu} - } - - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "processor": - cpuinfo = append(cpuinfo, commonCPUInfo) // start of the next processor - i++ - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].Processor = uint(v) - case "BogoMIPS": - if i == -1 { - cpuinfo = append(cpuinfo, commonCPUInfo) // There is only one processor - i++ - cpuinfo[i].Processor = 0 - } - v, err := strconv.ParseFloat(field[1], 64) - if err != nil { - return nil, err - } - cpuinfo[i].BogoMips = v - case "Features": - featuresLine = line - case "model name": - cpuinfo[i].ModelName = field[1] - } - } - fields := strings.SplitN(featuresLine, ": ", 2) - for i := range cpuinfo { - cpuinfo[i].Flags = strings.Fields(fields[1]) - } - return cpuinfo, nil - -} - -func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) { - scanner := bufio.NewScanner(bytes.NewReader(info)) - - firstLine := firstNonEmptyLine(scanner) - if !strings.HasPrefix(firstLine, "vendor_id") || !strings.Contains(firstLine, ":") { - return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, firstLine) - } - field := strings.SplitN(firstLine, ": ", 2) - cpuinfo := []CPUInfo{} - commonCPUInfo := CPUInfo{VendorID: field[1]} - - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "bogomips per cpu": - v, err := strconv.ParseFloat(field[1], 64) - if err != nil { - return nil, err - } - commonCPUInfo.BogoMips = v - case "features": - commonCPUInfo.Flags = strings.Fields(field[1]) - } - if strings.HasPrefix(line, "processor") { - match := cpuinfoS390XProcessorRegexp.FindStringSubmatch(line) - if len(match) < 2 { - return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine) - } - cpu := commonCPUInfo - v, err := strconv.ParseUint(match[1], 0, 32) - if err != nil { - return nil, err - } - cpu.Processor = uint(v) - cpuinfo = append(cpuinfo, cpu) - } - if strings.HasPrefix(line, "cpu number") { - break - } - } - - i := 0 - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "cpu number": - i++ - case "cpu MHz dynamic": - clock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1])) - v, err := strconv.ParseFloat(clock, 64) - if err != nil { - return nil, err - } - cpuinfo[i].CPUMHz = v - case "physical id": - cpuinfo[i].PhysicalID = field[1] - case "core id": - cpuinfo[i].CoreID = field[1] - case "cpu cores": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].CPUCores = uint(v) - case "siblings": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].Siblings = uint(v) - } - } - - return cpuinfo, nil -} - -func parseCPUInfoMips(info []byte) ([]CPUInfo, error) { - scanner := bufio.NewScanner(bytes.NewReader(info)) - - // find the first "processor" line - firstLine := firstNonEmptyLine(scanner) - if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") { - return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine) - } - field := strings.SplitN(firstLine, ": ", 2) - cpuinfo := []CPUInfo{} - systemType := field[1] - - i := 0 - - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "processor": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - i = int(v) - cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor - cpuinfo[i].Processor = uint(v) - cpuinfo[i].VendorID = systemType - case "cpu model": - cpuinfo[i].ModelName = field[1] - case "BogoMIPS": - v, err := strconv.ParseFloat(field[1], 64) - if err != nil { - return nil, err - } - cpuinfo[i].BogoMips = v - } - } - return cpuinfo, nil -} - -func parseCPUInfoLoong(info []byte) ([]CPUInfo, error) { - scanner := bufio.NewScanner(bytes.NewReader(info)) - // find the first "processor" line - firstLine := firstNonEmptyLine(scanner) - if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") { - return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine) - } - field := strings.SplitN(firstLine, ": ", 2) - cpuinfo := []CPUInfo{} - systemType := field[1] - i := 0 - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "processor": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - i = int(v) - cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor - cpuinfo[i].Processor = uint(v) - cpuinfo[i].VendorID = systemType - case "CPU Family": - cpuinfo[i].CPUFamily = field[1] - case "Model Name": - cpuinfo[i].ModelName = field[1] - } - } - return cpuinfo, nil -} - -func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) { - scanner := bufio.NewScanner(bytes.NewReader(info)) - - firstLine := firstNonEmptyLine(scanner) - if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") { - return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine) - } - field := strings.SplitN(firstLine, ": ", 2) - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - firstcpu := CPUInfo{Processor: uint(v)} - cpuinfo := []CPUInfo{firstcpu} - i := 0 - - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "processor": - cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor - i++ - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - cpuinfo[i].Processor = uint(v) - case "cpu": - cpuinfo[i].VendorID = field[1] - case "clock": - clock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1])) - v, err := strconv.ParseFloat(clock, 64) - if err != nil { - return nil, err - } - cpuinfo[i].CPUMHz = v - } - } - return cpuinfo, nil -} - -func parseCPUInfoRISCV(info []byte) ([]CPUInfo, error) { - scanner := bufio.NewScanner(bytes.NewReader(info)) - - firstLine := firstNonEmptyLine(scanner) - if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") { - return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine) - } - field := strings.SplitN(firstLine, ": ", 2) - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - firstcpu := CPUInfo{Processor: uint(v)} - cpuinfo := []CPUInfo{firstcpu} - i := 0 - - for scanner.Scan() { - line := scanner.Text() - if !strings.Contains(line, ":") { - continue - } - field := strings.SplitN(line, ": ", 2) - switch strings.TrimSpace(field[0]) { - case "processor": - v, err := strconv.ParseUint(field[1], 0, 32) - if err != nil { - return nil, err - } - i = int(v) - cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor - cpuinfo[i].Processor = uint(v) - case "hart": - cpuinfo[i].CoreID = field[1] - case "isa": - cpuinfo[i].ModelName = field[1] - } - } - return cpuinfo, nil -} - -func parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { //nolint:unused - return nil, errors.New("not implemented") -} - -// firstNonEmptyLine advances the scanner to the first non-empty line -// and returns the contents of that line. -func firstNonEmptyLine(scanner *bufio.Scanner) string { - for scanner.Scan() { - line := scanner.Text() - if strings.TrimSpace(line) != "" { - return line - } - } - return "" -} diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go deleted file mode 100644 index b09035ff38be..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux && (arm || arm64) - -package procfs - -var parseCPUInfo = parseCPUInfoARM diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go deleted file mode 100644 index 7bb20211f993..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux - -package procfs - -var parseCPUInfo = parseCPUInfoLoong diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go deleted file mode 100644 index fd75d0f79d04..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux && (mips || mipsle || mips64 || mips64le) - -package procfs - -var parseCPUInfo = parseCPUInfoMips diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_others.go b/vendor/github.com/prometheus/procfs/cpuinfo_others.go deleted file mode 100644 index 3d36ba0e6bf2..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_others.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x - -package procfs - -var parseCPUInfo = parseCPUInfoDummy diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go deleted file mode 100644 index b3425051ef98..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux && (ppc64 || ppc64le) - -package procfs - -var parseCPUInfo = parseCPUInfoPPC diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go deleted file mode 100644 index 72598230c367..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux && (riscv || riscv64) - -package procfs - -var parseCPUInfo = parseCPUInfoRISCV diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go deleted file mode 100644 index 50a8239cbcba..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux - -package procfs - -var parseCPUInfo = parseCPUInfoS390X diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go deleted file mode 100644 index 00edb30a5c5c..000000000000 --- a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux && (386 || amd64) - -package procfs - -var parseCPUInfo = parseCPUInfoX86 diff --git a/vendor/github.com/prometheus/procfs/crypto.go b/vendor/github.com/prometheus/procfs/crypto.go deleted file mode 100644 index e4a5876eafbc..000000000000 --- a/vendor/github.com/prometheus/procfs/crypto.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Crypto holds info parsed from /proc/crypto. -type Crypto struct { - Alignmask *uint64 - Async bool - Blocksize *uint64 - Chunksize *uint64 - Ctxsize *uint64 - Digestsize *uint64 - Driver string - Geniv string - Internal string - Ivsize *uint64 - Maxauthsize *uint64 - MaxKeysize *uint64 - MinKeysize *uint64 - Module string - Name string - Priority *int64 - Refcnt *int64 - Seedsize *uint64 - Selftest string - Type string - Walksize *uint64 -} - -// Crypto parses an crypto-file (/proc/crypto) and returns a slice of -// structs containing the relevant info. More information available here: -// https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html -func (fs FS) Crypto() ([]Crypto, error) { - path := fs.proc.Path("crypto") - b, err := util.ReadFileNoStat(path) - if err != nil { - return nil, fmt.Errorf("%w: Cannot read file %v: %w", ErrFileRead, b, err) - - } - - crypto, err := parseCrypto(bytes.NewReader(b)) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse %v: %w", ErrFileParse, crypto, err) - } - - return crypto, nil -} - -// parseCrypto parses a /proc/crypto stream into Crypto elements. -func parseCrypto(r io.Reader) ([]Crypto, error) { - var out []Crypto - - s := bufio.NewScanner(r) - for s.Scan() { - text := s.Text() - switch { - case strings.HasPrefix(text, "name"): - // Each crypto element begins with its name. - out = append(out, Crypto{}) - case text == "": - continue - } - - kv := strings.Split(text, ":") - if len(kv) != 2 { - return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, text) - } - - k := strings.TrimSpace(kv[0]) - v := strings.TrimSpace(kv[1]) - - // Parse the key/value pair into the currently focused element. - c := &out[len(out)-1] - if err := c.parseKV(k, v); err != nil { - return nil, err - } - } - - if err := s.Err(); err != nil { - return nil, err - } - - return out, nil -} - -// parseKV parses a key/value pair into the appropriate field of c. -func (c *Crypto) parseKV(k, v string) error { - vp := util.NewValueParser(v) - - switch k { - case "async": - // Interpret literal yes as true. - c.Async = v == "yes" - case "blocksize": - c.Blocksize = vp.PUInt64() - case "chunksize": - c.Chunksize = vp.PUInt64() - case "digestsize": - c.Digestsize = vp.PUInt64() - case "driver": - c.Driver = v - case "geniv": - c.Geniv = v - case "internal": - c.Internal = v - case "ivsize": - c.Ivsize = vp.PUInt64() - case "maxauthsize": - c.Maxauthsize = vp.PUInt64() - case "max keysize": - c.MaxKeysize = vp.PUInt64() - case "min keysize": - c.MinKeysize = vp.PUInt64() - case "module": - c.Module = v - case "name": - c.Name = v - case "priority": - c.Priority = vp.PInt64() - case "refcnt": - c.Refcnt = vp.PInt64() - case "seedsize": - c.Seedsize = vp.PUInt64() - case "selftest": - c.Selftest = v - case "type": - c.Type = v - case "walksize": - c.Walksize = vp.PUInt64() - } - - return vp.Err() -} diff --git a/vendor/github.com/prometheus/procfs/doc.go b/vendor/github.com/prometheus/procfs/doc.go deleted file mode 100644 index 26bfea071bae..000000000000 --- a/vendor/github.com/prometheus/procfs/doc.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package procfs provides functions to retrieve system, kernel and process -// metrics from the pseudo-filesystem proc. -// -// Example: -// -// package main -// -// import ( -// "fmt" -// "log" -// -// "github.com/prometheus/procfs" -// ) -// -// func main() { -// p, err := procfs.Self() -// if err != nil { -// log.Fatalf("could not get process: %s", err) -// } -// -// stat, err := p.Stat() -// if err != nil { -// log.Fatalf("could not get process stat: %s", err) -// } -// -// fmt.Printf("command: %s\n", stat.Comm) -// fmt.Printf("cpu time: %fs\n", stat.CPUTime()) -// fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) -// fmt.Printf("rss: %dB\n", stat.ResidentMemory()) -// } -package procfs diff --git a/vendor/github.com/prometheus/procfs/fs.go b/vendor/github.com/prometheus/procfs/fs.go deleted file mode 100644 index 8f27912a13a5..000000000000 --- a/vendor/github.com/prometheus/procfs/fs.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "github.com/prometheus/procfs/internal/fs" -) - -// FS represents the pseudo-filesystem sys, which provides an interface to -// kernel data structures. -type FS struct { - proc fs.FS - isReal bool -} - -const ( - // DefaultMountPoint is the common mount point of the proc filesystem. - DefaultMountPoint = fs.DefaultProcMountPoint - - // SectorSize represents the size of a sector in bytes. - // It is specific to Linux block I/O operations. - SectorSize = 512 -) - -// NewDefaultFS returns a new proc FS mounted under the default proc mountPoint. -// It will error if the mount point directory can't be read or is a file. -func NewDefaultFS() (FS, error) { - return NewFS(DefaultMountPoint) -} - -// NewFS returns a new proc FS mounted under the given proc mountPoint. It will error -// if the mount point directory can't be read or is a file. -func NewFS(mountPoint string) (FS, error) { - fs, err := fs.NewFS(mountPoint) - if err != nil { - return FS{}, err - } - - isReal, err := isRealProc(mountPoint) - if err != nil { - return FS{}, err - } - - return FS{fs, isReal}, nil -} diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_notype.go b/vendor/github.com/prometheus/procfs/fs_statfs_notype.go deleted file mode 100644 index 0bef25bdd929..000000000000 --- a/vendor/github.com/prometheus/procfs/fs_statfs_notype.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !freebsd && !linux - -package procfs - -// isRealProc returns true on architectures that don't have a Type argument -// in their Statfs_t struct. -func isRealProc(_ string) (bool, error) { - return true, nil -} diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_type.go b/vendor/github.com/prometheus/procfs/fs_statfs_type.go deleted file mode 100644 index d1833303900e..000000000000 --- a/vendor/github.com/prometheus/procfs/fs_statfs_type.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build freebsd || linux - -package procfs - -import ( - "syscall" -) - -// isRealProc determines whether supplied mountpoint is really a proc filesystem. -func isRealProc(mountPoint string) (bool, error) { - stat := syscall.Statfs_t{} - err := syscall.Statfs(mountPoint, &stat) - if err != nil { - return false, err - } - - // 0x9fa0 is PROC_SUPER_MAGIC: https://elixir.bootlin.com/linux/v6.1/source/include/uapi/linux/magic.h#L87 - return stat.Type == 0x9fa0, nil -} diff --git a/vendor/github.com/prometheus/procfs/fscache.go b/vendor/github.com/prometheus/procfs/fscache.go deleted file mode 100644 index 9dde85707376..000000000000 --- a/vendor/github.com/prometheus/procfs/fscache.go +++ /dev/null @@ -1,423 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Fscacheinfo represents fscache statistics. -type Fscacheinfo struct { - // Number of index cookies allocated - IndexCookiesAllocated uint64 - // data storage cookies allocated - DataStorageCookiesAllocated uint64 - // Number of special cookies allocated - SpecialCookiesAllocated uint64 - // Number of objects allocated - ObjectsAllocated uint64 - // Number of object allocation failures - ObjectAllocationsFailure uint64 - // Number of objects that reached the available state - ObjectsAvailable uint64 - // Number of objects that reached the dead state - ObjectsDead uint64 - // Number of objects that didn't have a coherency check - ObjectsWithoutCoherencyCheck uint64 - // Number of objects that passed a coherency check - ObjectsWithCoherencyCheck uint64 - // Number of objects that needed a coherency data update - ObjectsNeedCoherencyCheckUpdate uint64 - // Number of objects that were declared obsolete - ObjectsDeclaredObsolete uint64 - // Number of pages marked as being cached - PagesMarkedAsBeingCached uint64 - // Number of uncache page requests seen - UncachePagesRequestSeen uint64 - // Number of acquire cookie requests seen - AcquireCookiesRequestSeen uint64 - // Number of acq reqs given a NULL parent - AcquireRequestsWithNullParent uint64 - // Number of acq reqs rejected due to no cache available - AcquireRequestsRejectedNoCacheAvailable uint64 - // Number of acq reqs succeeded - AcquireRequestsSucceeded uint64 - // Number of acq reqs rejected due to error - AcquireRequestsRejectedDueToError uint64 - // Number of acq reqs failed on ENOMEM - AcquireRequestsFailedDueToEnomem uint64 - // Number of lookup calls made on cache backends - LookupsNumber uint64 - // Number of negative lookups made - LookupsNegative uint64 - // Number of positive lookups made - LookupsPositive uint64 - // Number of objects created by lookup - ObjectsCreatedByLookup uint64 - // Number of lookups timed out and requeued - LookupsTimedOutAndRequed uint64 - InvalidationsNumber uint64 - InvalidationsRunning uint64 - // Number of update cookie requests seen - UpdateCookieRequestSeen uint64 - // Number of upd reqs given a NULL parent - UpdateRequestsWithNullParent uint64 - // Number of upd reqs granted CPU time - UpdateRequestsRunning uint64 - // Number of relinquish cookie requests seen - RelinquishCookiesRequestSeen uint64 - // Number of rlq reqs given a NULL parent - RelinquishCookiesWithNullParent uint64 - // Number of rlq reqs waited on completion of creation - RelinquishRequestsWaitingCompleteCreation uint64 - // Relinqs rtr - RelinquishRetries uint64 - // Number of attribute changed requests seen - AttributeChangedRequestsSeen uint64 - // Number of attr changed requests queued - AttributeChangedRequestsQueued uint64 - // Number of attr changed rejected -ENOBUFS - AttributeChangedRejectDueToEnobufs uint64 - // Number of attr changed failed -ENOMEM - AttributeChangedFailedDueToEnomem uint64 - // Number of attr changed ops given CPU time - AttributeChangedOps uint64 - // Number of allocation requests seen - AllocationRequestsSeen uint64 - // Number of successful alloc reqs - AllocationOkRequests uint64 - // Number of alloc reqs that waited on lookup completion - AllocationWaitingOnLookup uint64 - // Number of alloc reqs rejected -ENOBUFS - AllocationsRejectedDueToEnobufs uint64 - // Number of alloc reqs aborted -ERESTARTSYS - AllocationsAbortedDueToErestartsys uint64 - // Number of alloc reqs submitted - AllocationOperationsSubmitted uint64 - // Number of alloc reqs waited for CPU time - AllocationsWaitedForCPU uint64 - // Number of alloc reqs aborted due to object death - AllocationsAbortedDueToObjectDeath uint64 - // Number of retrieval (read) requests seen - RetrievalsReadRequests uint64 - // Number of successful retr reqs - RetrievalsOk uint64 - // Number of retr reqs that waited on lookup completion - RetrievalsWaitingLookupCompletion uint64 - // Number of retr reqs returned -ENODATA - RetrievalsReturnedEnodata uint64 - // Number of retr reqs rejected -ENOBUFS - RetrievalsRejectedDueToEnobufs uint64 - // Number of retr reqs aborted -ERESTARTSYS - RetrievalsAbortedDueToErestartsys uint64 - // Number of retr reqs failed -ENOMEM - RetrievalsFailedDueToEnomem uint64 - // Number of retr reqs submitted - RetrievalsRequests uint64 - // Number of retr reqs waited for CPU time - RetrievalsWaitingCPU uint64 - // Number of retr reqs aborted due to object death - RetrievalsAbortedDueToObjectDeath uint64 - // Number of storage (write) requests seen - StoreWriteRequests uint64 - // Number of successful store reqs - StoreSuccessfulRequests uint64 - // Number of store reqs on a page already pending storage - StoreRequestsOnPendingStorage uint64 - // Number of store reqs rejected -ENOBUFS - StoreRequestsRejectedDueToEnobufs uint64 - // Number of store reqs failed -ENOMEM - StoreRequestsFailedDueToEnomem uint64 - // Number of store reqs submitted - StoreRequestsSubmitted uint64 - // Number of store reqs granted CPU time - StoreRequestsRunning uint64 - // Number of pages given store req processing time - StorePagesWithRequestsProcessing uint64 - // Number of store reqs deleted from tracking tree - StoreRequestsDeleted uint64 - // Number of store reqs over store limit - StoreRequestsOverStoreLimit uint64 - // Number of release reqs against pages with no pending store - ReleaseRequestsAgainstPagesWithNoPendingStorage uint64 - // Number of release reqs against pages stored by time lock granted - ReleaseRequestsAgainstPagesStoredByTimeLockGranted uint64 - // Number of release reqs ignored due to in-progress store - ReleaseRequestsIgnoredDueToInProgressStore uint64 - // Number of page stores canceled due to release req - PageStoresCancelledByReleaseRequests uint64 - VmscanWaiting uint64 - // Number of times async ops added to pending queues - OpsPending uint64 - // Number of times async ops given CPU time - OpsRunning uint64 - // Number of times async ops queued for processing - OpsEnqueued uint64 - // Number of async ops canceled - OpsCancelled uint64 - // Number of async ops rejected due to object lookup/create failure - OpsRejected uint64 - // Number of async ops initialized - OpsInitialised uint64 - // Number of async ops queued for deferred release - OpsDeferred uint64 - // Number of async ops released (should equal ini=N when idle) - OpsReleased uint64 - // Number of deferred-release async ops garbage collected - OpsGarbageCollected uint64 - // Number of in-progress alloc_object() cache ops - CacheopAllocationsinProgress uint64 - // Number of in-progress lookup_object() cache ops - CacheopLookupObjectInProgress uint64 - // Number of in-progress lookup_complete() cache ops - CacheopLookupCompleteInPorgress uint64 - // Number of in-progress grab_object() cache ops - CacheopGrabObjectInProgress uint64 - CacheopInvalidations uint64 - // Number of in-progress update_object() cache ops - CacheopUpdateObjectInProgress uint64 - // Number of in-progress drop_object() cache ops - CacheopDropObjectInProgress uint64 - // Number of in-progress put_object() cache ops - CacheopPutObjectInProgress uint64 - // Number of in-progress attr_changed() cache ops - CacheopAttributeChangeInProgress uint64 - // Number of in-progress sync_cache() cache ops - CacheopSyncCacheInProgress uint64 - // Number of in-progress read_or_alloc_page() cache ops - CacheopReadOrAllocPageInProgress uint64 - // Number of in-progress read_or_alloc_pages() cache ops - CacheopReadOrAllocPagesInProgress uint64 - // Number of in-progress allocate_page() cache ops - CacheopAllocatePageInProgress uint64 - // Number of in-progress allocate_pages() cache ops - CacheopAllocatePagesInProgress uint64 - // Number of in-progress write_page() cache ops - CacheopWritePagesInProgress uint64 - // Number of in-progress uncache_page() cache ops - CacheopUncachePagesInProgress uint64 - // Number of in-progress dissociate_pages() cache ops - CacheopDissociatePagesInProgress uint64 - // Number of object lookups/creations rejected due to lack of space - CacheevLookupsAndCreationsRejectedLackSpace uint64 - // Number of stale objects deleted - CacheevStaleObjectsDeleted uint64 - // Number of objects retired when relinquished - CacheevRetiredWhenReliquished uint64 - // Number of objects culled - CacheevObjectsCulled uint64 -} - -// Fscacheinfo returns information about current fscache statistics. -// See https://www.kernel.org/doc/Documentation/filesystems/caching/fscache.txt -func (fs FS) Fscacheinfo() (Fscacheinfo, error) { - b, err := util.ReadFileNoStat(fs.proc.Path("fs/fscache/stats")) - if err != nil { - return Fscacheinfo{}, err - } - - m, err := parseFscacheinfo(bytes.NewReader(b)) - if err != nil { - return Fscacheinfo{}, fmt.Errorf("%w: Cannot parse %v: %w", ErrFileParse, m, err) - } - - return *m, nil -} - -func setFSCacheFields(fields []string, setFields ...*uint64) error { - var err error - if len(fields) < len(setFields) { - return fmt.Errorf("%w: Expected %d, but got %d: %w", ErrFileParse, len(setFields), len(fields), err) - } - - for i := range setFields { - *setFields[i], err = strconv.ParseUint(strings.Split(fields[i], "=")[1], 0, 64) - if err != nil { - return err - } - } - return nil -} - -func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) { - var m Fscacheinfo - s := bufio.NewScanner(r) - for s.Scan() { - fields := strings.Fields(s.Text()) - if len(fields) < 2 { - return nil, fmt.Errorf("%w: malformed Fscacheinfo line: %q", ErrFileParse, s.Text()) - } - - switch fields[0] { - case "Cookies:": - err := setFSCacheFields(fields[1:], &m.IndexCookiesAllocated, &m.DataStorageCookiesAllocated, - &m.SpecialCookiesAllocated) - if err != nil { - return &m, err - } - case "Objects:": - err := setFSCacheFields(fields[1:], &m.ObjectsAllocated, &m.ObjectAllocationsFailure, - &m.ObjectsAvailable, &m.ObjectsDead) - if err != nil { - return &m, err - } - case "ChkAux": - err := setFSCacheFields(fields[2:], &m.ObjectsWithoutCoherencyCheck, &m.ObjectsWithCoherencyCheck, - &m.ObjectsNeedCoherencyCheckUpdate, &m.ObjectsDeclaredObsolete) - if err != nil { - return &m, err - } - case "Pages": - err := setFSCacheFields(fields[2:], &m.PagesMarkedAsBeingCached, &m.UncachePagesRequestSeen) - if err != nil { - return &m, err - } - case "Acquire:": - err := setFSCacheFields(fields[1:], &m.AcquireCookiesRequestSeen, &m.AcquireRequestsWithNullParent, - &m.AcquireRequestsRejectedNoCacheAvailable, &m.AcquireRequestsSucceeded, &m.AcquireRequestsRejectedDueToError, - &m.AcquireRequestsFailedDueToEnomem) - if err != nil { - return &m, err - } - case "Lookups:": - err := setFSCacheFields(fields[1:], &m.LookupsNumber, &m.LookupsNegative, &m.LookupsPositive, - &m.ObjectsCreatedByLookup, &m.LookupsTimedOutAndRequed) - if err != nil { - return &m, err - } - case "Invals": - err := setFSCacheFields(fields[2:], &m.InvalidationsNumber, &m.InvalidationsRunning) - if err != nil { - return &m, err - } - case "Updates:": - err := setFSCacheFields(fields[1:], &m.UpdateCookieRequestSeen, &m.UpdateRequestsWithNullParent, - &m.UpdateRequestsRunning) - if err != nil { - return &m, err - } - case "Relinqs:": - err := setFSCacheFields(fields[1:], &m.RelinquishCookiesRequestSeen, &m.RelinquishCookiesWithNullParent, - &m.RelinquishRequestsWaitingCompleteCreation, &m.RelinquishRetries) - if err != nil { - return &m, err - } - case "AttrChg:": - err := setFSCacheFields(fields[1:], &m.AttributeChangedRequestsSeen, &m.AttributeChangedRequestsQueued, - &m.AttributeChangedRejectDueToEnobufs, &m.AttributeChangedFailedDueToEnomem, &m.AttributeChangedOps) - if err != nil { - return &m, err - } - case "Allocs": - if strings.Split(fields[2], "=")[0] == "n" { - err := setFSCacheFields(fields[2:], &m.AllocationRequestsSeen, &m.AllocationOkRequests, - &m.AllocationWaitingOnLookup, &m.AllocationsRejectedDueToEnobufs, &m.AllocationsAbortedDueToErestartsys) - if err != nil { - return &m, err - } - } else { - err := setFSCacheFields(fields[2:], &m.AllocationOperationsSubmitted, &m.AllocationsWaitedForCPU, - &m.AllocationsAbortedDueToObjectDeath) - if err != nil { - return &m, err - } - } - case "Retrvls:": - if strings.Split(fields[1], "=")[0] == "n" { - err := setFSCacheFields(fields[1:], &m.RetrievalsReadRequests, &m.RetrievalsOk, &m.RetrievalsWaitingLookupCompletion, - &m.RetrievalsReturnedEnodata, &m.RetrievalsRejectedDueToEnobufs, &m.RetrievalsAbortedDueToErestartsys, - &m.RetrievalsFailedDueToEnomem) - if err != nil { - return &m, err - } - } else { - err := setFSCacheFields(fields[1:], &m.RetrievalsRequests, &m.RetrievalsWaitingCPU, &m.RetrievalsAbortedDueToObjectDeath) - if err != nil { - return &m, err - } - } - case "Stores": - if strings.Split(fields[2], "=")[0] == "n" { - err := setFSCacheFields(fields[2:], &m.StoreWriteRequests, &m.StoreSuccessfulRequests, - &m.StoreRequestsOnPendingStorage, &m.StoreRequestsRejectedDueToEnobufs, &m.StoreRequestsFailedDueToEnomem) - if err != nil { - return &m, err - } - } else { - err := setFSCacheFields(fields[2:], &m.StoreRequestsSubmitted, &m.StoreRequestsRunning, - &m.StorePagesWithRequestsProcessing, &m.StoreRequestsDeleted, &m.StoreRequestsOverStoreLimit) - if err != nil { - return &m, err - } - } - case "VmScan": - err := setFSCacheFields(fields[2:], &m.ReleaseRequestsAgainstPagesWithNoPendingStorage, - &m.ReleaseRequestsAgainstPagesStoredByTimeLockGranted, &m.ReleaseRequestsIgnoredDueToInProgressStore, - &m.PageStoresCancelledByReleaseRequests, &m.VmscanWaiting) - if err != nil { - return &m, err - } - case "Ops": - if strings.Split(fields[2], "=")[0] == "pend" { - err := setFSCacheFields(fields[2:], &m.OpsPending, &m.OpsRunning, &m.OpsEnqueued, &m.OpsCancelled, &m.OpsRejected) - if err != nil { - return &m, err - } - } else { - err := setFSCacheFields(fields[2:], &m.OpsInitialised, &m.OpsDeferred, &m.OpsReleased, &m.OpsGarbageCollected) - if err != nil { - return &m, err - } - } - case "CacheOp:": - switch strings.Split(fields[1], "=")[0] { - case "alo": - err := setFSCacheFields(fields[1:], &m.CacheopAllocationsinProgress, &m.CacheopLookupObjectInProgress, - &m.CacheopLookupCompleteInPorgress, &m.CacheopGrabObjectInProgress) - if err != nil { - return &m, err - } - case "inv": - err := setFSCacheFields(fields[1:], &m.CacheopInvalidations, &m.CacheopUpdateObjectInProgress, - &m.CacheopDropObjectInProgress, &m.CacheopPutObjectInProgress, &m.CacheopAttributeChangeInProgress, - &m.CacheopSyncCacheInProgress) - if err != nil { - return &m, err - } - default: - err := setFSCacheFields(fields[1:], &m.CacheopReadOrAllocPageInProgress, &m.CacheopReadOrAllocPagesInProgress, - &m.CacheopAllocatePageInProgress, &m.CacheopAllocatePagesInProgress, &m.CacheopWritePagesInProgress, - &m.CacheopUncachePagesInProgress, &m.CacheopDissociatePagesInProgress) - if err != nil { - return &m, err - } - } - case "CacheEv:": - err := setFSCacheFields(fields[1:], &m.CacheevLookupsAndCreationsRejectedLackSpace, &m.CacheevStaleObjectsDeleted, - &m.CacheevRetiredWhenReliquished, &m.CacheevObjectsCulled) - if err != nil { - return &m, err - } - } - } - - return &m, nil -} diff --git a/vendor/github.com/prometheus/procfs/internal/fs/fs.go b/vendor/github.com/prometheus/procfs/internal/fs/fs.go deleted file mode 100644 index e7ccad66b2ed..000000000000 --- a/vendor/github.com/prometheus/procfs/internal/fs/fs.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package fs - -import ( - "fmt" - "os" - "path/filepath" -) - -const ( - // DefaultProcMountPoint is the common mount point of the proc filesystem. - DefaultProcMountPoint = "/proc" - - // DefaultSysMountPoint is the common mount point of the sys filesystem. - DefaultSysMountPoint = "/sys" - - // DefaultConfigfsMountPoint is the common mount point of the configfs. - DefaultConfigfsMountPoint = "/sys/kernel/config" - - // DefaultSelinuxMountPoint is the common mount point of the selinuxfs. - DefaultSelinuxMountPoint = "/sys/fs/selinux" -) - -// FS represents a pseudo-filesystem, normally /proc or /sys, which provides an -// interface to kernel data structures. -type FS string - -// NewFS returns a new FS mounted under the given mountPoint. It will error -// if the mount point can't be read. -func NewFS(mountPoint string) (FS, error) { - info, err := os.Stat(mountPoint) - if err != nil { - return "", fmt.Errorf("could not read %q: %w", mountPoint, err) - } - if !info.IsDir() { - return "", fmt.Errorf("mount point %q is not a directory", mountPoint) - } - - return FS(mountPoint), nil -} - -// Path appends the given path elements to the filesystem path, adding separators -// as necessary. -func (fs FS) Path(p ...string) string { - return filepath.Join(append([]string{string(fs)}, p...)...) -} diff --git a/vendor/github.com/prometheus/procfs/internal/util/parse.go b/vendor/github.com/prometheus/procfs/internal/util/parse.go deleted file mode 100644 index 30c5872019a9..000000000000 --- a/vendor/github.com/prometheus/procfs/internal/util/parse.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "errors" - "os" - "strconv" - "strings" -) - -// ParseUint32s parses a slice of strings into a slice of uint32s. -func ParseUint32s(ss []string) ([]uint32, error) { - us := make([]uint32, 0, len(ss)) - for _, s := range ss { - u, err := strconv.ParseUint(s, 10, 32) - if err != nil { - return nil, err - } - - us = append(us, uint32(u)) - } - - return us, nil -} - -// ParseUint64s parses a slice of strings into a slice of uint64s. -func ParseUint64s(ss []string) ([]uint64, error) { - us := make([]uint64, 0, len(ss)) - for _, s := range ss { - u, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return nil, err - } - - us = append(us, u) - } - - return us, nil -} - -// ParsePInt64s parses a slice of strings into a slice of int64 pointers. -func ParsePInt64s(ss []string) ([]*int64, error) { - us := make([]*int64, 0, len(ss)) - for _, s := range ss { - u, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return nil, err - } - - us = append(us, &u) - } - - return us, nil -} - -// Parses a uint64 from given hex in string. -func ParseHexUint64s(ss []string) ([]*uint64, error) { - us := make([]*uint64, 0, len(ss)) - for _, s := range ss { - u, err := strconv.ParseUint(s, 16, 64) - if err != nil { - return nil, err - } - - us = append(us, &u) - } - - return us, nil -} - -// ReadUintFromFile reads a file and attempts to parse a uint64 from it. -func ReadUintFromFile(path string) (uint64, error) { - data, err := os.ReadFile(path) - if err != nil { - return 0, err - } - return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) -} - -// ReadIntFromFile reads a file and attempts to parse a int64 from it. -func ReadIntFromFile(path string) (int64, error) { - data, err := os.ReadFile(path) - if err != nil { - return 0, err - } - return strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64) -} - -// ParseBool parses a string into a boolean pointer. -func ParseBool(b string) *bool { - var truth bool - switch b { - case "enabled": - truth = true - case "disabled": - truth = false - default: - return nil - } - return &truth -} - -// ReadHexFromFile reads a file and attempts to parse a uint64 from a hexadecimal format 0xXX. -func ReadHexFromFile(path string) (uint64, error) { - data, err := os.ReadFile(path) - if err != nil { - return 0, err - } - hexString := strings.TrimSpace(string(data)) - if !strings.HasPrefix(hexString, "0x") { - return 0, errors.New("invalid format: hex string does not start with '0x'") - } - return strconv.ParseUint(hexString[2:], 16, 64) -} diff --git a/vendor/github.com/prometheus/procfs/internal/util/readfile.go b/vendor/github.com/prometheus/procfs/internal/util/readfile.go deleted file mode 100644 index 0e41f71af189..000000000000 --- a/vendor/github.com/prometheus/procfs/internal/util/readfile.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "io" - "os" -) - -// ReadFileNoStat uses io.ReadAll to read contents of entire file. -// This is similar to os.ReadFile but without the call to os.Stat, because -// many files in /proc and /sys report incorrect file sizes (either 0 or 4096). -// Reads a max file size of 1024kB. For files larger than this, a scanner -// should be used. -func ReadFileNoStat(filename string) ([]byte, error) { - const maxBufferSize = 1024 * 1024 - - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - - reader := io.LimitReader(f, maxBufferSize) - return io.ReadAll(reader) -} diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go deleted file mode 100644 index f6a4a4de6270..000000000000 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build (linux || darwin) && !appengine - -package util - -import ( - "bytes" - "os" - "strconv" - "strings" - "syscall" -) - -// SysReadFile is a simplified os.ReadFile that invokes syscall.Read directly. -// https://github.com/prometheus/node_exporter/pull/728/files -// -// Note that this function will not read files larger than 128 bytes. -func SysReadFile(file string) (string, error) { - f, err := os.Open(file) - if err != nil { - return "", err - } - defer f.Close() - - // On some machines, hwmon drivers are broken and return EAGAIN. This causes - // Go's os.ReadFile implementation to poll forever. - // - // Since we either want to read data or bail immediately, do the simplest - // possible read using syscall directly. - const sysFileBufferSize = 128 - b := make([]byte, sysFileBufferSize) - n, err := syscall.Read(int(f.Fd()), b) - if err != nil { - return "", err - } - - return string(bytes.TrimSpace(b[:n])), nil -} - -// SysReadUintFromFile reads a file using SysReadFile and attempts to parse a uint64 from it. -func SysReadUintFromFile(path string) (uint64, error) { - data, err := SysReadFile(path) - if err != nil { - return 0, err - } - return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) -} - -// SysReadIntFromFile reads a file using SysReadFile and attempts to parse a int64 from it. -func SysReadIntFromFile(path string) (int64, error) { - data, err := SysReadFile(path) - if err != nil { - return 0, err - } - return strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64) -} diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go deleted file mode 100644 index c80e082cb9fc..000000000000 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build (linux && appengine) || (!linux && !darwin) - -package util - -import ( - "fmt" -) - -// SysReadFile is here implemented as a noop for builds that do not support -// the read syscall. For example Windows, or Linux on Google App Engine. -func SysReadFile(file string) (string, error) { - return "", fmt.Errorf("not supported on this platform") -} diff --git a/vendor/github.com/prometheus/procfs/internal/util/valueparser.go b/vendor/github.com/prometheus/procfs/internal/util/valueparser.go deleted file mode 100644 index e0ed671ea076..000000000000 --- a/vendor/github.com/prometheus/procfs/internal/util/valueparser.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "strconv" -) - -// TODO(mdlayher): util packages are an anti-pattern and this should be moved -// somewhere else that is more focused in the future. - -// A ValueParser enables parsing a single string into a variety of data types -// in a concise and safe way. The Err method must be invoked after invoking -// any other methods to ensure a value was successfully parsed. -type ValueParser struct { - v string - err error -} - -// NewValueParser creates a ValueParser using the input string. -func NewValueParser(v string) *ValueParser { - return &ValueParser{v: v} -} - -// Int interprets the underlying value as an int and returns that value. -func (vp *ValueParser) Int() int { return int(vp.int64()) } - -// PInt64 interprets the underlying value as an int64 and returns a pointer to -// that value. -func (vp *ValueParser) PInt64() *int64 { - if vp.err != nil { - return nil - } - - v := vp.int64() - return &v -} - -// int64 interprets the underlying value as an int64 and returns that value. -// TODO: export if/when necessary. -func (vp *ValueParser) int64() int64 { - if vp.err != nil { - return 0 - } - - // A base value of zero makes ParseInt infer the correct base using the - // string's prefix, if any. - const base = 0 - v, err := strconv.ParseInt(vp.v, base, 64) - if err != nil { - vp.err = err - return 0 - } - - return v -} - -// PUInt64 interprets the underlying value as an uint64 and returns a pointer to -// that value. -func (vp *ValueParser) PUInt64() *uint64 { - if vp.err != nil { - return nil - } - - // A base value of zero makes ParseInt infer the correct base using the - // string's prefix, if any. - const base = 0 - v, err := strconv.ParseUint(vp.v, base, 64) - if err != nil { - vp.err = err - return nil - } - - return &v -} - -// Err returns the last error, if any, encountered by the ValueParser. -func (vp *ValueParser) Err() error { - return vp.err -} diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go deleted file mode 100644 index 5374da9fa891..000000000000 --- a/vendor/github.com/prometheus/procfs/ipvs.go +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "encoding/hex" - "errors" - "fmt" - "io" - "net" - "os" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// IPVSStats holds IPVS statistics, as exposed by the kernel in `/proc/net/ip_vs_stats`. -type IPVSStats struct { - // Total count of connections. - Connections uint64 - // Total incoming packages processed. - IncomingPackets uint64 - // Total outgoing packages processed. - OutgoingPackets uint64 - // Total incoming traffic. - IncomingBytes uint64 - // Total outgoing traffic. - OutgoingBytes uint64 -} - -// IPVSBackendStatus holds current metrics of one virtual / real address pair. -type IPVSBackendStatus struct { - // The local (virtual) IP address. - LocalAddress net.IP - // The remote (real) IP address. - RemoteAddress net.IP - // The local (virtual) port. - LocalPort uint16 - // The remote (real) port. - RemotePort uint16 - // The local firewall mark - LocalMark string - // The transport protocol (TCP, UDP). - Proto string - // The current number of active connections for this virtual/real address pair. - ActiveConn uint64 - // The current number of inactive connections for this virtual/real address pair. - InactConn uint64 - // The current weight of this virtual/real address pair. - Weight uint64 -} - -// IPVSStats reads the IPVS statistics from the specified `proc` filesystem. -func (fs FS) IPVSStats() (IPVSStats, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("net/ip_vs_stats")) - if err != nil { - return IPVSStats{}, err - } - - return parseIPVSStats(bytes.NewReader(data)) -} - -// parseIPVSStats performs the actual parsing of `ip_vs_stats`. -func parseIPVSStats(r io.Reader) (IPVSStats, error) { - var ( - statContent []byte - statLines []string - statFields []string - stats IPVSStats - ) - - statContent, err := io.ReadAll(r) - if err != nil { - return IPVSStats{}, err - } - - statLines = strings.SplitN(string(statContent), "\n", 4) - if len(statLines) != 4 { - return IPVSStats{}, errors.New("ip_vs_stats corrupt: too short") - } - - statFields = strings.Fields(statLines[2]) - if len(statFields) != 5 { - return IPVSStats{}, errors.New("ip_vs_stats corrupt: unexpected number of fields") - } - - stats.Connections, err = strconv.ParseUint(statFields[0], 16, 64) - if err != nil { - return IPVSStats{}, err - } - stats.IncomingPackets, err = strconv.ParseUint(statFields[1], 16, 64) - if err != nil { - return IPVSStats{}, err - } - stats.OutgoingPackets, err = strconv.ParseUint(statFields[2], 16, 64) - if err != nil { - return IPVSStats{}, err - } - stats.IncomingBytes, err = strconv.ParseUint(statFields[3], 16, 64) - if err != nil { - return IPVSStats{}, err - } - stats.OutgoingBytes, err = strconv.ParseUint(statFields[4], 16, 64) - if err != nil { - return IPVSStats{}, err - } - - return stats, nil -} - -// IPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem. -func (fs FS) IPVSBackendStatus() ([]IPVSBackendStatus, error) { - file, err := os.Open(fs.proc.Path("net/ip_vs")) - if err != nil { - return nil, err - } - defer file.Close() - - return parseIPVSBackendStatus(file) -} - -func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) { - var ( - status []IPVSBackendStatus - scanner = bufio.NewScanner(file) - proto string - localMark string - localAddress net.IP - localPort uint16 - err error - ) - - for scanner.Scan() { - fields := strings.Fields(scanner.Text()) - if len(fields) == 0 { - continue - } - switch { - case fields[0] == "IP" || fields[0] == "Prot" || fields[1] == "RemoteAddress:Port": - continue - case fields[0] == "TCP" || fields[0] == "UDP": - if len(fields) < 2 { - continue - } - proto = fields[0] - localMark = "" - localAddress, localPort, err = parseIPPort(fields[1]) - if err != nil { - return nil, err - } - case fields[0] == "FWM": - if len(fields) < 2 { - continue - } - proto = fields[0] - localMark = fields[1] - localAddress = nil - localPort = 0 - case fields[0] == "->": - if len(fields) < 6 { - continue - } - remoteAddress, remotePort, err := parseIPPort(fields[1]) - if err != nil { - return nil, err - } - weight, err := strconv.ParseUint(fields[3], 10, 64) - if err != nil { - return nil, err - } - activeConn, err := strconv.ParseUint(fields[4], 10, 64) - if err != nil { - return nil, err - } - inactConn, err := strconv.ParseUint(fields[5], 10, 64) - if err != nil { - return nil, err - } - status = append(status, IPVSBackendStatus{ - LocalAddress: localAddress, - LocalPort: localPort, - LocalMark: localMark, - RemoteAddress: remoteAddress, - RemotePort: remotePort, - Proto: proto, - Weight: weight, - ActiveConn: activeConn, - InactConn: inactConn, - }) - } - } - return status, nil -} - -func parseIPPort(s string) (net.IP, uint16, error) { - var ( - ip net.IP - err error - ) - - switch len(s) { - case 13: - ip, err = hex.DecodeString(s[0:8]) - if err != nil { - return nil, 0, err - } - case 46: - ip = net.ParseIP(s[1:40]) - if ip == nil { - return nil, 0, fmt.Errorf("%w: Invalid IPv6 addr %s: %w", ErrFileParse, s[1:40], err) - } - default: - return nil, 0, fmt.Errorf("%w: Unexpected IP:Port %s: %w", ErrFileParse, s, err) - } - - portString := s[len(s)-4:] - if len(portString) != 4 { - return nil, 0, - fmt.Errorf("%w: Unexpected port string format %s: %w", ErrFileParse, portString, err) - } - port, err := strconv.ParseUint(portString, 16, 16) - if err != nil { - return nil, 0, err - } - - return ip, uint16(port), nil -} diff --git a/vendor/github.com/prometheus/procfs/kernel_hung.go b/vendor/github.com/prometheus/procfs/kernel_hung.go deleted file mode 100644 index 0c7a69f99f3d..000000000000 --- a/vendor/github.com/prometheus/procfs/kernel_hung.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows - -package procfs - -import ( - "os" - "strconv" - "strings" -) - -// KernelHung contains information about to the kernel's hung_task_detect_count number. -type KernelHung struct { - // Indicates the total number of tasks that have been detected as hung since the system boot. - // This file shows up if `CONFIG_DETECT_HUNG_TASK` is enabled. - HungTaskDetectCount *uint64 -} - -// KernelHung returns values from /proc/sys/kernel/hung_task_detect_count. -func (fs FS) KernelHung() (KernelHung, error) { - data, err := os.ReadFile(fs.proc.Path("sys", "kernel", "hung_task_detect_count")) - if err != nil { - return KernelHung{}, err - } - val, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) - if err != nil { - return KernelHung{}, err - } - return KernelHung{ - HungTaskDetectCount: &val, - }, nil -} diff --git a/vendor/github.com/prometheus/procfs/kernel_random.go b/vendor/github.com/prometheus/procfs/kernel_random.go deleted file mode 100644 index e7c5b8cf2be9..000000000000 --- a/vendor/github.com/prometheus/procfs/kernel_random.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows - -package procfs - -import ( - "os" - - "github.com/prometheus/procfs/internal/util" -) - -// KernelRandom contains information about to the kernel's random number generator. -type KernelRandom struct { - // EntropyAvaliable gives the available entropy, in bits. - EntropyAvaliable *uint64 - // PoolSize gives the size of the entropy pool, in bits. - PoolSize *uint64 - // URandomMinReseedSeconds is the number of seconds after which the DRNG will be reseeded. - URandomMinReseedSeconds *uint64 - // WriteWakeupThreshold the number of bits of entropy below which we wake up processes - // that do a select(2) or poll(2) for write access to /dev/random. - WriteWakeupThreshold *uint64 - // ReadWakeupThreshold is the number of bits of entropy required for waking up processes that sleep - // waiting for entropy from /dev/random. - ReadWakeupThreshold *uint64 -} - -// KernelRandom returns values from /proc/sys/kernel/random. -func (fs FS) KernelRandom() (KernelRandom, error) { - random := KernelRandom{} - - for file, p := range map[string]**uint64{ - "entropy_avail": &random.EntropyAvaliable, - "poolsize": &random.PoolSize, - "urandom_min_reseed_secs": &random.URandomMinReseedSeconds, - "write_wakeup_threshold": &random.WriteWakeupThreshold, - "read_wakeup_threshold": &random.ReadWakeupThreshold, - } { - val, err := util.ReadUintFromFile(fs.proc.Path("sys", "kernel", "random", file)) - if os.IsNotExist(err) { - continue - } - if err != nil { - return random, err - } - *p = &val - } - - return random, nil -} diff --git a/vendor/github.com/prometheus/procfs/loadavg.go b/vendor/github.com/prometheus/procfs/loadavg.go deleted file mode 100644 index c8c78a65edc5..000000000000 --- a/vendor/github.com/prometheus/procfs/loadavg.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "fmt" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// LoadAvg represents an entry in /proc/loadavg. -type LoadAvg struct { - Load1 float64 - Load5 float64 - Load15 float64 -} - -// LoadAvg returns loadavg from /proc. -func (fs FS) LoadAvg() (*LoadAvg, error) { - path := fs.proc.Path("loadavg") - - data, err := util.ReadFileNoStat(path) - if err != nil { - return nil, err - } - return parseLoad(data) -} - -// Parse /proc loadavg and return 1m, 5m and 15m. -func parseLoad(loadavgBytes []byte) (*LoadAvg, error) { - loads := make([]float64, 3) - parts := strings.Fields(string(loadavgBytes)) - if len(parts) < 3 { - return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, string(loadavgBytes)) - } - - var err error - for i, load := range parts[0:3] { - loads[i], err = strconv.ParseFloat(load, 64) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse load: %f: %w", ErrFileParse, loads[i], err) - } - } - return &LoadAvg{ - Load1: loads[0], - Load5: loads[1], - Load15: loads[2], - }, nil -} diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go deleted file mode 100644 index d66eeda82a2f..000000000000 --- a/vendor/github.com/prometheus/procfs/mdstat.go +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "fmt" - "os" - "regexp" - "strconv" - "strings" -) - -var ( - statusLineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[([U_]+)\]`) - recoveryLineBlocksRE = regexp.MustCompile(`\((\d+/\d+)\)`) - recoveryLinePctRE = regexp.MustCompile(`= (.+)%`) - recoveryLineFinishRE = regexp.MustCompile(`finish=(.+)min`) - recoveryLineSpeedRE = regexp.MustCompile(`speed=(.+)[A-Z]`) - componentDeviceRE = regexp.MustCompile(`(.*)\[(\d+)\](\([SF]+\))?`) - personalitiesPrefix = "Personalities : " -) - -type MDStatComponent struct { - // Name of the component device. - Name string - // DescriptorIndex number of component device, e.g. the order in the superblock. - DescriptorIndex int32 - // Flags per Linux drivers/md/md.[ch] as of v6.12-rc1 - // Subset that are exposed in mdstat - WriteMostly bool - Journal bool - Faulty bool // "Faulty" is what kernel source uses for "(F)" - Spare bool - Replacement bool - // Some additional flags that are NOT exposed in procfs today; they may - // be available via sysfs. - // In_sync, Bitmap_sync, Blocked, WriteErrorSeen, FaultRecorded, - // BlockedBadBlocks, WantReplacement, Candidate, ... -} - -// MDStat holds info parsed from /proc/mdstat. -type MDStat struct { - // Name of the device. - Name string - // raid type of the device. - Type string - // activity-state of the device. - ActivityState string - // Number of active disks. - DisksActive int64 - // Total number of disks the device requires. - DisksTotal int64 - // Number of failed disks. - DisksFailed int64 - // Number of "down" disks. (the _ indicator in the status line) - DisksDown int64 - // Spare disks in the device. - DisksSpare int64 - // Number of blocks the device holds. - BlocksTotal int64 - // Number of blocks on the device that are in sync. - BlocksSynced int64 - // Number of blocks on the device that need to be synced. - BlocksToBeSynced int64 - // progress percentage of current sync - BlocksSyncedPct float64 - // estimated finishing time for current sync (in minutes) - BlocksSyncedFinishTime float64 - // current sync speed (in Kilobytes/sec) - BlocksSyncedSpeed float64 - // component devices - Devices []MDStatComponent -} - -// MDStat parses an mdstat-file (/proc/mdstat) and returns a slice of -// structs containing the relevant info. More information available here: -// https://raid.wiki.kernel.org/index.php/Mdstat -func (fs FS) MDStat() ([]MDStat, error) { - data, err := os.ReadFile(fs.proc.Path("mdstat")) - if err != nil { - return nil, err - } - mdstat, err := parseMDStat(data) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse %v: %w", ErrFileParse, fs.proc.Path("mdstat"), err) - } - return mdstat, nil -} - -// parseMDStat parses data from mdstat file (/proc/mdstat) and returns a slice of -// structs containing the relevant info. -func parseMDStat(mdStatData []byte) ([]MDStat, error) { - // TODO: - // - parse global hotspares from the "unused devices" line. - mdStats := []MDStat{} - lines := strings.Split(string(mdStatData), "\n") - knownRaidTypes := make(map[string]bool) - - for i, line := range lines { - if strings.TrimSpace(line) == "" || line[0] == ' ' || - strings.HasPrefix(line, "unused") { - continue - } - // Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] - if len(knownRaidTypes) == 0 && strings.HasPrefix(line, personalitiesPrefix) { - personalities := strings.Fields(line[len(personalitiesPrefix):]) - for _, word := range personalities { - word := word[1 : len(word)-1] - knownRaidTypes[word] = true - } - continue - } - - deviceFields := strings.Fields(line) - if len(deviceFields) < 3 { - return nil, fmt.Errorf("%w: Expected 3+ lines, got %q", ErrFileParse, line) - } - mdName := deviceFields[0] // mdx - state := deviceFields[2] // active, inactive, broken - - mdType := "unknown" // raid1, raid5, etc. - var deviceStartIndex int - if len(deviceFields) > 3 { // mdType may be in the 3rd or 4th field - if isRaidType(deviceFields[3], knownRaidTypes) { - mdType = deviceFields[3] - deviceStartIndex = 4 - } else if len(deviceFields) > 4 && isRaidType(deviceFields[4], knownRaidTypes) { - // if the 3rd field is (...), the 4th field is the mdType - mdType = deviceFields[4] - deviceStartIndex = 5 - } - } - - if len(lines) <= i+3 { - return nil, fmt.Errorf("%w: Too few lines for md device: %q", ErrFileParse, mdName) - } - - // Failed (Faulty) disks have the suffix (F) & Spare disks have the suffix (S). - fail := int64(strings.Count(line, "(F)")) - spare := int64(strings.Count(line, "(S)")) - active, total, down, size, err := evalStatusLine(lines[i], lines[i+1]) - - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse md device lines: %v: %w", ErrFileParse, active, err) - } - - syncLineIdx := i + 2 - if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line - syncLineIdx++ - } - - // If device is syncing at the moment, get the number of currently - // synced bytes, otherwise that number equals the size of the device. - blocksSynced := size - blocksToBeSynced := size - speed := float64(0) - finish := float64(0) - pct := float64(0) - recovering := strings.Contains(lines[syncLineIdx], "recovery") - reshaping := strings.Contains(lines[syncLineIdx], "reshape") - resyncing := strings.Contains(lines[syncLineIdx], "resync") - checking := strings.Contains(lines[syncLineIdx], "check") - - // Append recovery and resyncing state info. - if recovering || resyncing || checking || reshaping { - switch { - case recovering: - state = "recovering" - case reshaping: - state = "reshaping" - case checking: - state = "checking" - default: - state = "resyncing" - } - - // Handle case when resync=PENDING or resync=DELAYED. - if strings.Contains(lines[syncLineIdx], "PENDING") || - strings.Contains(lines[syncLineIdx], "DELAYED") { - blocksSynced = 0 - } else { - blocksSynced, blocksToBeSynced, pct, finish, speed, err = evalRecoveryLine(lines[syncLineIdx]) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse sync line in md device: %q: %w", ErrFileParse, mdName, err) - } - } - } - - devices, err := evalComponentDevices(deviceFields[deviceStartIndex:]) - if err != nil { - return nil, fmt.Errorf("error parsing components in md device %q: %w", mdName, err) - } - - mdStats = append(mdStats, MDStat{ - Name: mdName, - Type: mdType, - ActivityState: state, - DisksActive: active, - DisksFailed: fail, - DisksDown: down, - DisksSpare: spare, - DisksTotal: total, - BlocksTotal: size, - BlocksSynced: blocksSynced, - BlocksToBeSynced: blocksToBeSynced, - BlocksSyncedPct: pct, - BlocksSyncedFinishTime: finish, - BlocksSyncedSpeed: speed, - Devices: devices, - }) - } - - return mdStats, nil -} - -// check if a string's format is like the mdType -// Rule 1: mdType should not be like (...) -// Rule 2: mdType should not be like sda[0] -// . -func isRaidType(mdType string, knownRaidTypes map[string]bool) bool { - _, ok := knownRaidTypes[mdType] - return !strings.ContainsAny(mdType, "([") && ok -} - -func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) { - // e.g. 523968 blocks super 1.2 [4/4] [UUUU] - statusFields := strings.Fields(statusLine) - if len(statusFields) < 1 { - return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected statusline %q: %w", ErrFileParse, statusLine, err) - } - - sizeStr := statusFields[0] - size, err = strconv.ParseInt(sizeStr, 10, 64) - if err != nil { - return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected statusline %q: %w", ErrFileParse, statusLine, err) - } - - if strings.Contains(deviceLine, "raid0") || strings.Contains(deviceLine, "linear") { - // In the device deviceLine, only disks have a number associated with them in []. - total = int64(strings.Count(deviceLine, "[")) - return total, total, 0, size, nil - } - - if strings.Contains(deviceLine, "inactive") { - return 0, 0, 0, size, nil - } - - matches := statusLineRE.FindStringSubmatch(statusLine) - if len(matches) != 5 { - return 0, 0, 0, 0, fmt.Errorf("%w: Could not fild all substring matches %s: %w", ErrFileParse, statusLine, err) - } - - total, err = strconv.ParseInt(matches[2], 10, 64) - if err != nil { - return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected statusline %q: %w", ErrFileParse, statusLine, err) - } - - active, err = strconv.ParseInt(matches[3], 10, 64) - if err != nil { - return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected active %d: %w", ErrFileParse, active, err) - } - down = int64(strings.Count(matches[4], "_")) - - return active, total, down, size, nil -} - -func evalRecoveryLine(recoveryLine string) (blocksSynced int64, blocksToBeSynced int64, pct float64, finish float64, speed float64, err error) { - matches := recoveryLineBlocksRE.FindStringSubmatch(recoveryLine) - if len(matches) != 2 { - return 0, 0, 0, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine blocks %s: %w", ErrFileParse, recoveryLine, err) - } - - blocks := strings.Split(matches[1], "/") - blocksSynced, err = strconv.ParseInt(blocks[0], 10, 64) - if err != nil { - return 0, 0, 0, 0, 0, fmt.Errorf("%w: Unable to parse recovery blocks synced %q: %w", ErrFileParse, matches[1], err) - } - - blocksToBeSynced, err = strconv.ParseInt(blocks[1], 10, 64) - if err != nil { - return blocksSynced, 0, 0, 0, 0, fmt.Errorf("%w: Unable to parse recovery to be synced blocks %q: %w", ErrFileParse, matches[2], err) - } - - // Get percentage complete - matches = recoveryLinePctRE.FindStringSubmatch(recoveryLine) - if len(matches) != 2 { - return blocksSynced, blocksToBeSynced, 0, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine matching percentage %s", ErrFileParse, recoveryLine) - } - pct, err = strconv.ParseFloat(strings.TrimSpace(matches[1]), 64) - if err != nil { - return blocksSynced, blocksToBeSynced, 0, 0, 0, fmt.Errorf("%w: Error parsing float from recoveryLine %q", ErrFileParse, recoveryLine) - } - - // Get time expected left to complete - matches = recoveryLineFinishRE.FindStringSubmatch(recoveryLine) - if len(matches) != 2 { - return blocksSynced, blocksToBeSynced, pct, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine matching est. finish time: %s", ErrFileParse, recoveryLine) - } - finish, err = strconv.ParseFloat(matches[1], 64) - if err != nil { - return blocksSynced, blocksToBeSynced, pct, 0, 0, fmt.Errorf("%w: Unable to parse float from recoveryLine: %q", ErrFileParse, recoveryLine) - } - - // Get recovery speed - matches = recoveryLineSpeedRE.FindStringSubmatch(recoveryLine) - if len(matches) != 2 { - return blocksSynced, blocksToBeSynced, pct, finish, 0, fmt.Errorf("%w: Unexpected recoveryLine value: %s", ErrFileParse, recoveryLine) - } - speed, err = strconv.ParseFloat(matches[1], 64) - if err != nil { - return blocksSynced, blocksToBeSynced, pct, finish, 0, fmt.Errorf("%w: Error parsing float from recoveryLine: %q: %w", ErrFileParse, recoveryLine, err) - } - - return blocksSynced, blocksToBeSynced, pct, finish, speed, nil -} - -func evalComponentDevices(deviceFields []string) ([]MDStatComponent, error) { - mdComponentDevices := make([]MDStatComponent, 0) - for _, field := range deviceFields { - match := componentDeviceRE.FindStringSubmatch(field) - if match == nil { - continue - } - descriptorIndex, err := strconv.ParseInt(match[2], 10, 32) - if err != nil { - return mdComponentDevices, fmt.Errorf("error parsing int from device %q: %w", match[2], err) - } - mdComponentDevices = append(mdComponentDevices, MDStatComponent{ - Name: match[1], - DescriptorIndex: int32(descriptorIndex), - // match may contain one or more of these - // https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/md/md.c#L8376-L8392 - Faulty: strings.Contains(match[3], "(F)"), - Spare: strings.Contains(match[3], "(S)"), - Journal: strings.Contains(match[3], "(J)"), - Replacement: strings.Contains(match[3], "(R)"), - WriteMostly: strings.Contains(match[3], "(W)"), - }) - } - - return mdComponentDevices, nil -} diff --git a/vendor/github.com/prometheus/procfs/meminfo.go b/vendor/github.com/prometheus/procfs/meminfo.go deleted file mode 100644 index 34203831871e..000000000000 --- a/vendor/github.com/prometheus/procfs/meminfo.go +++ /dev/null @@ -1,422 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Meminfo represents memory statistics. -type Meminfo struct { - // Total usable ram (i.e. physical ram minus a few reserved - // bits and the kernel binary code) - MemTotal *uint64 - // The sum of LowFree+HighFree - MemFree *uint64 - // An estimate of how much memory is available for starting - // new applications, without swapping. Calculated from - // MemFree, SReclaimable, the size of the file LRU lists, and - // the low watermarks in each zone. The estimate takes into - // account that the system needs some page cache to function - // well, and that not all reclaimable slab will be - // reclaimable, due to items being in use. The impact of those - // factors will vary from system to system. - MemAvailable *uint64 - // Relatively temporary storage for raw disk blocks shouldn't - // get tremendously large (20MB or so) - Buffers *uint64 - Cached *uint64 - // Memory that once was swapped out, is swapped back in but - // still also is in the swapfile (if memory is needed it - // doesn't need to be swapped out AGAIN because it is already - // in the swapfile. This saves I/O) - SwapCached *uint64 - // Memory that has been used more recently and usually not - // reclaimed unless absolutely necessary. - Active *uint64 - // Memory which has been less recently used. It is more - // eligible to be reclaimed for other purposes - Inactive *uint64 - ActiveAnon *uint64 - InactiveAnon *uint64 - ActiveFile *uint64 - InactiveFile *uint64 - Unevictable *uint64 - Mlocked *uint64 - // total amount of swap space available - SwapTotal *uint64 - // Memory which has been evicted from RAM, and is temporarily - // on the disk - SwapFree *uint64 - // Memory consumed by the zswap backend (compressed size) - Zswap *uint64 - // Amount of anonymous memory stored in zswap (original size) - Zswapped *uint64 - // Memory which is waiting to get written back to the disk - Dirty *uint64 - // Memory which is actively being written back to the disk - Writeback *uint64 - // Non-file backed pages mapped into userspace page tables - AnonPages *uint64 - // files which have been mapped, such as libraries - Mapped *uint64 - Shmem *uint64 - // in-kernel data structures cache - Slab *uint64 - // Part of Slab, that might be reclaimed, such as caches - SReclaimable *uint64 - // Part of Slab, that cannot be reclaimed on memory pressure - SUnreclaim *uint64 - KernelStack *uint64 - // amount of memory dedicated to the lowest level of page - // tables. - PageTables *uint64 - // secondary page tables. - SecPageTables *uint64 - // NFS pages sent to the server, but not yet committed to - // stable storage - NFSUnstable *uint64 - // Memory used for block device "bounce buffers" - Bounce *uint64 - // Memory used by FUSE for temporary writeback buffers - WritebackTmp *uint64 - // Based on the overcommit ratio ('vm.overcommit_ratio'), - // this is the total amount of memory currently available to - // be allocated on the system. This limit is only adhered to - // if strict overcommit accounting is enabled (mode 2 in - // 'vm.overcommit_memory'). - // The CommitLimit is calculated with the following formula: - // CommitLimit = ([total RAM pages] - [total huge TLB pages]) * - // overcommit_ratio / 100 + [total swap pages] - // For example, on a system with 1G of physical RAM and 7G - // of swap with a `vm.overcommit_ratio` of 30 it would - // yield a CommitLimit of 7.3G. - // For more details, see the memory overcommit documentation - // in vm/overcommit-accounting. - CommitLimit *uint64 - // The amount of memory presently allocated on the system. - // The committed memory is a sum of all of the memory which - // has been allocated by processes, even if it has not been - // "used" by them as of yet. A process which malloc()'s 1G - // of memory, but only touches 300M of it will show up as - // using 1G. This 1G is memory which has been "committed" to - // by the VM and can be used at any time by the allocating - // application. With strict overcommit enabled on the system - // (mode 2 in 'vm.overcommit_memory'),allocations which would - // exceed the CommitLimit (detailed above) will not be permitted. - // This is useful if one needs to guarantee that processes will - // not fail due to lack of memory once that memory has been - // successfully allocated. - CommittedAS *uint64 - // total size of vmalloc memory area - VmallocTotal *uint64 - // amount of vmalloc area which is used - VmallocUsed *uint64 - // largest contiguous block of vmalloc area which is free - VmallocChunk *uint64 - Percpu *uint64 - HardwareCorrupted *uint64 - AnonHugePages *uint64 - FileHugePages *uint64 - ShmemHugePages *uint64 - ShmemPmdMapped *uint64 - CmaTotal *uint64 - CmaFree *uint64 - Unaccepted *uint64 - HugePagesTotal *uint64 - HugePagesFree *uint64 - HugePagesRsvd *uint64 - HugePagesSurp *uint64 - Hugepagesize *uint64 - Hugetlb *uint64 - DirectMap4k *uint64 - DirectMap2M *uint64 - DirectMap1G *uint64 - - // The struct fields below are the byte-normalized counterparts to the - // existing struct fields. Values are normalized using the optional - // unit field in the meminfo line. - MemTotalBytes *uint64 - MemFreeBytes *uint64 - MemAvailableBytes *uint64 - BuffersBytes *uint64 - CachedBytes *uint64 - SwapCachedBytes *uint64 - ActiveBytes *uint64 - InactiveBytes *uint64 - ActiveAnonBytes *uint64 - InactiveAnonBytes *uint64 - ActiveFileBytes *uint64 - InactiveFileBytes *uint64 - UnevictableBytes *uint64 - MlockedBytes *uint64 - SwapTotalBytes *uint64 - SwapFreeBytes *uint64 - ZswapBytes *uint64 - ZswappedBytes *uint64 - DirtyBytes *uint64 - WritebackBytes *uint64 - AnonPagesBytes *uint64 - MappedBytes *uint64 - ShmemBytes *uint64 - SlabBytes *uint64 - SReclaimableBytes *uint64 - SUnreclaimBytes *uint64 - KernelStackBytes *uint64 - PageTablesBytes *uint64 - SecPageTablesBytes *uint64 - NFSUnstableBytes *uint64 - BounceBytes *uint64 - WritebackTmpBytes *uint64 - CommitLimitBytes *uint64 - CommittedASBytes *uint64 - VmallocTotalBytes *uint64 - VmallocUsedBytes *uint64 - VmallocChunkBytes *uint64 - PercpuBytes *uint64 - HardwareCorruptedBytes *uint64 - AnonHugePagesBytes *uint64 - FileHugePagesBytes *uint64 - ShmemHugePagesBytes *uint64 - ShmemPmdMappedBytes *uint64 - CmaTotalBytes *uint64 - CmaFreeBytes *uint64 - UnacceptedBytes *uint64 - HugepagesizeBytes *uint64 - HugetlbBytes *uint64 - DirectMap4kBytes *uint64 - DirectMap2MBytes *uint64 - DirectMap1GBytes *uint64 -} - -// Meminfo returns an information about current kernel/system memory statistics. -// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt -func (fs FS) Meminfo() (Meminfo, error) { - b, err := util.ReadFileNoStat(fs.proc.Path("meminfo")) - if err != nil { - return Meminfo{}, err - } - - m, err := parseMemInfo(bytes.NewReader(b)) - if err != nil { - return Meminfo{}, fmt.Errorf("%w: %w", ErrFileParse, err) - } - - return *m, nil -} - -func parseMemInfo(r io.Reader) (*Meminfo, error) { - var m Meminfo - s := bufio.NewScanner(r) - for s.Scan() { - fields := strings.Fields(s.Text()) - var val, valBytes uint64 - - val, err := strconv.ParseUint(fields[1], 0, 64) - if err != nil { - return nil, err - } - - switch len(fields) { - case 2: - // No unit present, use the parsed the value as bytes directly. - valBytes = val - case 3: - // Unit present in optional 3rd field, convert it to - // bytes. The only unit supported within the Linux - // kernel is `kB`. - if fields[2] != "kB" { - return nil, fmt.Errorf("%w: Unsupported unit in optional 3rd field %q", ErrFileParse, fields[2]) - } - - valBytes = 1024 * val - - default: - return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, s.Text()) - } - - switch fields[0] { - case "MemTotal:": - m.MemTotal = &val - m.MemTotalBytes = &valBytes - case "MemFree:": - m.MemFree = &val - m.MemFreeBytes = &valBytes - case "MemAvailable:": - m.MemAvailable = &val - m.MemAvailableBytes = &valBytes - case "Buffers:": - m.Buffers = &val - m.BuffersBytes = &valBytes - case "Cached:": - m.Cached = &val - m.CachedBytes = &valBytes - case "SwapCached:": - m.SwapCached = &val - m.SwapCachedBytes = &valBytes - case "Active:": - m.Active = &val - m.ActiveBytes = &valBytes - case "Inactive:": - m.Inactive = &val - m.InactiveBytes = &valBytes - case "Active(anon):": - m.ActiveAnon = &val - m.ActiveAnonBytes = &valBytes - case "Inactive(anon):": - m.InactiveAnon = &val - m.InactiveAnonBytes = &valBytes - case "Active(file):": - m.ActiveFile = &val - m.ActiveFileBytes = &valBytes - case "Inactive(file):": - m.InactiveFile = &val - m.InactiveFileBytes = &valBytes - case "Unevictable:": - m.Unevictable = &val - m.UnevictableBytes = &valBytes - case "Mlocked:": - m.Mlocked = &val - m.MlockedBytes = &valBytes - case "SwapTotal:": - m.SwapTotal = &val - m.SwapTotalBytes = &valBytes - case "SwapFree:": - m.SwapFree = &val - m.SwapFreeBytes = &valBytes - case "Zswap:": - m.Zswap = &val - m.ZswapBytes = &valBytes - case "Zswapped:": - m.Zswapped = &val - m.ZswappedBytes = &valBytes - case "Dirty:": - m.Dirty = &val - m.DirtyBytes = &valBytes - case "Writeback:": - m.Writeback = &val - m.WritebackBytes = &valBytes - case "AnonPages:": - m.AnonPages = &val - m.AnonPagesBytes = &valBytes - case "Mapped:": - m.Mapped = &val - m.MappedBytes = &valBytes - case "Shmem:": - m.Shmem = &val - m.ShmemBytes = &valBytes - case "Slab:": - m.Slab = &val - m.SlabBytes = &valBytes - case "SReclaimable:": - m.SReclaimable = &val - m.SReclaimableBytes = &valBytes - case "SUnreclaim:": - m.SUnreclaim = &val - m.SUnreclaimBytes = &valBytes - case "KernelStack:": - m.KernelStack = &val - m.KernelStackBytes = &valBytes - case "PageTables:": - m.PageTables = &val - m.PageTablesBytes = &valBytes - case "SecPageTables:": - m.SecPageTables = &val - m.SecPageTablesBytes = &valBytes - case "NFS_Unstable:": - m.NFSUnstable = &val - m.NFSUnstableBytes = &valBytes - case "Bounce:": - m.Bounce = &val - m.BounceBytes = &valBytes - case "WritebackTmp:": - m.WritebackTmp = &val - m.WritebackTmpBytes = &valBytes - case "CommitLimit:": - m.CommitLimit = &val - m.CommitLimitBytes = &valBytes - case "Committed_AS:": - m.CommittedAS = &val - m.CommittedASBytes = &valBytes - case "VmallocTotal:": - m.VmallocTotal = &val - m.VmallocTotalBytes = &valBytes - case "VmallocUsed:": - m.VmallocUsed = &val - m.VmallocUsedBytes = &valBytes - case "VmallocChunk:": - m.VmallocChunk = &val - m.VmallocChunkBytes = &valBytes - case "Percpu:": - m.Percpu = &val - m.PercpuBytes = &valBytes - case "HardwareCorrupted:": - m.HardwareCorrupted = &val - m.HardwareCorruptedBytes = &valBytes - case "AnonHugePages:": - m.AnonHugePages = &val - m.AnonHugePagesBytes = &valBytes - case "FileHugePages:": - m.FileHugePages = &val - m.FileHugePagesBytes = &valBytes - case "ShmemHugePages:": - m.ShmemHugePages = &val - m.ShmemHugePagesBytes = &valBytes - case "ShmemPmdMapped:": - m.ShmemPmdMapped = &val - m.ShmemPmdMappedBytes = &valBytes - case "CmaTotal:": - m.CmaTotal = &val - m.CmaTotalBytes = &valBytes - case "CmaFree:": - m.CmaFree = &val - m.CmaFreeBytes = &valBytes - case "Unaccepted:": - m.Unaccepted = &val - m.UnacceptedBytes = &valBytes - case "HugePages_Total:": - m.HugePagesTotal = &val - case "HugePages_Free:": - m.HugePagesFree = &val - case "HugePages_Rsvd:": - m.HugePagesRsvd = &val - case "HugePages_Surp:": - m.HugePagesSurp = &val - case "Hugepagesize:": - m.Hugepagesize = &val - m.HugepagesizeBytes = &valBytes - case "Hugetlb:": - m.Hugetlb = &val - m.HugetlbBytes = &valBytes - case "DirectMap4k:": - m.DirectMap4k = &val - m.DirectMap4kBytes = &valBytes - case "DirectMap2M:": - m.DirectMap2M = &val - m.DirectMap2MBytes = &valBytes - case "DirectMap1G:": - m.DirectMap1G = &val - m.DirectMap1GBytes = &valBytes - } - } - - return &m, nil -} diff --git a/vendor/github.com/prometheus/procfs/mountinfo.go b/vendor/github.com/prometheus/procfs/mountinfo.go deleted file mode 100644 index 9414a12f42f0..000000000000 --- a/vendor/github.com/prometheus/procfs/mountinfo.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// A MountInfo is a type that describes the details, options -// for each mount, parsed from /proc/self/mountinfo. -// The fields described in each entry of /proc/self/mountinfo -// is described in the following man page. -// http://man7.org/linux/man-pages/man5/proc.5.html -type MountInfo struct { - // Unique ID for the mount - MountID int - // The ID of the parent mount - ParentID int - // The value of `st_dev` for the files on this FS - MajorMinorVer string - // The pathname of the directory in the FS that forms - // the root for this mount - Root string - // The pathname of the mount point relative to the root - MountPoint string - // Mount options - Options map[string]string - // Zero or more optional fields - OptionalFields map[string]string - // The Filesystem type - FSType string - // FS specific information or "none" - Source string - // Superblock options - SuperOptions map[string]string -} - -// Reads each line of the mountinfo file, and returns a list of formatted MountInfo structs. -func parseMountInfo(info []byte) ([]*MountInfo, error) { - mounts := []*MountInfo{} - scanner := bufio.NewScanner(bytes.NewReader(info)) - for scanner.Scan() { - mountString := scanner.Text() - parsedMounts, err := parseMountInfoString(mountString) - if err != nil { - return nil, err - } - mounts = append(mounts, parsedMounts) - } - - err := scanner.Err() - return mounts, err -} - -// Parses a mountinfo file line, and converts it to a MountInfo struct. -// An important check here is to see if the hyphen separator, as if it does not exist, -// it means that the line is malformed. -func parseMountInfoString(mountString string) (*MountInfo, error) { - var err error - - mountInfo := strings.Split(mountString, " ") - mountInfoLength := len(mountInfo) - if mountInfoLength < 10 { - return nil, fmt.Errorf("%w: Too few fields in mount string: %s", ErrFileParse, mountString) - } - - if mountInfo[mountInfoLength-4] != "-" { - return nil, fmt.Errorf("%w: couldn't find separator in expected field: %s", ErrFileParse, mountInfo[mountInfoLength-4]) - } - - mount := &MountInfo{ - MajorMinorVer: mountInfo[2], - Root: mountInfo[3], - MountPoint: mountInfo[4], - Options: mountOptionsParser(mountInfo[5]), - OptionalFields: nil, - FSType: mountInfo[mountInfoLength-3], - Source: mountInfo[mountInfoLength-2], - SuperOptions: mountOptionsParser(mountInfo[mountInfoLength-1]), - } - - mount.MountID, err = strconv.Atoi(mountInfo[0]) - if err != nil { - return nil, fmt.Errorf("%w: mount ID: %q", ErrFileParse, mount.MountID) - } - mount.ParentID, err = strconv.Atoi(mountInfo[1]) - if err != nil { - return nil, fmt.Errorf("%w: parent ID: %q", ErrFileParse, mount.ParentID) - } - // Has optional fields, which is a space separated list of values. - // Example: shared:2 master:7 - if mountInfo[6] != "" { - mount.OptionalFields, err = mountOptionsParseOptionalFields(mountInfo[6 : mountInfoLength-4]) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrFileParse, err) - } - } - return mount, nil -} - -// mountOptionsIsValidField checks a string against a valid list of optional fields keys. -func mountOptionsIsValidField(s string) bool { - switch s { - case - "shared", - "master", - "propagate_from", - "unbindable": - return true - } - return false -} - -// mountOptionsParseOptionalFields parses a list of optional fields strings into a double map of strings. -func mountOptionsParseOptionalFields(o []string) (map[string]string, error) { - optionalFields := make(map[string]string) - for _, field := range o { - optionSplit := strings.SplitN(field, ":", 2) - value := "" - if len(optionSplit) == 2 { - value = optionSplit[1] - } - if mountOptionsIsValidField(optionSplit[0]) { - optionalFields[optionSplit[0]] = value - } - } - return optionalFields, nil -} - -// mountOptionsParser parses the mount options, superblock options. -func mountOptionsParser(mountOptions string) map[string]string { - opts := make(map[string]string) - for opt := range strings.SplitSeq(mountOptions, ",") { - splitOption := strings.Split(opt, "=") - if len(splitOption) < 2 { - key := splitOption[0] - opts[key] = "" - } else { - key, value := splitOption[0], splitOption[1] - opts[key] = value - } - } - return opts -} - -// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`. -func GetMounts() ([]*MountInfo, error) { - data, err := util.ReadFileNoStat("/proc/self/mountinfo") - if err != nil { - return nil, err - } - return parseMountInfo(data) -} - -// GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`. -func GetProcMounts(pid int) ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid)) - if err != nil { - return nil, err - } - return parseMountInfo(data) -} - -// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`. -func (fs FS) GetMounts() ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("self/mountinfo")) - if err != nil { - return nil, err - } - return parseMountInfo(data) -} - -// GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`. -func (fs FS) GetProcMounts(pid int) ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid))) - if err != nil { - return nil, err - } - return parseMountInfo(data) -} diff --git a/vendor/github.com/prometheus/procfs/mountstats.go b/vendor/github.com/prometheus/procfs/mountstats.go deleted file mode 100644 index e503cb3a6c5d..000000000000 --- a/vendor/github.com/prometheus/procfs/mountstats.go +++ /dev/null @@ -1,710 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -// While implementing parsing of /proc/[pid]/mountstats, this blog was used -// heavily as a reference: -// https://utcc.utoronto.ca/~cks/space/blog/linux/NFSMountstatsIndex -// -// Special thanks to Chris Siebenmann for all of his posts explaining the -// various statistics available for NFS. - -import ( - "bufio" - "fmt" - "io" - "strconv" - "strings" - "time" -) - -// Constants shared between multiple functions. -const ( - deviceEntryLen = 8 - - fieldBytesLen = 8 - fieldEventsLen = 27 - - statVersion10 = "1.0" - statVersion11 = "1.1" - - fieldTransport10TCPLen = 10 - fieldTransport10UDPLen = 7 - - fieldTransport11TCPLen = 13 - fieldTransport11UDPLen = 10 - - // Kernel version >= 4.14 MaxLen - // See: https://elixir.bootlin.com/linux/v6.4.8/source/net/sunrpc/xprtrdma/xprt_rdma.h#L393 - fieldTransport11RDMAMaxLen = 28 - - // Kernel version <= 4.2 MinLen - // See: https://elixir.bootlin.com/linux/v4.2.8/source/net/sunrpc/xprtrdma/xprt_rdma.h#L331 - fieldTransport11RDMAMinLen = 20 -) - -// A Mount is a device mount parsed from /proc/[pid]/mountstats. -type Mount struct { - // Name of the device. - Device string - // The mount point of the device. - Mount string - // The filesystem type used by the device. - Type string - // If available additional statistics related to this Mount. - // Use a type assertion to determine if additional statistics are available. - Stats MountStats -} - -// A MountStats is a type which contains detailed statistics for a specific -// type of Mount. -type MountStats interface { - mountStats() -} - -// A MountStatsNFS is a MountStats implementation for NFSv3 and v4 mounts. -type MountStatsNFS struct { - // The version of statistics provided. - StatVersion string - // The mount options of the NFS mount. - Opts map[string]string - // The age of the NFS mount. - Age time.Duration - // Statistics related to byte counters for various operations. - Bytes NFSBytesStats - // Statistics related to various NFS event occurrences. - Events NFSEventsStats - // Statistics broken down by filesystem operation. - Operations []NFSOperationStats - // Statistics about the NFS RPC transport. - Transport []NFSTransportStats -} - -// mountStats implements MountStats. -func (m MountStatsNFS) mountStats() {} - -// A NFSBytesStats contains statistics about the number of bytes read and written -// by an NFS client to and from an NFS server. -type NFSBytesStats struct { - // Number of bytes read using the read() syscall. - Read uint64 - // Number of bytes written using the write() syscall. - Write uint64 - // Number of bytes read using the read() syscall in O_DIRECT mode. - DirectRead uint64 - // Number of bytes written using the write() syscall in O_DIRECT mode. - DirectWrite uint64 - // Number of bytes read from the NFS server, in total. - ReadTotal uint64 - // Number of bytes written to the NFS server, in total. - WriteTotal uint64 - // Number of pages read directly via mmap()'d files. - ReadPages uint64 - // Number of pages written directly via mmap()'d files. - WritePages uint64 -} - -// A NFSEventsStats contains statistics about NFS event occurrences. -type NFSEventsStats struct { - // Number of times cached inode attributes are re-validated from the server. - InodeRevalidate uint64 - // Number of times cached dentry nodes are re-validated from the server. - DnodeRevalidate uint64 - // Number of times an inode cache is cleared. - DataInvalidate uint64 - // Number of times cached inode attributes are invalidated. - AttributeInvalidate uint64 - // Number of times files or directories have been open()'d. - VFSOpen uint64 - // Number of times a directory lookup has occurred. - VFSLookup uint64 - // Number of times permissions have been checked. - VFSAccess uint64 - // Number of updates (and potential writes) to pages. - VFSUpdatePage uint64 - // Number of pages read directly via mmap()'d files. - VFSReadPage uint64 - // Number of times a group of pages have been read. - VFSReadPages uint64 - // Number of pages written directly via mmap()'d files. - VFSWritePage uint64 - // Number of times a group of pages have been written. - VFSWritePages uint64 - // Number of times directory entries have been read with getdents(). - VFSGetdents uint64 - // Number of times attributes have been set on inodes. - VFSSetattr uint64 - // Number of pending writes that have been forcefully flushed to the server. - VFSFlush uint64 - // Number of times fsync() has been called on directories and files. - VFSFsync uint64 - // Number of times locking has been attempted on a file. - VFSLock uint64 - // Number of times files have been closed and released. - VFSFileRelease uint64 - // Unknown. Possibly unused. - CongestionWait uint64 - // Number of times files have been truncated. - Truncation uint64 - // Number of times a file has been grown due to writes beyond its existing end. - WriteExtension uint64 - // Number of times a file was removed while still open by another process. - SillyRename uint64 - // Number of times the NFS server gave less data than expected while reading. - ShortRead uint64 - // Number of times the NFS server wrote less data than expected while writing. - ShortWrite uint64 - // Number of times the NFS server indicated EJUKEBOX; retrieving data from - // offline storage. - JukeboxDelay uint64 - // Number of NFS v4.1+ pNFS reads. - PNFSRead uint64 - // Number of NFS v4.1+ pNFS writes. - PNFSWrite uint64 -} - -// A NFSOperationStats contains statistics for a single operation. -type NFSOperationStats struct { - // The name of the operation. - Operation string - // Number of requests performed for this operation. - Requests uint64 - // Number of times an actual RPC request has been transmitted for this operation. - Transmissions uint64 - // Number of times a request has had a major timeout. - MajorTimeouts uint64 - // Number of bytes sent for this operation, including RPC headers and payload. - BytesSent uint64 - // Number of bytes received for this operation, including RPC headers and payload. - BytesReceived uint64 - // Duration all requests spent queued for transmission before they were sent. - CumulativeQueueMilliseconds uint64 - // Duration it took to get a reply back after the request was transmitted. - CumulativeTotalResponseMilliseconds uint64 - // Duration from when a request was enqueued to when it was completely handled. - CumulativeTotalRequestMilliseconds uint64 - // The count of operations that complete with tk_status < 0. These statuses usually indicate error conditions. - Errors uint64 -} - -// A NFSTransportStats contains statistics for the NFS mount RPC requests and -// responses. -type NFSTransportStats struct { - // The transport protocol used for the NFS mount. - Protocol string - // The local port used for the NFS mount. - Port uint64 - // Number of times the client has had to establish a connection from scratch - // to the NFS server. - Bind uint64 - // Number of times the client has made a TCP connection to the NFS server. - Connect uint64 - // Duration (in jiffies, a kernel internal unit of time) the NFS mount has - // spent waiting for connections to the server to be established. - ConnectIdleTime uint64 - // Duration since the NFS mount last saw any RPC traffic. - IdleTimeSeconds uint64 - // Number of RPC requests for this mount sent to the NFS server. - Sends uint64 - // Number of RPC responses for this mount received from the NFS server. - Receives uint64 - // Number of times the NFS server sent a response with a transaction ID - // unknown to this client. - BadTransactionIDs uint64 - // A running counter, incremented on each request as the current difference - // ebetween sends and receives. - CumulativeActiveRequests uint64 - // A running counter, incremented on each request by the current backlog - // queue size. - CumulativeBacklog uint64 - - // Stats below only available with stat version 1.1. - - // Maximum number of simultaneously active RPC requests ever used. - MaximumRPCSlotsUsed uint64 - // A running counter, incremented on each request as the current size of the - // sending queue. - CumulativeSendingQueue uint64 - // A running counter, incremented on each request as the current size of the - // pending queue. - CumulativePendingQueue uint64 - - // Stats below only available with stat version 1.1. - // Transport over RDMA - - // accessed when sending a call - ReadChunkCount uint64 - WriteChunkCount uint64 - ReplyChunkCount uint64 - TotalRdmaRequest uint64 - - // rarely accessed error counters - PullupCopyCount uint64 - HardwayRegisterCount uint64 - FailedMarshalCount uint64 - BadReplyCount uint64 - MrsRecovered uint64 - MrsOrphaned uint64 - MrsAllocated uint64 - EmptySendctxQ uint64 - - // accessed when receiving a reply - TotalRdmaReply uint64 - FixupCopyCount uint64 - ReplyWaitsForSend uint64 - LocalInvNeeded uint64 - NomsgCallCount uint64 - BcallCount uint64 -} - -// parseMountStats parses a /proc/[pid]/mountstats file and returns a slice -// of Mount structures containing detailed information about each mount. -// If available, statistics for each mount are parsed as well. -func parseMountStats(r io.Reader) ([]*Mount, error) { - const ( - device = "device" - statVersionPrefix = "statvers=" - - nfs3Type = "nfs" - nfs4Type = "nfs4" - ) - - var mounts []*Mount - - s := bufio.NewScanner(r) - for s.Scan() { - // Only look for device entries in this function - ss := strings.Fields(string(s.Bytes())) - if len(ss) == 0 || ss[0] != device { - continue - } - - m, err := parseMount(ss) - if err != nil { - return nil, err - } - - // Does this mount also possess statistics information? - if len(ss) > deviceEntryLen { - // Only NFSv3 and v4 are supported for parsing statistics - if m.Type != nfs3Type && m.Type != nfs4Type { - return nil, fmt.Errorf("%w: Cannot parse MountStats for %q", ErrFileParse, m.Type) - } - - statVersion := strings.TrimPrefix(ss[8], statVersionPrefix) - - stats, err := parseMountStatsNFS(s, statVersion) - if err != nil { - return nil, err - } - - m.Stats = stats - } - - mounts = append(mounts, m) - } - - return mounts, s.Err() -} - -// parseMount parses an entry in /proc/[pid]/mountstats in the format: -// -// device [device] mounted on [mount] with fstype [type] -func parseMount(ss []string) (*Mount, error) { - if len(ss) < deviceEntryLen { - return nil, fmt.Errorf("%w: Invalid device %q", ErrFileParse, ss) - } - - // Check for specific words appearing at specific indices to ensure - // the format is consistent with what we expect - format := []struct { - i int - s string - }{ - {i: 0, s: "device"}, - {i: 2, s: "mounted"}, - {i: 3, s: "on"}, - {i: 5, s: "with"}, - {i: 6, s: "fstype"}, - } - - for _, f := range format { - if ss[f.i] != f.s { - return nil, fmt.Errorf("%w: Invalid device %q", ErrFileParse, ss) - } - } - - return &Mount{ - Device: ss[1], - Mount: ss[4], - Type: ss[7], - }, nil -} - -// parseMountStatsNFS parses a MountStatsNFS by scanning additional information -// related to NFS statistics. -func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, error) { - // Field indicators for parsing specific types of data - const ( - fieldOpts = "opts:" - fieldAge = "age:" - fieldBytes = "bytes:" - fieldEvents = "events:" - fieldPerOpStats = "per-op" - fieldTransport = "xprt:" - ) - - stats := &MountStatsNFS{ - StatVersion: statVersion, - } - - for s.Scan() { - ss := strings.Fields(string(s.Bytes())) - if len(ss) == 0 { - break - } - - switch ss[0] { - case fieldOpts: - if len(ss) < 2 { - return nil, fmt.Errorf("%w: Incomplete information for NFS stats: %v", ErrFileParse, ss) - } - if stats.Opts == nil { - stats.Opts = map[string]string{} - } - for opt := range strings.SplitSeq(ss[1], ",") { - split := strings.Split(opt, "=") - if len(split) == 2 { - stats.Opts[split[0]] = split[1] - } else { - stats.Opts[opt] = "" - } - } - case fieldAge: - if len(ss) < 2 { - return nil, fmt.Errorf("%w: Incomplete information for NFS stats: %v", ErrFileParse, ss) - } - // Age integer is in seconds - d, err := time.ParseDuration(ss[1] + "s") - if err != nil { - return nil, err - } - - stats.Age = d - case fieldBytes: - if len(ss) < 2 { - return nil, fmt.Errorf("%w: Incomplete information for NFS stats: %v", ErrFileParse, ss) - } - bstats, err := parseNFSBytesStats(ss[1:]) - if err != nil { - return nil, err - } - - stats.Bytes = *bstats - case fieldEvents: - if len(ss) < 2 { - return nil, fmt.Errorf("%w: Incomplete information for NFS events: %v", ErrFileParse, ss) - } - estats, err := parseNFSEventsStats(ss[1:]) - if err != nil { - return nil, err - } - - stats.Events = *estats - case fieldTransport: - if len(ss) < 3 { - return nil, fmt.Errorf("%w: Incomplete information for NFS transport stats: %v", ErrFileParse, ss) - } - - tstats, err := parseNFSTransportStats(ss[1:], statVersion) - if err != nil { - return nil, err - } - - stats.Transport = append(stats.Transport, *tstats) - } - - // When encountering "per-operation statistics", we must break this - // loop and parse them separately to ensure we can terminate parsing - // before reaching another device entry; hence why this 'if' statement - // is not just another switch case - if ss[0] == fieldPerOpStats { - break - } - } - - if err := s.Err(); err != nil { - return nil, err - } - - // NFS per-operation stats appear last before the next device entry - perOpStats, err := parseNFSOperationStats(s) - if err != nil { - return nil, err - } - - stats.Operations = perOpStats - - return stats, nil -} - -// parseNFSBytesStats parses a NFSBytesStats line using an input set of -// integer fields. -func parseNFSBytesStats(ss []string) (*NFSBytesStats, error) { - if len(ss) != fieldBytesLen { - return nil, fmt.Errorf("%w: Invalid NFS bytes stats: %v", ErrFileParse, ss) - } - - ns := make([]uint64, 0, fieldBytesLen) - for _, s := range ss { - n, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return nil, err - } - - ns = append(ns, n) - } - - return &NFSBytesStats{ - Read: ns[0], - Write: ns[1], - DirectRead: ns[2], - DirectWrite: ns[3], - ReadTotal: ns[4], - WriteTotal: ns[5], - ReadPages: ns[6], - WritePages: ns[7], - }, nil -} - -// parseNFSEventsStats parses a NFSEventsStats line using an input set of -// integer fields. -func parseNFSEventsStats(ss []string) (*NFSEventsStats, error) { - if len(ss) != fieldEventsLen { - return nil, fmt.Errorf("%w: invalid NFS events stats: %v", ErrFileParse, ss) - } - - ns := make([]uint64, 0, fieldEventsLen) - for _, s := range ss { - n, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return nil, err - } - - ns = append(ns, n) - } - - return &NFSEventsStats{ - InodeRevalidate: ns[0], - DnodeRevalidate: ns[1], - DataInvalidate: ns[2], - AttributeInvalidate: ns[3], - VFSOpen: ns[4], - VFSLookup: ns[5], - VFSAccess: ns[6], - VFSUpdatePage: ns[7], - VFSReadPage: ns[8], - VFSReadPages: ns[9], - VFSWritePage: ns[10], - VFSWritePages: ns[11], - VFSGetdents: ns[12], - VFSSetattr: ns[13], - VFSFlush: ns[14], - VFSFsync: ns[15], - VFSLock: ns[16], - VFSFileRelease: ns[17], - CongestionWait: ns[18], - Truncation: ns[19], - WriteExtension: ns[20], - SillyRename: ns[21], - ShortRead: ns[22], - ShortWrite: ns[23], - JukeboxDelay: ns[24], - PNFSRead: ns[25], - PNFSWrite: ns[26], - }, nil -} - -// parseNFSOperationStats parses a slice of NFSOperationStats by scanning -// additional information about per-operation statistics until an empty -// line is reached. -func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) { - const ( - // Minimum number of expected fields in each per-operation statistics set - minFields = 9 - ) - - var ops []NFSOperationStats - - for s.Scan() { - ss := strings.Fields(string(s.Bytes())) - if len(ss) == 0 { - // Must break when reading a blank line after per-operation stats to - // enable top-level function to parse the next device entry - break - } - - if len(ss) < minFields { - return nil, fmt.Errorf("%w: invalid NFS per-operations stats: %v", ErrFileParse, ss) - } - - // Skip string operation name for integers - ns := make([]uint64, 0, minFields-1) - for _, st := range ss[1:] { - n, err := strconv.ParseUint(st, 10, 64) - if err != nil { - return nil, err - } - - ns = append(ns, n) - } - opStats := NFSOperationStats{ - Operation: strings.TrimSuffix(ss[0], ":"), - Requests: ns[0], - Transmissions: ns[1], - MajorTimeouts: ns[2], - BytesSent: ns[3], - BytesReceived: ns[4], - CumulativeQueueMilliseconds: ns[5], - CumulativeTotalResponseMilliseconds: ns[6], - CumulativeTotalRequestMilliseconds: ns[7], - } - - if len(ns) > 8 { - opStats.Errors = ns[8] - } - - ops = append(ops, opStats) - } - - return ops, s.Err() -} - -// parseNFSTransportStats parses a NFSTransportStats line using an input set of -// integer fields matched to a specific stats version. -func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) { - // Extract the protocol field. It is the only string value in the line - protocol := ss[0] - ss = ss[1:] - - switch statVersion { - case statVersion10: - var expectedLength int - switch protocol { - case "tcp": - expectedLength = fieldTransport10TCPLen - case "udp": - expectedLength = fieldTransport10UDPLen - default: - return nil, fmt.Errorf("%w: Invalid NFS protocol \"%s\" in stats 1.0 statement: %v", ErrFileParse, protocol, ss) - } - if len(ss) != expectedLength { - return nil, fmt.Errorf("%w: Invalid NFS transport stats 1.0 statement: %v", ErrFileParse, ss) - } - case statVersion11: - var expectedLength int - switch protocol { - case "tcp": - expectedLength = fieldTransport11TCPLen - case "udp": - expectedLength = fieldTransport11UDPLen - case "rdma": - expectedLength = fieldTransport11RDMAMinLen - default: - return nil, fmt.Errorf("%w: invalid NFS protocol \"%s\" in stats 1.1 statement: %v", ErrFileParse, protocol, ss) - } - if (len(ss) != expectedLength && (protocol == "tcp" || protocol == "udp")) || - (protocol == "rdma" && len(ss) < expectedLength) { - return nil, fmt.Errorf("%w: invalid NFS transport stats 1.1 statement: %v, protocol: %v", ErrFileParse, ss, protocol) - } - default: - return nil, fmt.Errorf("%w: Unrecognized NFS transport stats version: %q, protocol: %v", ErrFileParse, statVersion, protocol) - } - - // Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay - // in a v1.0 response. Since the stat length is bigger for TCP stats, we use - // the TCP length here. - // - // Note: slice length must be set to length of v1.1 stats to avoid a panic when - // only v1.0 stats are present. - // See: https://github.com/prometheus/node_exporter/issues/571. - // - // Note: NFS Over RDMA slice length is fieldTransport11RDMAMaxLen - ns := make([]uint64, fieldTransport11RDMAMaxLen+3) - for i, s := range ss { - n, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return nil, err - } - - ns[i] = n - } - - // The fields differ depending on the transport protocol (TCP or UDP) - // From https://utcc.utoronto.ca/%7Ecks/space/blog/linux/NFSMountstatsXprt - // - // For the udp RPC transport there is no connection count, connect idle time, - // or idle time (fields #3, #4, and #5); all other fields are the same. So - // we set them to 0 here. - switch protocol { - case "udp": - ns = append(ns[:2], append(make([]uint64, 3), ns[2:]...)...) - case "tcp": - ns = append(ns[:fieldTransport11TCPLen], make([]uint64, fieldTransport11RDMAMaxLen-fieldTransport11TCPLen+3)...) - case "rdma": - ns = append(ns[:fieldTransport10TCPLen], append(make([]uint64, 3), ns[fieldTransport10TCPLen:]...)...) - } - - return &NFSTransportStats{ - // NFS xprt over tcp or udp - Protocol: protocol, - Port: ns[0], - Bind: ns[1], - Connect: ns[2], - ConnectIdleTime: ns[3], - IdleTimeSeconds: ns[4], - Sends: ns[5], - Receives: ns[6], - BadTransactionIDs: ns[7], - CumulativeActiveRequests: ns[8], - CumulativeBacklog: ns[9], - - // NFS xprt over tcp or udp - // And statVersion 1.1 - MaximumRPCSlotsUsed: ns[10], - CumulativeSendingQueue: ns[11], - CumulativePendingQueue: ns[12], - - // NFS xprt over rdma - // And stat Version 1.1 - ReadChunkCount: ns[13], - WriteChunkCount: ns[14], - ReplyChunkCount: ns[15], - TotalRdmaRequest: ns[16], - PullupCopyCount: ns[17], - HardwayRegisterCount: ns[18], - FailedMarshalCount: ns[19], - BadReplyCount: ns[20], - MrsRecovered: ns[21], - MrsOrphaned: ns[22], - MrsAllocated: ns[23], - EmptySendctxQ: ns[24], - TotalRdmaReply: ns[25], - FixupCopyCount: ns[26], - ReplyWaitsForSend: ns[27], - LocalInvNeeded: ns[28], - NomsgCallCount: ns[29], - BcallCount: ns[30], - }, nil -} diff --git a/vendor/github.com/prometheus/procfs/net_conntrackstat.go b/vendor/github.com/prometheus/procfs/net_conntrackstat.go deleted file mode 100644 index e9ca35707905..000000000000 --- a/vendor/github.com/prometheus/procfs/net_conntrackstat.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// A ConntrackStatEntry represents one line from net/stat/nf_conntrack -// and contains netfilter conntrack statistics at one CPU core. -type ConntrackStatEntry struct { - Entries uint64 - Searched uint64 - Found uint64 - New uint64 - Invalid uint64 - Ignore uint64 - Delete uint64 - DeleteList uint64 - Insert uint64 - InsertFailed uint64 - Drop uint64 - EarlyDrop uint64 - SearchRestart uint64 -} - -// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores. -func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) { - return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack")) -} - -// Parses a slice of ConntrackStatEntries from the given filepath. -func readConntrackStat(path string) ([]ConntrackStatEntry, error) { - // This file is small and can be read with one syscall. - b, err := util.ReadFileNoStat(path) - if err != nil { - // Do not wrap this error so the caller can detect os.IsNotExist and - // similar conditions. - return nil, err - } - - stat, err := parseConntrackStat(bytes.NewReader(b)) - if err != nil { - return nil, fmt.Errorf("%w: Cannot read file: %v: %w", ErrFileRead, path, err) - } - - return stat, nil -} - -// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries. -func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { - var entries []ConntrackStatEntry - - scanner := bufio.NewScanner(r) - scanner.Scan() - for scanner.Scan() { - fields := strings.Fields(scanner.Text()) - conntrackEntry, err := parseConntrackStatEntry(fields) - if err != nil { - return nil, err - } - entries = append(entries, *conntrackEntry) - } - - return entries, nil -} - -// Parses a ConntrackStatEntry from given array of fields. -func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { - entries, err := util.ParseHexUint64s(fields) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse entry: %d: %w", ErrFileParse, entries, err) - } - numEntries := len(entries) - if numEntries < 16 || numEntries > 17 { - return nil, - fmt.Errorf("%w: invalid conntrackstat entry, invalid number of fields: %d", ErrFileParse, numEntries) - } - - stats := &ConntrackStatEntry{ - Entries: *entries[0], - Searched: *entries[1], - Found: *entries[2], - New: *entries[3], - Invalid: *entries[4], - Ignore: *entries[5], - Delete: *entries[6], - DeleteList: *entries[7], - Insert: *entries[8], - InsertFailed: *entries[9], - Drop: *entries[10], - EarlyDrop: *entries[11], - } - - // Ignore missing search_restart on Linux < 2.6.35. - if numEntries == 17 { - stats.SearchRestart = *entries[16] - } - - return stats, nil -} diff --git a/vendor/github.com/prometheus/procfs/net_dev.go b/vendor/github.com/prometheus/procfs/net_dev.go deleted file mode 100644 index 7b3e1d61c95e..000000000000 --- a/vendor/github.com/prometheus/procfs/net_dev.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "errors" - "os" - "sort" - "strconv" - "strings" -) - -// NetDevLine is single line parsed from /proc/net/dev or /proc/[pid]/net/dev. -type NetDevLine struct { - Name string `json:"name"` // The name of the interface. - RxBytes uint64 `json:"rx_bytes"` // Cumulative count of bytes received. - RxPackets uint64 `json:"rx_packets"` // Cumulative count of packets received. - RxErrors uint64 `json:"rx_errors"` // Cumulative count of receive errors encountered. - RxDropped uint64 `json:"rx_dropped"` // Cumulative count of packets dropped while receiving. - RxFIFO uint64 `json:"rx_fifo"` // Cumulative count of FIFO buffer errors. - RxFrame uint64 `json:"rx_frame"` // Cumulative count of packet framing errors. - RxCompressed uint64 `json:"rx_compressed"` // Cumulative count of compressed packets received by the device driver. - RxMulticast uint64 `json:"rx_multicast"` // Cumulative count of multicast frames received by the device driver. - TxBytes uint64 `json:"tx_bytes"` // Cumulative count of bytes transmitted. - TxPackets uint64 `json:"tx_packets"` // Cumulative count of packets transmitted. - TxErrors uint64 `json:"tx_errors"` // Cumulative count of transmit errors encountered. - TxDropped uint64 `json:"tx_dropped"` // Cumulative count of packets dropped while transmitting. - TxFIFO uint64 `json:"tx_fifo"` // Cumulative count of FIFO buffer errors. - TxCollisions uint64 `json:"tx_collisions"` // Cumulative count of collisions detected on the interface. - TxCarrier uint64 `json:"tx_carrier"` // Cumulative count of carrier losses detected by the device driver. - TxCompressed uint64 `json:"tx_compressed"` // Cumulative count of compressed packets transmitted by the device driver. -} - -// NetDev is parsed from /proc/net/dev or /proc/[pid]/net/dev. The map keys -// are interface names. -type NetDev map[string]NetDevLine - -// NetDev returns kernel/system statistics read from /proc/net/dev. -func (fs FS) NetDev() (NetDev, error) { - return newNetDev(fs.proc.Path("net/dev")) -} - -// NetDev returns kernel/system statistics read from /proc/[pid]/net/dev. -func (p Proc) NetDev() (NetDev, error) { - return newNetDev(p.path("net/dev")) -} - -// newNetDev creates a new NetDev from the contents of the given file. -func newNetDev(file string) (NetDev, error) { - f, err := os.Open(file) - if err != nil { - return NetDev{}, err - } - defer f.Close() - - netDev := NetDev{} - s := bufio.NewScanner(f) - for n := 0; s.Scan(); n++ { - // Skip the 2 header lines. - if n < 2 { - continue - } - - line, err := netDev.parseLine(s.Text()) - if err != nil { - return netDev, err - } - - netDev[line.Name] = *line - } - - return netDev, s.Err() -} - -// parseLine parses a single line from the /proc/net/dev file. Header lines -// must be filtered prior to calling this method. -func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) { - idx := strings.LastIndex(rawLine, ":") - if idx == -1 { - return nil, errors.New("invalid net/dev line, missing colon") - } - fields := strings.Fields(strings.TrimSpace(rawLine[idx+1:])) - - var err error - line := &NetDevLine{} - - // Interface Name - line.Name = strings.TrimSpace(rawLine[:idx]) - if line.Name == "" { - return nil, errors.New("invalid net/dev line, empty interface name") - } - - // RX - line.RxBytes, err = strconv.ParseUint(fields[0], 10, 64) - if err != nil { - return nil, err - } - line.RxPackets, err = strconv.ParseUint(fields[1], 10, 64) - if err != nil { - return nil, err - } - line.RxErrors, err = strconv.ParseUint(fields[2], 10, 64) - if err != nil { - return nil, err - } - line.RxDropped, err = strconv.ParseUint(fields[3], 10, 64) - if err != nil { - return nil, err - } - line.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64) - if err != nil { - return nil, err - } - line.RxFrame, err = strconv.ParseUint(fields[5], 10, 64) - if err != nil { - return nil, err - } - line.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64) - if err != nil { - return nil, err - } - line.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64) - if err != nil { - return nil, err - } - - // TX - line.TxBytes, err = strconv.ParseUint(fields[8], 10, 64) - if err != nil { - return nil, err - } - line.TxPackets, err = strconv.ParseUint(fields[9], 10, 64) - if err != nil { - return nil, err - } - line.TxErrors, err = strconv.ParseUint(fields[10], 10, 64) - if err != nil { - return nil, err - } - line.TxDropped, err = strconv.ParseUint(fields[11], 10, 64) - if err != nil { - return nil, err - } - line.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64) - if err != nil { - return nil, err - } - line.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64) - if err != nil { - return nil, err - } - line.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64) - if err != nil { - return nil, err - } - line.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64) - if err != nil { - return nil, err - } - - return line, nil -} - -// Total aggregates the values across interfaces and returns a new NetDevLine. -// The Name field will be a sorted comma separated list of interface names. -func (netDev NetDev) Total() NetDevLine { - total := NetDevLine{} - - names := make([]string, 0, len(netDev)) - for _, ifc := range netDev { - names = append(names, ifc.Name) - total.RxBytes += ifc.RxBytes - total.RxPackets += ifc.RxPackets - total.RxErrors += ifc.RxErrors - total.RxDropped += ifc.RxDropped - total.RxFIFO += ifc.RxFIFO - total.RxFrame += ifc.RxFrame - total.RxCompressed += ifc.RxCompressed - total.RxMulticast += ifc.RxMulticast - total.TxBytes += ifc.TxBytes - total.TxPackets += ifc.TxPackets - total.TxErrors += ifc.TxErrors - total.TxDropped += ifc.TxDropped - total.TxFIFO += ifc.TxFIFO - total.TxCollisions += ifc.TxCollisions - total.TxCarrier += ifc.TxCarrier - total.TxCompressed += ifc.TxCompressed - } - sort.Strings(names) - total.Name = strings.Join(names, ", ") - - return total -} diff --git a/vendor/github.com/prometheus/procfs/net_dev_snmp6.go b/vendor/github.com/prometheus/procfs/net_dev_snmp6.go deleted file mode 100644 index 2a0f60f29fee..000000000000 --- a/vendor/github.com/prometheus/procfs/net_dev_snmp6.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "errors" - "io" - "os" - "path/filepath" - "strconv" - "strings" -) - -// NetDevSNMP6 is parsed from files in /proc/net/dev_snmp6/ or /proc//net/dev_snmp6/. -// The outer map's keys are interface names and the inner map's keys are stat names. -// -// If you'd like a total across all interfaces, please use the Snmp6() method of the Proc type. -type NetDevSNMP6 map[string]map[string]uint64 - -// Returns kernel/system statistics read from interface files within the /proc/net/dev_snmp6/ -// directory. -func (fs FS) NetDevSNMP6() (NetDevSNMP6, error) { - return newNetDevSNMP6(fs.proc.Path("net/dev_snmp6")) -} - -// Returns kernel/system statistics read from interface files within the /proc//net/dev_snmp6/ -// directory. -func (p Proc) NetDevSNMP6() (NetDevSNMP6, error) { - return newNetDevSNMP6(p.path("net/dev_snmp6")) -} - -// newNetDevSNMP6 creates a new NetDevSNMP6 from the contents of the given directory. -func newNetDevSNMP6(dir string) (NetDevSNMP6, error) { - netDevSNMP6 := make(NetDevSNMP6) - - // The net/dev_snmp6 folders contain one file per interface - ifaceFiles, err := os.ReadDir(dir) - if err != nil { - // On systems with IPv6 disabled, this directory won't exist. - // Do nothing. - if errors.Is(err, os.ErrNotExist) { - return netDevSNMP6, err - } - return netDevSNMP6, err - } - - for _, iFaceFile := range ifaceFiles { - filePath := filepath.Join(dir, iFaceFile.Name()) - - f, err := os.Open(filePath) - if err != nil { - return netDevSNMP6, err - } - defer f.Close() - - netDevSNMP6[iFaceFile.Name()], err = parseNetDevSNMP6Stats(f) - if err != nil { - return netDevSNMP6, err - } - } - - return netDevSNMP6, nil -} - -func parseNetDevSNMP6Stats(r io.Reader) (map[string]uint64, error) { - m := make(map[string]uint64) - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - stat := strings.Fields(scanner.Text()) - if len(stat) < 2 { - continue - } - key, val := stat[0], stat[1] - - // Expect stat name to contain "6" or be "ifIndex" - if strings.Contains(key, "6") || key == "ifIndex" { - v, err := strconv.ParseUint(val, 10, 64) - if err != nil { - return m, err - } - - m[key] = v - } - } - return m, scanner.Err() -} diff --git a/vendor/github.com/prometheus/procfs/net_ip_socket.go b/vendor/github.com/prometheus/procfs/net_ip_socket.go deleted file mode 100644 index 9291f8cd4c80..000000000000 --- a/vendor/github.com/prometheus/procfs/net_ip_socket.go +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "encoding/hex" - "fmt" - "io" - "net" - "os" - "strconv" - "strings" -) - -const ( - // Maximum size limit used by io.LimitReader while reading the content of the - // /proc/net/udp{,6} files. The number of lines inside such a file is dynamic - // as each line represents a single used socket. - // In theory, the number of available sockets is 65535 (2^16 - 1) per IP. - // With e.g. 150 Byte per line and the maximum number of 65535, - // the reader needs to handle 150 Byte * 65535 =~ 10 MB for a single IP. - readLimit = 4294967296 // Byte -> 4 GiB -) - -// This contains generic data structures for both udp and tcp sockets. -type ( - // NetIPSocket represents the contents of /proc/net/{t,u}dp{,6} file without the header. - NetIPSocket []*netIPSocketLine - - // NetIPSocketSummary provides already computed values like the total queue lengths or - // the total number of used sockets. In contrast to NetIPSocket it does not collect - // the parsed lines into a slice. - NetIPSocketSummary struct { - // TxQueueLength shows the total queue length of all parsed tx_queue lengths. - TxQueueLength uint64 - // RxQueueLength shows the total queue length of all parsed rx_queue lengths. - RxQueueLength uint64 - // UsedSockets shows the total number of parsed lines representing the - // number of used sockets. - UsedSockets uint64 - // Drops shows the total number of dropped packets of all UDP sockets. - Drops *uint64 - } - - // A single line parser for fields from /proc/net/{t,u}dp{,6}. - // Fields which are not used by IPSocket are skipped. - // Drops is non-nil for udp{,6}, but nil for tcp{,6}. - // For the proc file format details, see https://linux.die.net/man/5/proc. - netIPSocketLine struct { - Sl uint64 - LocalAddr net.IP - LocalPort uint64 - RemAddr net.IP - RemPort uint64 - St uint64 - TxQueue uint64 - RxQueue uint64 - UID uint64 - Inode uint64 - Drops *uint64 - } -) - -func newNetIPSocket(file string) (NetIPSocket, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - - var netIPSocket NetIPSocket - isUDP := strings.Contains(file, "udp") - - lr := io.LimitReader(f, readLimit) - s := bufio.NewScanner(lr) - s.Scan() // skip first line with headers - for s.Scan() { - fields := strings.Fields(s.Text()) - line, err := parseNetIPSocketLine(fields, isUDP) - if err != nil { - return nil, err - } - netIPSocket = append(netIPSocket, line) - } - if err := s.Err(); err != nil { - return nil, err - } - return netIPSocket, nil -} - -// newNetIPSocketSummary creates a new NetIPSocket{,6} from the contents of the given file. -func newNetIPSocketSummary(file string) (*NetIPSocketSummary, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - - var netIPSocketSummary NetIPSocketSummary - var udpPacketDrops uint64 - isUDP := strings.Contains(file, "udp") - - lr := io.LimitReader(f, readLimit) - s := bufio.NewScanner(lr) - s.Scan() // skip first line with headers - for s.Scan() { - fields := strings.Fields(s.Text()) - line, err := parseNetIPSocketLine(fields, isUDP) - if err != nil { - return nil, err - } - netIPSocketSummary.TxQueueLength += line.TxQueue - netIPSocketSummary.RxQueueLength += line.RxQueue - netIPSocketSummary.UsedSockets++ - if isUDP { - udpPacketDrops += *line.Drops - netIPSocketSummary.Drops = &udpPacketDrops - } - } - if err := s.Err(); err != nil { - return nil, err - } - return &netIPSocketSummary, nil -} - -// the /proc/net/{t,u}dp{,6} files are network byte order for ipv4 and for ipv6 the address is four words consisting of four bytes each. In each of those four words the four bytes are written in reverse order. - -func parseIP(hexIP string) (net.IP, error) { - var byteIP []byte - byteIP, err := hex.DecodeString(hexIP) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse socket field in %q: %w", ErrFileParse, hexIP, err) - } - switch len(byteIP) { - case 4: - return net.IP{byteIP[3], byteIP[2], byteIP[1], byteIP[0]}, nil - case 16: - i := net.IP{ - byteIP[3], byteIP[2], byteIP[1], byteIP[0], - byteIP[7], byteIP[6], byteIP[5], byteIP[4], - byteIP[11], byteIP[10], byteIP[9], byteIP[8], - byteIP[15], byteIP[14], byteIP[13], byteIP[12], - } - return i, nil - default: - return nil, fmt.Errorf("%w: Unable to parse IP %s: %v", ErrFileParse, hexIP, nil) - } -} - -// parseNetIPSocketLine parses a single line, represented by a list of fields. -func parseNetIPSocketLine(fields []string, isUDP bool) (*netIPSocketLine, error) { - line := &netIPSocketLine{} - if len(fields) < 10 { - return nil, fmt.Errorf( - "%w: Less than 10 columns found %q", - ErrFileParse, - strings.Join(fields, " "), - ) - } - var err error // parse error - - // sl - s := strings.Split(fields[0], ":") - if len(s) != 2 { - return nil, fmt.Errorf("%w: Unable to parse sl field in line %q", ErrFileParse, fields[0]) - } - - if line.Sl, err = strconv.ParseUint(s[0], 0, 64); err != nil { - return nil, fmt.Errorf("%w: Unable to parse sl field in %q: %w", ErrFileParse, line.Sl, err) - } - // local_address - l := strings.Split(fields[1], ":") - if len(l) != 2 { - return nil, fmt.Errorf("%w: Unable to parse local_address field in %q", ErrFileParse, fields[1]) - } - if line.LocalAddr, err = parseIP(l[0]); err != nil { - return nil, err - } - if line.LocalPort, err = strconv.ParseUint(l[1], 16, 64); err != nil { - return nil, fmt.Errorf("%w: Unable to parse local_address port value line %q: %w", ErrFileParse, line.LocalPort, err) - } - - // remote_address - r := strings.Split(fields[2], ":") - if len(r) != 2 { - return nil, fmt.Errorf("%w: Unable to parse rem_address field in %q", ErrFileParse, fields[1]) - } - if line.RemAddr, err = parseIP(r[0]); err != nil { - return nil, err - } - if line.RemPort, err = strconv.ParseUint(r[1], 16, 64); err != nil { - return nil, fmt.Errorf("%w: Cannot parse rem_address port value in %q: %w", ErrFileParse, line.RemPort, err) - } - - // st - if line.St, err = strconv.ParseUint(fields[3], 16, 64); err != nil { - return nil, fmt.Errorf("%w: Cannot parse st value in %q: %w", ErrFileParse, line.St, err) - } - - // tx_queue and rx_queue - q := strings.Split(fields[4], ":") - if len(q) != 2 { - return nil, fmt.Errorf( - "%w: Missing colon for tx/rx queues in socket line %q", - ErrFileParse, - fields[4], - ) - } - if line.TxQueue, err = strconv.ParseUint(q[0], 16, 64); err != nil { - return nil, fmt.Errorf("%w: Cannot parse tx_queue value in %q: %w", ErrFileParse, line.TxQueue, err) - } - if line.RxQueue, err = strconv.ParseUint(q[1], 16, 64); err != nil { - return nil, fmt.Errorf("%w: Cannot parse trx_queue value in %q: %w", ErrFileParse, line.RxQueue, err) - } - - // uid - if line.UID, err = strconv.ParseUint(fields[7], 0, 64); err != nil { - return nil, fmt.Errorf("%w: Cannot parse UID value in %q: %w", ErrFileParse, line.UID, err) - } - - // inode - if line.Inode, err = strconv.ParseUint(fields[9], 0, 64); err != nil { - return nil, fmt.Errorf("%w: Cannot parse inode value in %q: %w", ErrFileParse, line.Inode, err) - } - - // drops - if isUDP { - drops, err := strconv.ParseUint(fields[12], 0, 64) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse drops value in %q: %w", ErrFileParse, drops, err) - } - line.Drops = &drops - } - - return line, nil -} diff --git a/vendor/github.com/prometheus/procfs/net_protocols.go b/vendor/github.com/prometheus/procfs/net_protocols.go deleted file mode 100644 index eaa996cbcf19..000000000000 --- a/vendor/github.com/prometheus/procfs/net_protocols.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// NetProtocolStats stores the contents from /proc/net/protocols. -type NetProtocolStats map[string]NetProtocolStatLine - -// NetProtocolStatLine contains a single line parsed from /proc/net/protocols. We -// only care about the first six columns as the rest are not likely to change -// and only serve to provide a set of capabilities for each protocol. -type NetProtocolStatLine struct { - Name string // 0 The name of the protocol - Size uint64 // 1 The size, in bytes, of a given protocol structure. e.g. sizeof(struct tcp_sock) or sizeof(struct unix_sock) - Sockets int64 // 2 Number of sockets in use by this protocol - Memory int64 // 3 Number of 4KB pages allocated by all sockets of this protocol - Pressure int // 4 This is either yes, no, or NI (not implemented). For the sake of simplicity we treat NI as not experiencing memory pressure. - MaxHeader uint64 // 5 Protocol specific max header size - Slab bool // 6 Indicates whether or not memory is allocated from the SLAB - ModuleName string // 7 The name of the module that implemented this protocol or "kernel" if not from a module - Capabilities NetProtocolCapabilities -} - -// NetProtocolCapabilities contains a list of capabilities for each protocol. -type NetProtocolCapabilities struct { - Close bool // 8 - Connect bool // 9 - Disconnect bool // 10 - Accept bool // 11 - IoCtl bool // 12 - Init bool // 13 - Destroy bool // 14 - Shutdown bool // 15 - SetSockOpt bool // 16 - GetSockOpt bool // 17 - SendMsg bool // 18 - RecvMsg bool // 19 - SendPage bool // 20 - Bind bool // 21 - BacklogRcv bool // 22 - Hash bool // 23 - UnHash bool // 24 - GetPort bool // 25 - EnterMemoryPressure bool // 26 -} - -// NetProtocols reads stats from /proc/net/protocols and returns a map of -// PortocolStatLine entries. As of this writing no official Linux Documentation -// exists, however the source is fairly self-explanatory and the format seems -// stable since its introduction in 2.6.12-rc2 -// Linux 2.6.12-rc2 - https://elixir.bootlin.com/linux/v2.6.12-rc2/source/net/core/sock.c#L1452 -// Linux 5.10 - https://elixir.bootlin.com/linux/v5.10.4/source/net/core/sock.c#L3586 -func (fs FS) NetProtocols() (NetProtocolStats, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("net/protocols")) - if err != nil { - return NetProtocolStats{}, err - } - return parseNetProtocols(bufio.NewScanner(bytes.NewReader(data))) -} - -func parseNetProtocols(s *bufio.Scanner) (NetProtocolStats, error) { - nps := NetProtocolStats{} - - // Skip the header line - s.Scan() - - for s.Scan() { - line, err := nps.parseLine(s.Text()) - if err != nil { - return NetProtocolStats{}, err - } - - nps[line.Name] = *line - } - return nps, nil -} - -func (ps NetProtocolStats) parseLine(rawLine string) (*NetProtocolStatLine, error) { - line := &NetProtocolStatLine{Capabilities: NetProtocolCapabilities{}} - var err error - const enabled = "yes" - const disabled = "no" - - fields := strings.Fields(rawLine) - line.Name = fields[0] - line.Size, err = strconv.ParseUint(fields[1], 10, 64) - if err != nil { - return nil, err - } - line.Sockets, err = strconv.ParseInt(fields[2], 10, 64) - if err != nil { - return nil, err - } - line.Memory, err = strconv.ParseInt(fields[3], 10, 64) - if err != nil { - return nil, err - } - switch fields[4] { - case enabled: - line.Pressure = 1 - case disabled: - line.Pressure = 0 - default: - line.Pressure = -1 - } - line.MaxHeader, err = strconv.ParseUint(fields[5], 10, 64) - if err != nil { - return nil, err - } - switch fields[6] { - case enabled: - line.Slab = true - case disabled: - line.Slab = false - default: - return nil, fmt.Errorf("%w: capability for protocol: %s", ErrFileParse, line.Name) - } - line.ModuleName = fields[7] - - err = line.Capabilities.parseCapabilities(fields[8:]) - if err != nil { - return nil, err - } - - return line, nil -} - -func (pc *NetProtocolCapabilities) parseCapabilities(capabilities []string) error { - // The capabilities are all bools so we can loop over to map them - capabilityFields := [...]*bool{ - &pc.Close, - &pc.Connect, - &pc.Disconnect, - &pc.Accept, - &pc.IoCtl, - &pc.Init, - &pc.Destroy, - &pc.Shutdown, - &pc.SetSockOpt, - &pc.GetSockOpt, - &pc.SendMsg, - &pc.RecvMsg, - &pc.SendPage, - &pc.Bind, - &pc.BacklogRcv, - &pc.Hash, - &pc.UnHash, - &pc.GetPort, - &pc.EnterMemoryPressure, - } - - for i := range capabilities { - switch capabilities[i] { - case "y": - *capabilityFields[i] = true - case "n": - *capabilityFields[i] = false - default: - return fmt.Errorf("%w: capability block for protocol: position %d", ErrFileParse, i) - } - } - return nil -} diff --git a/vendor/github.com/prometheus/procfs/net_route.go b/vendor/github.com/prometheus/procfs/net_route.go deleted file mode 100644 index fa3812d9d00c..000000000000 --- a/vendor/github.com/prometheus/procfs/net_route.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -const ( - blackholeRepresentation string = "*" - blackholeIfaceName string = "blackhole" - routeLineColumns int = 11 -) - -// A NetRouteLine represents one line from net/route. -type NetRouteLine struct { - Iface string - Destination uint32 - Gateway uint32 - Flags uint32 - RefCnt uint32 - Use uint32 - Metric uint32 - Mask uint32 - MTU uint32 - Window uint32 - IRTT uint32 -} - -func (fs FS) NetRoute() ([]NetRouteLine, error) { - return readNetRoute(fs.proc.Path("net", "route")) -} - -func readNetRoute(path string) ([]NetRouteLine, error) { - b, err := util.ReadFileNoStat(path) - if err != nil { - return nil, err - } - - routelines, err := parseNetRoute(bytes.NewReader(b)) - if err != nil { - return nil, fmt.Errorf("failed to read net route from %s: %w", path, err) - } - return routelines, nil -} - -func parseNetRoute(r io.Reader) ([]NetRouteLine, error) { - var routelines []NetRouteLine - - scanner := bufio.NewScanner(r) - scanner.Scan() - for scanner.Scan() { - fields := strings.Fields(scanner.Text()) - routeline, err := parseNetRouteLine(fields) - if err != nil { - return nil, err - } - routelines = append(routelines, *routeline) - } - return routelines, nil -} - -func parseNetRouteLine(fields []string) (*NetRouteLine, error) { - if len(fields) != routeLineColumns { - return nil, fmt.Errorf("invalid routeline, num of digits: %d", len(fields)) - } - iface := fields[0] - if iface == blackholeRepresentation { - iface = blackholeIfaceName - } - destination, err := strconv.ParseUint(fields[1], 16, 32) - if err != nil { - return nil, err - } - gateway, err := strconv.ParseUint(fields[2], 16, 32) - if err != nil { - return nil, err - } - flags, err := strconv.ParseUint(fields[3], 10, 32) - if err != nil { - return nil, err - } - refcnt, err := strconv.ParseUint(fields[4], 10, 32) - if err != nil { - return nil, err - } - use, err := strconv.ParseUint(fields[5], 10, 32) - if err != nil { - return nil, err - } - metric, err := strconv.ParseUint(fields[6], 10, 32) - if err != nil { - return nil, err - } - mask, err := strconv.ParseUint(fields[7], 16, 32) - if err != nil { - return nil, err - } - mtu, err := strconv.ParseUint(fields[8], 10, 32) - if err != nil { - return nil, err - } - window, err := strconv.ParseUint(fields[9], 10, 32) - if err != nil { - return nil, err - } - irtt, err := strconv.ParseUint(fields[10], 10, 32) - if err != nil { - return nil, err - } - routeline := &NetRouteLine{ - Iface: iface, - Destination: uint32(destination), - Gateway: uint32(gateway), - Flags: uint32(flags), - RefCnt: uint32(refcnt), - Use: uint32(use), - Metric: uint32(metric), - Mask: uint32(mask), - MTU: uint32(mtu), - Window: uint32(window), - IRTT: uint32(irtt), - } - return routeline, nil -} diff --git a/vendor/github.com/prometheus/procfs/net_sockstat.go b/vendor/github.com/prometheus/procfs/net_sockstat.go deleted file mode 100644 index 8b221ebfff75..000000000000 --- a/vendor/github.com/prometheus/procfs/net_sockstat.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// A NetSockstat contains the output of /proc/net/sockstat{,6} for IPv4 or IPv6, -// respectively. -type NetSockstat struct { - // Used is non-nil for IPv4 sockstat results, but nil for IPv6. - Used *int - Protocols []NetSockstatProtocol -} - -// A NetSockstatProtocol contains statistics about a given socket protocol. -// Pointer fields indicate that the value may or may not be present on any -// given protocol. -type NetSockstatProtocol struct { - Protocol string - InUse int - Orphan *int - TW *int - Alloc *int - Mem *int - Memory *int -} - -// NetSockstat retrieves IPv4 socket statistics. -func (fs FS) NetSockstat() (*NetSockstat, error) { - return readSockstat(fs.proc.Path("net", "sockstat")) -} - -// NetSockstat6 retrieves IPv6 socket statistics. -// -// If IPv6 is disabled on this kernel, the returned error can be checked with -// os.IsNotExist. -func (fs FS) NetSockstat6() (*NetSockstat, error) { - return readSockstat(fs.proc.Path("net", "sockstat6")) -} - -// readSockstat opens and parses a NetSockstat from the input file. -func readSockstat(name string) (*NetSockstat, error) { - // This file is small and can be read with one syscall. - b, err := util.ReadFileNoStat(name) - if err != nil { - // Do not wrap this error so the caller can detect os.IsNotExist and - // similar conditions. - return nil, err - } - - stat, err := parseSockstat(bytes.NewReader(b)) - if err != nil { - return nil, fmt.Errorf("%w: sockstats from %q: %w", ErrFileRead, name, err) - } - - return stat, nil -} - -// parseSockstat reads the contents of a sockstat file and parses a NetSockstat. -func parseSockstat(r io.Reader) (*NetSockstat, error) { - var stat NetSockstat - s := bufio.NewScanner(r) - for s.Scan() { - // Expect a minimum of a protocol and one key/value pair. - fields := strings.Split(s.Text(), " ") - if len(fields) < 3 { - return nil, fmt.Errorf("%w: Malformed sockstat line: %q", ErrFileParse, s.Text()) - } - - // The remaining fields are key/value pairs. - kvs, err := parseSockstatKVs(fields[1:]) - if err != nil { - return nil, fmt.Errorf("%w: sockstat key/value pairs from %q: %w", ErrFileParse, s.Text(), err) - } - - // The first field is the protocol. We must trim its colon suffix. - proto := strings.TrimSuffix(fields[0], ":") - switch proto { - case "sockets": - // Special case: IPv4 has a sockets "used" key/value pair that we - // embed at the top level of the structure. - used := kvs["used"] - stat.Used = &used - default: - // Parse all other lines as individual protocols. - nsp := parseSockstatProtocol(kvs) - nsp.Protocol = proto - stat.Protocols = append(stat.Protocols, nsp) - } - } - - if err := s.Err(); err != nil { - return nil, err - } - - return &stat, nil -} - -// parseSockstatKVs parses a string slice into a map of key/value pairs. -func parseSockstatKVs(kvs []string) (map[string]int, error) { - if len(kvs)%2 != 0 { - return nil, fmt.Errorf("%w:: Odd number of fields in key/value pairs %q", ErrFileParse, kvs) - } - - // Iterate two values at a time to gather key/value pairs. - out := make(map[string]int, len(kvs)/2) - for i := 0; i < len(kvs); i += 2 { - vp := util.NewValueParser(kvs[i+1]) - out[kvs[i]] = vp.Int() - - if err := vp.Err(); err != nil { - return nil, err - } - } - - return out, nil -} - -// parseSockstatProtocol parses a NetSockstatProtocol from the input kvs map. -func parseSockstatProtocol(kvs map[string]int) NetSockstatProtocol { - var nsp NetSockstatProtocol - for k, v := range kvs { - switch k { - case "inuse": - nsp.InUse = v - case "orphan": - nsp.Orphan = &v - case "tw": - nsp.TW = &v - case "alloc": - nsp.Alloc = &v - case "mem": - nsp.Mem = &v - case "memory": - nsp.Memory = &v - } - } - - return nsp -} diff --git a/vendor/github.com/prometheus/procfs/net_softnet.go b/vendor/github.com/prometheus/procfs/net_softnet.go deleted file mode 100644 index 4a2dfa18fd82..000000000000 --- a/vendor/github.com/prometheus/procfs/net_softnet.go +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// For the proc file format details, -// See: -// * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343 -// * Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086 -// * Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162 -// * Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169 - -// SoftnetStat contains a single row of data from /proc/net/softnet_stat. -type SoftnetStat struct { - // Number of processed packets. - Processed uint32 - // Number of dropped packets. - Dropped uint32 - // Number of times processing packets ran out of quota. - TimeSqueezed uint32 - // Number of collision occur while obtaining device lock while transmitting. - CPUCollision uint32 - // Number of times cpu woken up received_rps. - ReceivedRps uint32 - // number of times flow limit has been reached. - FlowLimitCount uint32 - // Softnet backlog status. - SoftnetBacklogLen uint32 - // CPU id owning this softnet_data. - Index uint32 - // softnet_data's Width. - Width int -} - -var softNetProcFile = "net/softnet_stat" - -// NetSoftnetStat reads data from /proc/net/softnet_stat. -func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) { - b, err := util.ReadFileNoStat(fs.proc.Path(softNetProcFile)) - if err != nil { - return nil, err - } - - entries, err := parseSoftnet(bytes.NewReader(b)) - if err != nil { - return nil, fmt.Errorf("%w: /proc/net/softnet_stat: %w", ErrFileParse, err) - } - - return entries, nil -} - -func parseSoftnet(r io.Reader) ([]SoftnetStat, error) { - const minColumns = 9 - - s := bufio.NewScanner(r) - - var stats []SoftnetStat - cpuIndex := 0 - for s.Scan() { - columns := strings.Fields(s.Text()) - width := len(columns) - softnetStat := SoftnetStat{} - - if width < minColumns { - return nil, fmt.Errorf("%w: detected %d columns, but expected at least %d", ErrFileParse, width, minColumns) - } - - // Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2347 - if width >= minColumns { - us, err := parseHexUint32s(columns[0:9]) - if err != nil { - return nil, err - } - - softnetStat.Processed = us[0] - softnetStat.Dropped = us[1] - softnetStat.TimeSqueezed = us[2] - softnetStat.CPUCollision = us[8] - } - - // Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086 - if width >= 10 { - us, err := parseHexUint32s(columns[9:10]) - if err != nil { - return nil, err - } - - softnetStat.ReceivedRps = us[0] - } - - // Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162 - if width >= 11 { - us, err := parseHexUint32s(columns[10:11]) - if err != nil { - return nil, err - } - - softnetStat.FlowLimitCount = us[0] - } - - // Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169 - if width >= 13 { - us, err := parseHexUint32s(columns[11:13]) - if err != nil { - return nil, err - } - - softnetStat.SoftnetBacklogLen = us[0] - softnetStat.Index = us[1] - } else { - // For older kernels, create the Index based on the scan line number. - softnetStat.Index = uint32(cpuIndex) - } - softnetStat.Width = width - stats = append(stats, softnetStat) - cpuIndex++ - } - - return stats, nil -} - -func parseHexUint32s(ss []string) ([]uint32, error) { - us := make([]uint32, 0, len(ss)) - for _, s := range ss { - u, err := strconv.ParseUint(s, 16, 32) - if err != nil { - return nil, err - } - - us = append(us, uint32(u)) - } - - return us, nil -} diff --git a/vendor/github.com/prometheus/procfs/net_tcp.go b/vendor/github.com/prometheus/procfs/net_tcp.go deleted file mode 100644 index 2c7f9bc7c315..000000000000 --- a/vendor/github.com/prometheus/procfs/net_tcp.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -type ( - // NetTCP represents the contents of /proc/net/tcp{,6} file without the header. - NetTCP []*netIPSocketLine - - // NetTCPSummary provides already computed values like the total queue lengths or - // the total number of used sockets. In contrast to NetTCP it does not collect - // the parsed lines into a slice. - NetTCPSummary NetIPSocketSummary -) - -// NetTCP returns the IPv4 kernel/networking statistics for TCP datagrams -// read from /proc/net/tcp. -// -// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET) instead. -func (fs FS) NetTCP() (NetTCP, error) { - return newNetTCP(fs.proc.Path("net/tcp")) -} - -// NetTCP6 returns the IPv6 kernel/networking statistics for TCP datagrams -// read from /proc/net/tcp6. -// -// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET6) instead. -func (fs FS) NetTCP6() (NetTCP, error) { - return newNetTCP(fs.proc.Path("net/tcp6")) -} - -// NetTCPSummary returns already computed statistics like the total queue lengths -// for TCP datagrams read from /proc/net/tcp. -// -// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET) instead. -func (fs FS) NetTCPSummary() (*NetTCPSummary, error) { - return newNetTCPSummary(fs.proc.Path("net/tcp")) -} - -// NetTCP6Summary returns already computed statistics like the total queue lengths -// for TCP datagrams read from /proc/net/tcp6. -// -// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET6) instead. -func (fs FS) NetTCP6Summary() (*NetTCPSummary, error) { - return newNetTCPSummary(fs.proc.Path("net/tcp6")) -} - -// newNetTCP creates a new NetTCP{,6} from the contents of the given file. -func newNetTCP(file string) (NetTCP, error) { - n, err := newNetIPSocket(file) - n1 := NetTCP(n) - return n1, err -} - -func newNetTCPSummary(file string) (*NetTCPSummary, error) { - n, err := newNetIPSocketSummary(file) - if n == nil { - return nil, err - } - n1 := NetTCPSummary(*n) - return &n1, err -} diff --git a/vendor/github.com/prometheus/procfs/net_tls_stat.go b/vendor/github.com/prometheus/procfs/net_tls_stat.go deleted file mode 100644 index b1b3f6a6a2f5..000000000000 --- a/vendor/github.com/prometheus/procfs/net_tls_stat.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -// TLSStat struct represents data in /proc/net/tls_stat. -// See https://docs.kernel.org/networking/tls.html#statistics -type TLSStat struct { - // number of TX sessions currently installed where host handles cryptography - TLSCurrTxSw int - // number of RX sessions currently installed where host handles cryptography - TLSCurrRxSw int - // number of TX sessions currently installed where NIC handles cryptography - TLSCurrTxDevice int - // number of RX sessions currently installed where NIC handles cryptography - TLSCurrRxDevice int - //number of TX sessions opened with host cryptography - TLSTxSw int - //number of RX sessions opened with host cryptography - TLSRxSw int - // number of TX sessions opened with NIC cryptography - TLSTxDevice int - // number of RX sessions opened with NIC cryptography - TLSRxDevice int - // record decryption failed (e.g. due to incorrect authentication tag) - TLSDecryptError int - // number of RX resyncs sent to NICs handling cryptography - TLSRxDeviceResync int - // number of RX records which had to be re-decrypted due to TLS_RX_EXPECT_NO_PAD mis-prediction. Note that this counter will also increment for non-data records. - TLSDecryptRetry int - // number of data RX records which had to be re-decrypted due to TLS_RX_EXPECT_NO_PAD mis-prediction. - TLSRxNoPadViolation int -} - -// NewTLSStat reads the tls_stat statistics. -func NewTLSStat() (TLSStat, error) { - fs, err := NewFS(DefaultMountPoint) - if err != nil { - return TLSStat{}, err - } - - return fs.NewTLSStat() -} - -// NewTLSStat reads the tls_stat statistics. -func (fs FS) NewTLSStat() (TLSStat, error) { - file, err := os.Open(fs.proc.Path("net/tls_stat")) - if err != nil { - return TLSStat{}, err - } - defer file.Close() - - var ( - tlsstat = TLSStat{} - s = bufio.NewScanner(file) - ) - - for s.Scan() { - fields := strings.Fields(s.Text()) - - if len(fields) != 2 { - return TLSStat{}, fmt.Errorf("%w: %q line %q", ErrFileParse, file.Name(), s.Text()) - } - - name := fields[0] - value, err := strconv.Atoi(fields[1]) - if err != nil { - return TLSStat{}, err - } - - switch name { - case "TlsCurrTxSw": - tlsstat.TLSCurrTxSw = value - case "TlsCurrRxSw": - tlsstat.TLSCurrRxSw = value - case "TlsCurrTxDevice": - tlsstat.TLSCurrTxDevice = value - case "TlsCurrRxDevice": - tlsstat.TLSCurrRxDevice = value - case "TlsTxSw": - tlsstat.TLSTxSw = value - case "TlsRxSw": - tlsstat.TLSRxSw = value - case "TlsTxDevice": - tlsstat.TLSTxDevice = value - case "TlsRxDevice": - tlsstat.TLSRxDevice = value - case "TlsDecryptError": - tlsstat.TLSDecryptError = value - case "TlsRxDeviceResync": - tlsstat.TLSRxDeviceResync = value - case "TlsDecryptRetry": - tlsstat.TLSDecryptRetry = value - case "TlsRxNoPadViolation": - tlsstat.TLSRxNoPadViolation = value - } - - } - - return tlsstat, s.Err() -} diff --git a/vendor/github.com/prometheus/procfs/net_udp.go b/vendor/github.com/prometheus/procfs/net_udp.go deleted file mode 100644 index 8a327791026a..000000000000 --- a/vendor/github.com/prometheus/procfs/net_udp.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -type ( - // NetUDP represents the contents of /proc/net/udp{,6} file without the header. - NetUDP []*netIPSocketLine - - // NetUDPSummary provides already computed values like the total queue lengths or - // the total number of used sockets. In contrast to NetUDP it does not collect - // the parsed lines into a slice. - NetUDPSummary NetIPSocketSummary -) - -// NetUDP returns the IPv4 kernel/networking statistics for UDP datagrams -// read from /proc/net/udp. -func (fs FS) NetUDP() (NetUDP, error) { - return newNetUDP(fs.proc.Path("net/udp")) -} - -// NetUDP6 returns the IPv6 kernel/networking statistics for UDP datagrams -// read from /proc/net/udp6. -func (fs FS) NetUDP6() (NetUDP, error) { - return newNetUDP(fs.proc.Path("net/udp6")) -} - -// NetUDPSummary returns already computed statistics like the total queue lengths -// for UDP datagrams read from /proc/net/udp. -func (fs FS) NetUDPSummary() (*NetUDPSummary, error) { - return newNetUDPSummary(fs.proc.Path("net/udp")) -} - -// NetUDP6Summary returns already computed statistics like the total queue lengths -// for UDP datagrams read from /proc/net/udp6. -func (fs FS) NetUDP6Summary() (*NetUDPSummary, error) { - return newNetUDPSummary(fs.proc.Path("net/udp6")) -} - -// newNetUDP creates a new NetUDP{,6} from the contents of the given file. -func newNetUDP(file string) (NetUDP, error) { - n, err := newNetIPSocket(file) - n1 := NetUDP(n) - return n1, err -} - -func newNetUDPSummary(file string) (*NetUDPSummary, error) { - n, err := newNetIPSocketSummary(file) - if n == nil { - return nil, err - } - n1 := NetUDPSummary(*n) - return &n1, err -} diff --git a/vendor/github.com/prometheus/procfs/net_unix.go b/vendor/github.com/prometheus/procfs/net_unix.go deleted file mode 100644 index e4d635923659..000000000000 --- a/vendor/github.com/prometheus/procfs/net_unix.go +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "fmt" - "io" - "os" - "strconv" - "strings" -) - -// For the proc file format details, -// see https://elixir.bootlin.com/linux/v4.17/source/net/unix/af_unix.c#L2815 -// and https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net.h#L48. - -// Constants for the various /proc/net/unix enumerations. -// TODO: match against x/sys/unix or similar? -const ( - netUnixTypeStream = 1 - netUnixTypeDgram = 2 - netUnixTypeSeqpacket = 5 - - netUnixFlagDefault = 0 - netUnixFlagListen = 1 << 16 - - netUnixStateUnconnected = 1 - netUnixStateConnecting = 2 - netUnixStateConnected = 3 - netUnixStateDisconnected = 4 -) - -// NetUNIXType is the type of the type field. -type NetUNIXType uint64 - -// NetUNIXFlags is the type of the flags field. -type NetUNIXFlags uint64 - -// NetUNIXState is the type of the state field. -type NetUNIXState uint64 - -// NetUNIXLine represents a line of /proc/net/unix. -type NetUNIXLine struct { - KernelPtr string - RefCount uint64 - Protocol uint64 - Flags NetUNIXFlags - Type NetUNIXType - State NetUNIXState - Inode uint64 - Path string -} - -// NetUNIX holds the data read from /proc/net/unix. -type NetUNIX struct { - Rows []*NetUNIXLine -} - -// NetUNIX returns data read from /proc/net/unix. -func (fs FS) NetUNIX() (*NetUNIX, error) { - return readNetUNIX(fs.proc.Path("net/unix")) -} - -// readNetUNIX reads data in /proc/net/unix format from the specified file. -func readNetUNIX(file string) (*NetUNIX, error) { - // This file could be quite large and a streaming read is desirable versus - // reading the entire contents at once. - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - - return parseNetUNIX(f) -} - -// parseNetUNIX creates a NetUnix structure from the incoming stream. -func parseNetUNIX(r io.Reader) (*NetUNIX, error) { - // Begin scanning by checking for the existence of Inode. - s := bufio.NewScanner(r) - s.Scan() - - // From the man page of proc(5), it does not contain an Inode field, - // but in actually it exists. This code works for both cases. - hasInode := strings.Contains(s.Text(), "Inode") - - // Expect a minimum number of fields, but Inode and Path are optional: - // Num RefCount Protocol Flags Type St Inode Path - minFields := 6 - if hasInode { - minFields++ - } - - var nu NetUNIX - for s.Scan() { - line := s.Text() - item, err := nu.parseLine(line, hasInode, minFields) - if err != nil { - return nil, fmt.Errorf("%w: /proc/net/unix encountered data %q: %w", ErrFileParse, line, err) - } - - nu.Rows = append(nu.Rows, item) - } - - if err := s.Err(); err != nil { - return nil, fmt.Errorf("%w: /proc/net/unix encountered data: %w", ErrFileParse, err) - } - - return &nu, nil -} - -func (u *NetUNIX) parseLine(line string, hasInode bool, minFields int) (*NetUNIXLine, error) { - fields := strings.Fields(line) - - l := len(fields) - if l < minFields { - return nil, fmt.Errorf("%w: expected at least %d fields but got %d", ErrFileParse, minFields, l) - } - - // Field offsets are as follows: - // Num RefCount Protocol Flags Type St Inode Path - - kernelPtr := strings.TrimSuffix(fields[0], ":") - - users, err := u.parseUsers(fields[1]) - if err != nil { - return nil, fmt.Errorf("%w: ref count %q: %w", ErrFileParse, fields[1], err) - } - - flags, err := u.parseFlags(fields[3]) - if err != nil { - return nil, fmt.Errorf("%w: Unable to parse flags %q: %w", ErrFileParse, fields[3], err) - } - - typ, err := u.parseType(fields[4]) - if err != nil { - return nil, fmt.Errorf("%w: Failed to parse type %q: %w", ErrFileParse, fields[4], err) - } - - state, err := u.parseState(fields[5]) - if err != nil { - return nil, fmt.Errorf("%w: Failed to parse state %q: %w", ErrFileParse, fields[5], err) - } - - var inode uint64 - if hasInode { - inode, err = u.parseInode(fields[6]) - if err != nil { - return nil, fmt.Errorf("%w failed to parse inode %q: %w", ErrFileParse, fields[6], err) - } - } - - n := &NetUNIXLine{ - KernelPtr: kernelPtr, - RefCount: users, - Type: typ, - Flags: flags, - State: state, - Inode: inode, - } - - // Path field is optional. - if l > minFields { - // Path occurs at either index 6 or 7 depending on whether inode is - // already present. - pathIdx := 7 - if !hasInode { - pathIdx-- - } - - n.Path = fields[pathIdx] - } - - return n, nil -} - -func (u NetUNIX) parseUsers(s string) (uint64, error) { - return strconv.ParseUint(s, 16, 32) -} - -func (u NetUNIX) parseType(s string) (NetUNIXType, error) { - typ, err := strconv.ParseUint(s, 16, 16) - if err != nil { - return 0, err - } - - return NetUNIXType(typ), nil -} - -func (u NetUNIX) parseFlags(s string) (NetUNIXFlags, error) { - flags, err := strconv.ParseUint(s, 16, 32) - if err != nil { - return 0, err - } - - return NetUNIXFlags(flags), nil -} - -func (u NetUNIX) parseState(s string) (NetUNIXState, error) { - st, err := strconv.ParseInt(s, 16, 8) - if err != nil { - return 0, err - } - - return NetUNIXState(st), nil -} - -func (u NetUNIX) parseInode(s string) (uint64, error) { - return strconv.ParseUint(s, 10, 64) -} - -func (t NetUNIXType) String() string { - switch t { - case netUnixTypeStream: - return "stream" - case netUnixTypeDgram: - return "dgram" - case netUnixTypeSeqpacket: - return "seqpacket" - } - return "unknown" -} - -func (f NetUNIXFlags) String() string { - switch f { - case netUnixFlagListen: - return "listen" - default: - return "default" - } -} - -func (s NetUNIXState) String() string { - switch s { - case netUnixStateUnconnected: - return "unconnected" - case netUnixStateConnecting: - return "connecting" - case netUnixStateConnected: - return "connected" - case netUnixStateDisconnected: - return "disconnected" - } - return "unknown" -} diff --git a/vendor/github.com/prometheus/procfs/net_wireless.go b/vendor/github.com/prometheus/procfs/net_wireless.go deleted file mode 100644 index 69d079445161..000000000000 --- a/vendor/github.com/prometheus/procfs/net_wireless.go +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Wireless models the content of /proc/net/wireless. -type Wireless struct { - Name string - - // Status is the current 4-digit hex value status of the interface. - Status uint64 - - // QualityLink is the link quality. - QualityLink int - - // QualityLevel is the signal gain (dBm). - QualityLevel int - - // QualityNoise is the signal noise baseline (dBm). - QualityNoise int - - // DiscardedNwid is the number of discarded packets with wrong nwid/essid. - DiscardedNwid int - - // DiscardedCrypt is the number of discarded packets with wrong code/decode (WEP). - DiscardedCrypt int - - // DiscardedFrag is the number of discarded packets that can't perform MAC reassembly. - DiscardedFrag int - - // DiscardedRetry is the number of discarded packets that reached max MAC retries. - DiscardedRetry int - - // DiscardedMisc is the number of discarded packets for other reasons. - DiscardedMisc int - - // MissedBeacon is the number of missed beacons/superframe. - MissedBeacon int -} - -// Wireless returns kernel wireless statistics. -func (fs FS) Wireless() ([]*Wireless, error) { - b, err := util.ReadFileNoStat(fs.proc.Path("net/wireless")) - if err != nil { - return nil, err - } - - m, err := parseWireless(bytes.NewReader(b)) - if err != nil { - return nil, fmt.Errorf("%w: wireless: %w", ErrFileParse, err) - } - - return m, nil -} - -// parseWireless parses the contents of /proc/net/wireless. -/* -Inter-| sta-| Quality | Discarded packets | Missed | WE -face | tus | link level noise | nwid crypt frag retry misc | beacon | 22 - eth1: 0000 5. -256. -10. 0 1 0 3 0 0 - eth2: 0000 5. -256. -20. 0 2 0 4 0 0 -*/ -func parseWireless(r io.Reader) ([]*Wireless, error) { - var ( - interfaces []*Wireless - scanner = bufio.NewScanner(r) - ) - - for n := 0; scanner.Scan(); n++ { - // Skip the 2 header lines. - if n < 2 { - continue - } - - line := scanner.Text() - - parts := strings.Split(line, ":") - if len(parts) != 2 { - return nil, fmt.Errorf("%w: expected 2 parts after splitting line by ':', got %d for line %q", ErrFileParse, len(parts), line) - } - - name := strings.TrimSpace(parts[0]) - stats := strings.Fields(parts[1]) - - if len(stats) < 10 { - return nil, fmt.Errorf("%w: invalid number of fields in line %d, expected 10+, got %d: %q", ErrFileParse, n, len(stats), line) - } - - status, err := strconv.ParseUint(stats[0], 16, 16) - if err != nil { - return nil, fmt.Errorf("%w: invalid status in line %d: %q", ErrFileParse, n, line) - } - - qlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], ".")) - if err != nil { - return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, qlink, err) - } - - qlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], ".")) - if err != nil { - return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, qlevel, err) - } - - qnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], ".")) - if err != nil { - return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, qnoise, err) - } - - dnwid, err := strconv.Atoi(stats[4]) - if err != nil { - return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, dnwid, err) - } - - dcrypt, err := strconv.Atoi(stats[5]) - if err != nil { - return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, dcrypt, err) - } - - dfrag, err := strconv.Atoi(stats[6]) - if err != nil { - return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, dfrag, err) - } - - dretry, err := strconv.Atoi(stats[7]) - if err != nil { - return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, dretry, err) - } - - dmisc, err := strconv.Atoi(stats[8]) - if err != nil { - return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, dmisc, err) - } - - mbeacon, err := strconv.Atoi(stats[9]) - if err != nil { - return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, mbeacon, err) - } - - w := &Wireless{ - Name: name, - Status: status, - QualityLink: qlink, - QualityLevel: qlevel, - QualityNoise: qnoise, - DiscardedNwid: dnwid, - DiscardedCrypt: dcrypt, - DiscardedFrag: dfrag, - DiscardedRetry: dretry, - DiscardedMisc: dmisc, - MissedBeacon: mbeacon, - } - - interfaces = append(interfaces, w) - } - - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("%w: Failed to scan /proc/net/wireless: %w", ErrFileRead, err) - } - - return interfaces, nil -} diff --git a/vendor/github.com/prometheus/procfs/net_xfrm.go b/vendor/github.com/prometheus/procfs/net_xfrm.go deleted file mode 100644 index 5a9f497d1903..000000000000 --- a/vendor/github.com/prometheus/procfs/net_xfrm.go +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -// XfrmStat models the contents of /proc/net/xfrm_stat. -type XfrmStat struct { - // All errors which are not matched by other - XfrmInError int - // No buffer is left - XfrmInBufferError int - // Header Error - XfrmInHdrError int - // No state found - // i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong - XfrmInNoStates int - // Transformation protocol specific error - // e.g. SA Key is wrong - XfrmInStateProtoError int - // Transformation mode specific error - XfrmInStateModeError int - // Sequence error - // e.g. sequence number is out of window - XfrmInStateSeqError int - // State is expired - XfrmInStateExpired int - // State has mismatch option - // e.g. UDP encapsulation type is mismatched - XfrmInStateMismatch int - // State is invalid - XfrmInStateInvalid int - // No matching template for states - // e.g. Inbound SAs are correct but SP rule is wrong - XfrmInTmplMismatch int - // No policy is found for states - // e.g. Inbound SAs are correct but no SP is found - XfrmInNoPols int - // Policy discards - XfrmInPolBlock int - // Policy error - XfrmInPolError int - // All errors which are not matched by others - XfrmOutError int - // Bundle generation error - XfrmOutBundleGenError int - // Bundle check error - XfrmOutBundleCheckError int - // No state was found - XfrmOutNoStates int - // Transformation protocol specific error - XfrmOutStateProtoError int - // Transportation mode specific error - XfrmOutStateModeError int - // Sequence error - // i.e sequence number overflow - XfrmOutStateSeqError int - // State is expired - XfrmOutStateExpired int - // Policy discads - XfrmOutPolBlock int - // Policy is dead - XfrmOutPolDead int - // Policy Error - XfrmOutPolError int - // Forward routing of a packet is not allowed - XfrmFwdHdrError int - // State is invalid, perhaps expired - XfrmOutStateInvalid int - // State hasn’t been fully acquired before use - XfrmAcquireError int -} - -// NewXfrmStat reads the xfrm_stat statistics. -func NewXfrmStat() (XfrmStat, error) { - fs, err := NewFS(DefaultMountPoint) - if err != nil { - return XfrmStat{}, err - } - - return fs.NewXfrmStat() -} - -// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem. -func (fs FS) NewXfrmStat() (XfrmStat, error) { - file, err := os.Open(fs.proc.Path("net/xfrm_stat")) - if err != nil { - return XfrmStat{}, err - } - defer file.Close() - - var ( - x = XfrmStat{} - s = bufio.NewScanner(file) - ) - - for s.Scan() { - fields := strings.Fields(s.Text()) - - if len(fields) != 2 { - return XfrmStat{}, fmt.Errorf("%w: %q line %q", ErrFileParse, file.Name(), s.Text()) - } - - name := fields[0] - value, err := strconv.Atoi(fields[1]) - if err != nil { - return XfrmStat{}, err - } - - switch name { - case "XfrmInError": - x.XfrmInError = value - case "XfrmInBufferError": - x.XfrmInBufferError = value - case "XfrmInHdrError": - x.XfrmInHdrError = value - case "XfrmInNoStates": - x.XfrmInNoStates = value - case "XfrmInStateProtoError": - x.XfrmInStateProtoError = value - case "XfrmInStateModeError": - x.XfrmInStateModeError = value - case "XfrmInStateSeqError": - x.XfrmInStateSeqError = value - case "XfrmInStateExpired": - x.XfrmInStateExpired = value - case "XfrmInStateInvalid": - x.XfrmInStateInvalid = value - case "XfrmInTmplMismatch": - x.XfrmInTmplMismatch = value - case "XfrmInNoPols": - x.XfrmInNoPols = value - case "XfrmInPolBlock": - x.XfrmInPolBlock = value - case "XfrmInPolError": - x.XfrmInPolError = value - case "XfrmOutError": - x.XfrmOutError = value - case "XfrmInStateMismatch": - x.XfrmInStateMismatch = value - case "XfrmOutBundleGenError": - x.XfrmOutBundleGenError = value - case "XfrmOutBundleCheckError": - x.XfrmOutBundleCheckError = value - case "XfrmOutNoStates": - x.XfrmOutNoStates = value - case "XfrmOutStateProtoError": - x.XfrmOutStateProtoError = value - case "XfrmOutStateModeError": - x.XfrmOutStateModeError = value - case "XfrmOutStateSeqError": - x.XfrmOutStateSeqError = value - case "XfrmOutStateExpired": - x.XfrmOutStateExpired = value - case "XfrmOutPolBlock": - x.XfrmOutPolBlock = value - case "XfrmOutPolDead": - x.XfrmOutPolDead = value - case "XfrmOutPolError": - x.XfrmOutPolError = value - case "XfrmFwdHdrError": - x.XfrmFwdHdrError = value - case "XfrmOutStateInvalid": - x.XfrmOutStateInvalid = value - case "XfrmAcquireError": - x.XfrmAcquireError = value - } - - } - - return x, s.Err() -} diff --git a/vendor/github.com/prometheus/procfs/netstat.go b/vendor/github.com/prometheus/procfs/netstat.go deleted file mode 100644 index dbdae473924b..000000000000 --- a/vendor/github.com/prometheus/procfs/netstat.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "os" - "path/filepath" - "strconv" - "strings" -) - -// NetStat contains statistics for all the counters from one file. -type NetStat struct { - Stats map[string][]uint64 - Filename string -} - -// NetStat retrieves stats from `/proc/net/stat/`. -func (fs FS) NetStat() ([]NetStat, error) { - statFiles, err := filepath.Glob(fs.proc.Path("net/stat/*")) - if err != nil { - return nil, err - } - - var netStatsTotal []NetStat - - for _, filePath := range statFiles { - procNetstat, err := parseNetstat(filePath) - if err != nil { - return nil, err - } - procNetstat.Filename = filepath.Base(filePath) - - netStatsTotal = append(netStatsTotal, procNetstat) - } - return netStatsTotal, nil -} - -// parseNetstat parses the metrics from `/proc/net/stat/` file -// and returns a NetStat structure. -func parseNetstat(filePath string) (NetStat, error) { - netStat := NetStat{ - Stats: make(map[string][]uint64), - } - file, err := os.Open(filePath) - if err != nil { - return netStat, err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - scanner.Scan() - - // First string is always a header for stats - var headers []string - headers = append(headers, strings.Fields(scanner.Text())...) - - // Other strings represent per-CPU counters - for scanner.Scan() { - for num, counter := range strings.Fields(scanner.Text()) { - value, err := strconv.ParseUint(counter, 16, 64) - if err != nil { - return NetStat{}, err - } - netStat.Stats[headers[num]] = append(netStat.Stats[headers[num]], value) - } - } - - return netStat, nil -} diff --git a/vendor/github.com/prometheus/procfs/nfnetlink_queue.go b/vendor/github.com/prometheus/procfs/nfnetlink_queue.go deleted file mode 100644 index b0a73b11e9e4..000000000000 --- a/vendor/github.com/prometheus/procfs/nfnetlink_queue.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - - "github.com/prometheus/procfs/internal/util" -) - -const nfNetLinkQueueFormat = "%d %d %d %d %d %d %d %d %d" - -// NFNetLinkQueue contains general information about netfilter queues found in /proc/net/netfilter/nfnetlink_queue. -type NFNetLinkQueue struct { - // id of the queue - QueueID uint - // pid of process handling the queue - PeerPID uint - // number of packets waiting for a decision - QueueTotal uint - // indicate how userspace receive packets - CopyMode uint - // size of copy - CopyRange uint - // number of items dropped by the kernel because too many packets were waiting a decision. - // It queue_total is superior to queue_max_len (1024 per default) the packets are dropped. - QueueDropped uint - // number of packets dropped by userspace (due to kernel send failure on the netlink socket) - QueueUserDropped uint - // sequence number of packets queued. It gives a correct approximation of the number of queued packets. - SequenceID uint - // internal value (number of entity using the queue) - Use uint -} - -// NFNetLinkQueue returns information about current state of netfilter queues. -func (fs FS) NFNetLinkQueue() ([]NFNetLinkQueue, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("net/netfilter/nfnetlink_queue")) - if err != nil { - return nil, err - } - - queue := []NFNetLinkQueue{} - if len(data) == 0 { - return queue, nil - } - - scanner := bufio.NewScanner(bytes.NewReader(data)) - for scanner.Scan() { - line := scanner.Text() - nFNetLinkQueue, err := parseNFNetLinkQueueLine(line) - if err != nil { - return nil, err - } - queue = append(queue, *nFNetLinkQueue) - } - return queue, nil -} - -// parseNFNetLinkQueueLine parses each line of the /proc/net/netfilter/nfnetlink_queue file. -func parseNFNetLinkQueueLine(line string) (*NFNetLinkQueue, error) { - nFNetLinkQueue := NFNetLinkQueue{} - _, err := fmt.Sscanf( - line, nfNetLinkQueueFormat, - &nFNetLinkQueue.QueueID, &nFNetLinkQueue.PeerPID, &nFNetLinkQueue.QueueTotal, &nFNetLinkQueue.CopyMode, - &nFNetLinkQueue.CopyRange, &nFNetLinkQueue.QueueDropped, &nFNetLinkQueue.QueueUserDropped, &nFNetLinkQueue.SequenceID, &nFNetLinkQueue.Use, - ) - if err != nil { - return nil, err - } - return &nFNetLinkQueue, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go deleted file mode 100644 index 39c14aa55ebd..000000000000 --- a/vendor/github.com/prometheus/procfs/proc.go +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bytes" - "errors" - "fmt" - "io" - "os" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Proc provides information about a running process. -type Proc struct { - // The process ID. - PID int - - fs FS -} - -// Procs represents a list of Proc structs. -type Procs []Proc - -var ( - ErrFileParse = errors.New("error parsing file") - ErrFileRead = errors.New("error reading file") - ErrMountPoint = errors.New("error accessing mount point") -) - -func (p Procs) Len() int { return len(p) } -func (p Procs) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID } - -// Self returns a process for the current process read via /proc/self. -func Self() (Proc, error) { - fs, err := NewFS(DefaultMountPoint) - if err != nil || errors.Is(err, ErrMountPoint) { - return Proc{}, err - } - return fs.Self() -} - -// NewProc returns a process for the given pid under /proc. -func NewProc(pid int) (Proc, error) { - fs, err := NewFS(DefaultMountPoint) - if err != nil { - return Proc{}, err - } - return fs.Proc(pid) -} - -// AllProcs returns a list of all currently available processes under /proc. -func AllProcs() (Procs, error) { - fs, err := NewFS(DefaultMountPoint) - if err != nil { - return Procs{}, err - } - return fs.AllProcs() -} - -// Self returns a process for the current process. -func (fs FS) Self() (Proc, error) { - p, err := os.Readlink(fs.proc.Path("self")) - if err != nil { - return Proc{}, err - } - pid, err := strconv.Atoi(strings.ReplaceAll(p, string(fs.proc), "")) - if err != nil { - return Proc{}, err - } - return fs.Proc(pid) -} - -// NewProc returns a process for the given pid. -// -// Deprecated: Use fs.Proc() instead. -func (fs FS) NewProc(pid int) (Proc, error) { - return fs.Proc(pid) -} - -// Proc returns a process for the given pid. -func (fs FS) Proc(pid int) (Proc, error) { - if _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil { - return Proc{}, err - } - return Proc{PID: pid, fs: fs}, nil -} - -// AllProcs returns a list of all currently available processes. -func (fs FS) AllProcs() (Procs, error) { - d, err := os.Open(fs.proc.Path()) - if err != nil { - return Procs{}, err - } - defer d.Close() - - names, err := d.Readdirnames(-1) - if err != nil { - return Procs{}, fmt.Errorf("%w: Cannot read file: %v: %w", ErrFileRead, names, err) - } - - p := Procs{} - for _, n := range names { - pid, err := strconv.ParseInt(n, 10, 64) - if err != nil { - continue - } - p = append(p, Proc{PID: int(pid), fs: fs}) - } - - return p, nil -} - -// CmdLine returns the command line of a process. -func (p Proc) CmdLine() ([]string, error) { - data, err := util.ReadFileNoStat(p.path("cmdline")) - if err != nil { - return nil, err - } - - if len(data) < 1 { - return []string{}, nil - } - - return strings.Split(string(bytes.TrimRight(data, "\x00")), "\x00"), nil -} - -// Wchan returns the wchan (wait channel) of a process. -func (p Proc) Wchan() (string, error) { - f, err := os.Open(p.path("wchan")) - if err != nil { - return "", err - } - defer f.Close() - - data, err := io.ReadAll(f) - if err != nil { - return "", err - } - - wchan := string(data) - if wchan == "" || wchan == "0" { - return "", nil - } - - return wchan, nil -} - -// Comm returns the command name of a process. -func (p Proc) Comm() (string, error) { - data, err := util.ReadFileNoStat(p.path("comm")) - if err != nil { - return "", err - } - - return strings.TrimSpace(string(data)), nil -} - -// Executable returns the absolute path of the executable command of a process. -func (p Proc) Executable() (string, error) { - exe, err := os.Readlink(p.path("exe")) - if os.IsNotExist(err) { - return "", nil - } - - return exe, err -} - -// Cwd returns the absolute path to the current working directory of the process. -func (p Proc) Cwd() (string, error) { - wd, err := os.Readlink(p.path("cwd")) - if os.IsNotExist(err) { - return "", nil - } - - return wd, err -} - -// RootDir returns the absolute path to the process's root directory (as set by chroot). -func (p Proc) RootDir() (string, error) { - rdir, err := os.Readlink(p.path("root")) - if os.IsNotExist(err) { - return "", nil - } - - return rdir, err -} - -// FileDescriptors returns the currently open file descriptors of a process. -func (p Proc) FileDescriptors() ([]uintptr, error) { - names, err := p.fileDescriptors() - if err != nil { - return nil, err - } - - fds := make([]uintptr, len(names)) - for i, n := range names { - fd, err := strconv.ParseInt(n, 10, 32) - if err != nil { - return nil, fmt.Errorf("%w: Cannot parse line: %v: %w", ErrFileParse, i, err) - } - fds[i] = uintptr(fd) - } - - return fds, nil -} - -// FileDescriptorTargets returns the targets of all file descriptors of a process. -// If a file descriptor is not a symlink to a file (like a socket), that value will be the empty string. -func (p Proc) FileDescriptorTargets() ([]string, error) { - names, err := p.fileDescriptors() - if err != nil { - return nil, err - } - - targets := make([]string, len(names)) - - for i, name := range names { - target, err := os.Readlink(p.path("fd", name)) - if err == nil { - targets[i] = target - } - } - - return targets, nil -} - -// FileDescriptorsLen returns the number of currently open file descriptors of -// a process. -func (p Proc) FileDescriptorsLen() (int, error) { - // Use fast path if available (Linux v6.2): https://github.com/torvalds/linux/commit/f1f1f2569901 - if p.fs.isReal { - stat, err := os.Stat(p.path("fd")) - if err != nil { - return 0, err - } - - size := stat.Size() - if size > 0 { - return int(size), nil - } - } - - fds, err := p.fileDescriptors() - if err != nil { - return 0, err - } - - return len(fds), nil -} - -// MountStats retrieves statistics and configuration for mount points in a -// process's namespace. -func (p Proc) MountStats() ([]*Mount, error) { - f, err := os.Open(p.path("mountstats")) - if err != nil { - return nil, err - } - defer f.Close() - - return parseMountStats(f) -} - -// MountInfo retrieves mount information for mount points in a -// process's namespace. -// It supplies information missing in `/proc/self/mounts` and -// fixes various other problems with that file too. -func (p Proc) MountInfo() ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(p.path("mountinfo")) - if err != nil { - return nil, err - } - return parseMountInfo(data) -} - -func (p Proc) fileDescriptors() ([]string, error) { - d, err := os.Open(p.path("fd")) - if err != nil { - return nil, err - } - defer d.Close() - - names, err := d.Readdirnames(-1) - if err != nil { - return nil, fmt.Errorf("%w: Cannot read file: %v: %w", ErrFileRead, names, err) - } - - return names, nil -} - -func (p Proc) path(pa ...string) string { - return p.fs.proc.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...) -} - -// FileDescriptorsInfo retrieves information about all file descriptors of -// the process. -func (p Proc) FileDescriptorsInfo() (ProcFDInfos, error) { - names, err := p.fileDescriptors() - if err != nil { - return nil, err - } - - var fdinfos ProcFDInfos - - for _, n := range names { - fdinfo, err := p.FDInfo(n) - if err != nil { - continue - } - fdinfos = append(fdinfos, *fdinfo) - } - - return fdinfos, nil -} - -// Schedstat returns task scheduling information for the process. -func (p Proc) Schedstat() (ProcSchedstat, error) { - contents, err := os.ReadFile(p.path("schedstat")) - if err != nil { - return ProcSchedstat{}, err - } - return parseProcSchedstat(string(contents)) -} diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go deleted file mode 100644 index 535c08d6fc01..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_cgroup.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the placement of a PID inside a -// specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. The v1 has one hierarchy per available resource -// controller, while v2 has one unified hierarchy shared by all controllers. Regardless of v1 or v2, all hierarchies -// contain all running processes, so the question answerable with a Cgroup struct is 'where is this process in -// this hierarchy' (where==what path on the specific cgroupfs). By prefixing this path with the mount point of -// *this specific* hierarchy, you can locate the relevant pseudo-files needed to read/set the data for this PID -// in this hierarchy -// -// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html -type Cgroup struct { - // HierarchyID that can be matched to a named hierarchy using /proc/cgroups. Cgroups V2 only has one - // hierarchy, so HierarchyID is always 0. For cgroups v1 this is a unique ID number - HierarchyID int - // Controllers using this hierarchy of processes. Controllers are also known as subsystems. For - // Cgroups V2 this may be empty, as all active controllers use the same hierarchy - Controllers []string - // Path of this control group, relative to the mount point of the cgroupfs representing this specific - // hierarchy - Path string -} - -// parseCgroupString parses each line of the /proc/[pid]/cgroup file -// Line format is hierarchyID:[controller1,controller2]:path. -func parseCgroupString(cgroupStr string) (*Cgroup, error) { - var err error - - fields := strings.SplitN(cgroupStr, ":", 3) - if len(fields) < 3 { - return nil, fmt.Errorf("%w: 3+ fields required, found %d fields in cgroup string: %s", ErrFileParse, len(fields), cgroupStr) - } - - cgroup := &Cgroup{ - Path: fields[2], - Controllers: nil, - } - cgroup.HierarchyID, err = strconv.Atoi(fields[0]) - if err != nil { - return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, cgroup.HierarchyID) - } - if fields[1] != "" { - ssNames := strings.Split(fields[1], ",") - cgroup.Controllers = append(cgroup.Controllers, ssNames...) - } - return cgroup, nil -} - -// parseCgroups reads each line of the /proc/[pid]/cgroup file. -func parseCgroups(data []byte) ([]Cgroup, error) { - var cgroups []Cgroup - scanner := bufio.NewScanner(bytes.NewReader(data)) - for scanner.Scan() { - mountString := scanner.Text() - parsedMounts, err := parseCgroupString(mountString) - if err != nil { - return nil, err - } - cgroups = append(cgroups, *parsedMounts) - } - - err := scanner.Err() - return cgroups, err -} - -// Cgroups reads from /proc//cgroups and returns a []*Cgroup struct locating this PID in each process -// control hierarchy running on this system. On every system (v1 and v2), all hierarchies contain all processes, -// so the len of the returned struct is equal to the number of active hierarchies on this system. -func (p Proc) Cgroups() ([]Cgroup, error) { - data, err := util.ReadFileNoStat(p.path("cgroup")) - if err != nil { - return nil, err - } - return parseCgroups(data) -} diff --git a/vendor/github.com/prometheus/procfs/proc_cgroups.go b/vendor/github.com/prometheus/procfs/proc_cgroups.go deleted file mode 100644 index 0b275c3b1f5c..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_cgroups.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// CgroupSummary models one line from /proc/cgroups. -// This file contains information about the controllers that are compiled into the kernel. -// -// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html -type CgroupSummary struct { - // The name of the controller. controller is also known as subsystem. - SubsysName string - // The unique ID of the cgroup hierarchy on which this controller is mounted. - Hierarchy int - // The number of control groups in this hierarchy using this controller. - Cgroups int - // This field contains the value 1 if this controller is enabled, or 0 if it has been disabled - Enabled int -} - -// parseCgroupSummary parses each line of the /proc/cgroup file -// Line format is `subsys_name hierarchy num_cgroups enabled`. -func parseCgroupSummaryString(cgroupSummaryStr string) (*CgroupSummary, error) { - var err error - - fields := strings.Fields(cgroupSummaryStr) - // require at least 4 fields - if len(fields) < 4 { - return nil, fmt.Errorf("%w: 4+ fields required, found %d fields in cgroup info string: %s", ErrFileParse, len(fields), cgroupSummaryStr) - } - - CgroupSummary := &CgroupSummary{ - SubsysName: fields[0], - } - CgroupSummary.Hierarchy, err = strconv.Atoi(fields[1]) - if err != nil { - return nil, fmt.Errorf("%w: Unable to parse hierarchy ID from %q", ErrFileParse, fields[1]) - } - CgroupSummary.Cgroups, err = strconv.Atoi(fields[2]) - if err != nil { - return nil, fmt.Errorf("%w: Unable to parse Cgroup Num from %q", ErrFileParse, fields[2]) - } - CgroupSummary.Enabled, err = strconv.Atoi(fields[3]) - if err != nil { - return nil, fmt.Errorf("%w: Unable to parse Enabled from %q", ErrFileParse, fields[3]) - } - return CgroupSummary, nil -} - -// parseCgroupSummary reads each line of the /proc/cgroup file. -func parseCgroupSummary(data []byte) ([]CgroupSummary, error) { - var CgroupSummarys []CgroupSummary - scanner := bufio.NewScanner(bytes.NewReader(data)) - for scanner.Scan() { - CgroupSummaryString := scanner.Text() - // ignore comment lines - if strings.HasPrefix(CgroupSummaryString, "#") { - continue - } - CgroupSummary, err := parseCgroupSummaryString(CgroupSummaryString) - if err != nil { - return nil, err - } - CgroupSummarys = append(CgroupSummarys, *CgroupSummary) - } - - err := scanner.Err() - return CgroupSummarys, err -} - -// CgroupSummarys returns information about current /proc/cgroups. -func (fs FS) CgroupSummarys() ([]CgroupSummary, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("cgroups")) - if err != nil { - return nil, err - } - return parseCgroupSummary(data) -} diff --git a/vendor/github.com/prometheus/procfs/proc_environ.go b/vendor/github.com/prometheus/procfs/proc_environ.go deleted file mode 100644 index 5b941de04779..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_environ.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Environ reads process environments from `/proc//environ`. -func (p Proc) Environ() ([]string, error) { - environments := make([]string, 0) - - data, err := util.ReadFileNoStat(p.path("environ")) - if err != nil { - return environments, err - } - - environments = strings.Split(string(data), "\000") - if len(environments) > 0 { - environments = environments[:len(environments)-1] - } - - return environments, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc_fdinfo.go b/vendor/github.com/prometheus/procfs/proc_fdinfo.go deleted file mode 100644 index fa57761dbe36..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_fdinfo.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "regexp" - - "github.com/prometheus/procfs/internal/util" -) - -var ( - rPos = regexp.MustCompile(`^pos:\s+(\d+)$`) - rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`) - rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`) - rIno = regexp.MustCompile(`^ino:\s+(\d+)$`) - rInotify = regexp.MustCompile(`^inotify`) - rInotifyParts = regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)(?:\s+mask:([0-9a-f]+))?`) -) - -// ProcFDInfo contains represents file descriptor information. -type ProcFDInfo struct { - // File descriptor - FD string - // File offset - Pos string - // File access mode and status flags - Flags string - // Mount point ID - MntID string - // Inode number - Ino string - // List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only) - InotifyInfos []InotifyInfo -} - -// FDInfo constructor. On kernels older than 3.8, InotifyInfos will always be empty. -func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) { - data, err := util.ReadFileNoStat(p.path("fdinfo", fd)) - if err != nil { - return nil, err - } - - var text, pos, flags, mntid, ino string - var inotify []InotifyInfo - - scanner := bufio.NewScanner(bytes.NewReader(data)) - for scanner.Scan() { - text = scanner.Text() - switch { - case rPos.MatchString(text): - pos = rPos.FindStringSubmatch(text)[1] - case rFlags.MatchString(text): - flags = rFlags.FindStringSubmatch(text)[1] - case rMntID.MatchString(text): - mntid = rMntID.FindStringSubmatch(text)[1] - case rIno.MatchString(text): - ino = rIno.FindStringSubmatch(text)[1] - case rInotify.MatchString(text): - newInotify, err := parseInotifyInfo(text) - if err != nil { - return nil, err - } - inotify = append(inotify, *newInotify) - } - } - - i := &ProcFDInfo{ - FD: fd, - Pos: pos, - Flags: flags, - MntID: mntid, - Ino: ino, - InotifyInfos: inotify, - } - - return i, nil -} - -// InotifyInfo represents a single inotify line in the fdinfo file. -type InotifyInfo struct { - // Watch descriptor number - WD string - // Inode number - Ino string - // Device ID - Sdev string - // Mask of events being monitored - Mask string -} - -// InotifyInfo constructor. Only available on kernel 3.8+. -func parseInotifyInfo(line string) (*InotifyInfo, error) { - m := rInotifyParts.FindStringSubmatch(line) - if len(m) >= 4 { - var mask string - if len(m) == 5 { - mask = m[4] - } - i := &InotifyInfo{ - WD: m[1], - Ino: m[2], - Sdev: m[3], - Mask: mask, - } - return i, nil - } - return nil, fmt.Errorf("%w: invalid inode entry: %q", ErrFileParse, line) -} - -// ProcFDInfos represents a list of ProcFDInfo structs. -type ProcFDInfos []ProcFDInfo - -func (p ProcFDInfos) Len() int { return len(p) } -func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD } - -// InotifyWatchLen returns the total number of inotify watches. -func (p ProcFDInfos) InotifyWatchLen() (int, error) { - length := 0 - for _, f := range p { - length += len(f.InotifyInfos) - } - - return length, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc_interrupts.go b/vendor/github.com/prometheus/procfs/proc_interrupts.go deleted file mode 100644 index 643b500d5d93..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_interrupts.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Interrupt represents a single interrupt line. -type Interrupt struct { - // Info is the type of interrupt. - Info string - // Devices is the name of the device that is located at that IRQ - Devices string - // Values is the number of interrupts per CPU. - Values []string -} - -// Interrupts models the content of /proc/interrupts. Key is the IRQ number. -// - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-interrupts -// - https://raspberrypi.stackexchange.com/questions/105802/explanation-of-proc-interrupts-output -type Interrupts map[string]Interrupt - -// Interrupts creates a new instance from a given Proc instance. -func (p Proc) Interrupts() (Interrupts, error) { - data, err := util.ReadFileNoStat(p.fs.proc.Path("interrupts")) - if err != nil { - return nil, err - } - return parseInterrupts(bytes.NewReader(data)) -} - -func parseInterrupts(r io.Reader) (Interrupts, error) { - var ( - interrupts = Interrupts{} - scanner = bufio.NewScanner(r) - ) - - if !scanner.Scan() { - return nil, errors.New("interrupts empty") - } - cpuNum := len(strings.Fields(scanner.Text())) // one header per cpu - - for scanner.Scan() { - parts := strings.Fields(scanner.Text()) - if len(parts) == 0 { // skip empty lines - continue - } - if len(parts) < 2 { - return nil, fmt.Errorf("%w: Not enough fields in interrupts (expected 2+ fields but got %d): %s", ErrFileParse, len(parts), parts) - } - intName := parts[0][:len(parts[0])-1] // remove trailing : - - if len(parts) == 2 { - interrupts[intName] = Interrupt{ - Info: "", - Devices: "", - Values: []string{ - parts[1], - }, - } - continue - } - - intr := Interrupt{ - Values: parts[1 : cpuNum+1], - } - - if _, err := strconv.Atoi(intName); err == nil { // numeral interrupt - intr.Info = parts[cpuNum+1] - intr.Devices = strings.Join(parts[cpuNum+2:], " ") - } else { - intr.Info = strings.Join(parts[cpuNum+1:], " ") - } - interrupts[intName] = intr - } - - return interrupts, scanner.Err() -} diff --git a/vendor/github.com/prometheus/procfs/proc_io.go b/vendor/github.com/prometheus/procfs/proc_io.go deleted file mode 100644 index dd8086ba2e7c..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_io.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "fmt" - - "github.com/prometheus/procfs/internal/util" -) - -// ProcIO models the content of /proc//io. -type ProcIO struct { - // Chars read. - RChar uint64 - // Chars written. - WChar uint64 - // Read syscalls. - SyscR uint64 - // Write syscalls. - SyscW uint64 - // Bytes read. - ReadBytes uint64 - // Bytes written. - WriteBytes uint64 - // Bytes written, but taking into account truncation. See - // Documentation/filesystems/proc.txt in the kernel sources for - // detailed explanation. - CancelledWriteBytes int64 -} - -// IO creates a new ProcIO instance from a given Proc instance. -func (p Proc) IO() (ProcIO, error) { - pio := ProcIO{} - - data, err := util.ReadFileNoStat(p.path("io")) - if err != nil { - return pio, err - } - - ioFormat := "rchar: %d\nwchar: %d\nsyscr: %d\nsyscw: %d\n" + - "read_bytes: %d\nwrite_bytes: %d\n" + - "cancelled_write_bytes: %d\n" //nolint:misspell - - _, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR, - &pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes) - - return pio, err -} diff --git a/vendor/github.com/prometheus/procfs/proc_limits.go b/vendor/github.com/prometheus/procfs/proc_limits.go deleted file mode 100644 index 4b7d33784712..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_limits.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "fmt" - "os" - "regexp" - "strconv" - "strings" -) - -// ProcLimits represents the soft limits for each of the process's resource -// limits. For more information see getrlimit(2): -// http://man7.org/linux/man-pages/man2/getrlimit.2.html. -type ProcLimits struct { - // CPU time limit in seconds. - CPUTime uint64 - // Maximum size of files that the process may create. - FileSize uint64 - // Maximum size of the process's data segment (initialized data, - // uninitialized data, and heap). - DataSize uint64 - // Maximum size of the process stack in bytes. - StackSize uint64 - // Maximum size of a core file. - CoreFileSize uint64 - // Limit of the process's resident set in pages. - ResidentSet uint64 - // Maximum number of processes that can be created for the real user ID of - // the calling process. - Processes uint64 - // Value one greater than the maximum file descriptor number that can be - // opened by this process. - OpenFiles uint64 - // Maximum number of bytes of memory that may be locked into RAM. - LockedMemory uint64 - // Maximum size of the process's virtual memory address space in bytes. - AddressSpace uint64 - // Limit on the combined number of flock(2) locks and fcntl(2) leases that - // this process may establish. - FileLocks uint64 - // Limit of signals that may be queued for the real user ID of the calling - // process. - PendingSignals uint64 - // Limit on the number of bytes that can be allocated for POSIX message - // queues for the real user ID of the calling process. - MsqqueueSize uint64 - // Limit of the nice priority set using setpriority(2) or nice(2). - NicePriority uint64 - // Limit of the real-time priority set using sched_setscheduler(2) or - // sched_setparam(2). - RealtimePriority uint64 - // Limit (in microseconds) on the amount of CPU time that a process - // scheduled under a real-time scheduling policy may consume without making - // a blocking system call. - RealtimeTimeout uint64 -} - -const ( - limitsFields = 4 - limitsUnlimited = "unlimited" -) - -var ( - limitsMatch = regexp.MustCompile(`(Max \w+\s??\w*\s?\w*)\s{2,}(\w+)\s+(\w+)`) -) - -// NewLimits returns the current soft limits of the process. -// -// Deprecated: Use p.Limits() instead. -func (p Proc) NewLimits() (ProcLimits, error) { - return p.Limits() -} - -// Limits returns the current soft limits of the process. -func (p Proc) Limits() (ProcLimits, error) { - f, err := os.Open(p.path("limits")) - if err != nil { - return ProcLimits{}, err - } - defer f.Close() - - var ( - l = ProcLimits{} - s = bufio.NewScanner(f) - ) - - s.Scan() // Skip limits header - - for s.Scan() { - //fields := limitsMatch.Split(s.Text(), limitsFields) - fields := limitsMatch.FindStringSubmatch(s.Text()) - if len(fields) != limitsFields { - return ProcLimits{}, fmt.Errorf("%w: couldn't parse %q line %q", ErrFileParse, f.Name(), s.Text()) - } - - switch strings.TrimSpace(fields[1]) { - case "Max cpu time": - l.CPUTime, err = parseUint(fields[2]) - case "Max file size": - l.FileSize, err = parseUint(fields[2]) - case "Max data size": - l.DataSize, err = parseUint(fields[2]) - case "Max stack size": - l.StackSize, err = parseUint(fields[2]) - case "Max core file size": - l.CoreFileSize, err = parseUint(fields[2]) - case "Max resident set": - l.ResidentSet, err = parseUint(fields[2]) - case "Max processes": - l.Processes, err = parseUint(fields[2]) - case "Max open files": - l.OpenFiles, err = parseUint(fields[2]) - case "Max locked memory": - l.LockedMemory, err = parseUint(fields[2]) - case "Max address space": - l.AddressSpace, err = parseUint(fields[2]) - case "Max file locks": - l.FileLocks, err = parseUint(fields[2]) - case "Max pending signals": - l.PendingSignals, err = parseUint(fields[2]) - case "Max msgqueue size": - l.MsqqueueSize, err = parseUint(fields[2]) - case "Max nice priority": - l.NicePriority, err = parseUint(fields[2]) - case "Max realtime priority": - l.RealtimePriority, err = parseUint(fields[2]) - case "Max realtime timeout": - l.RealtimeTimeout, err = parseUint(fields[2]) - } - if err != nil { - return ProcLimits{}, err - } - } - - return l, s.Err() -} - -func parseUint(s string) (uint64, error) { - if s == limitsUnlimited { - return 18446744073709551615, nil - } - i, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return 0, fmt.Errorf("%w: couldn't parse value %q: %w", ErrFileParse, s, err) - } - return i, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc_maps.go b/vendor/github.com/prometheus/procfs/proc_maps.go deleted file mode 100644 index 08b89a6eb9e3..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_maps.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && !js - -package procfs - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" - - "golang.org/x/sys/unix" -) - -// ProcMapPermissions contains permission settings read from `/proc/[pid]/maps`. -type ProcMapPermissions struct { - // mapping has the [R]ead flag set - Read bool - // mapping has the [W]rite flag set - Write bool - // mapping has the [X]ecutable flag set - Execute bool - // mapping has the [S]hared flag set - Shared bool - // mapping is marked as [P]rivate (copy on write) - Private bool -} - -// ProcMap contains the process memory-mappings of the process -// read from `/proc/[pid]/maps`. -type ProcMap struct { - // The start address of current mapping. - StartAddr uintptr - // The end address of the current mapping - EndAddr uintptr - // The permissions for this mapping - Perms *ProcMapPermissions - // The current offset into the file/fd (e.g., shared libs) - Offset int64 - // Device owner of this mapping (major:minor) in Mkdev format. - Dev uint64 - // The inode of the device above - Inode uint64 - // The file or psuedofile (or empty==anonymous) - Pathname string -} - -// parseDevice parses the device token of a line and converts it to a dev_t -// (mkdev) like structure. -func parseDevice(s string) (uint64, error) { - i := strings.Index(s, ":") - if i == -1 { - return 0, fmt.Errorf("%w: expected separator `:` in %s", ErrFileParse, s) - } - - major, err := strconv.ParseUint(s[0:i], 16, 0) - if err != nil { - return 0, err - } - - minor, err := strconv.ParseUint(s[i+1:], 16, 0) - if err != nil { - return 0, err - } - - return unix.Mkdev(uint32(major), uint32(minor)), nil -} - -// parseAddress converts a hex-string to a uintptr. -func parseAddress(s string) (uintptr, error) { - a, err := strconv.ParseUint(s, 16, 0) - if err != nil { - return 0, err - } - - return uintptr(a), nil -} - -// parseAddresses parses the start-end address. -func parseAddresses(s string) (uintptr, uintptr, error) { - idx := strings.Index(s, "-") - if idx == -1 { - return 0, 0, fmt.Errorf("%w: expected separator `-` in %s", ErrFileParse, s) - } - - saddr, err := parseAddress(s[0:idx]) - if err != nil { - return 0, 0, err - } - - eaddr, err := parseAddress(s[idx+1:]) - if err != nil { - return 0, 0, err - } - - return saddr, eaddr, nil -} - -// parsePermissions parses a token and returns any that are set. -func parsePermissions(s string) (*ProcMapPermissions, error) { - if len(s) < 4 { - return nil, fmt.Errorf("%w: invalid permissions token", ErrFileParse) - } - - perms := ProcMapPermissions{} - for _, ch := range s { - switch ch { - case 'r': - perms.Read = true - case 'w': - perms.Write = true - case 'x': - perms.Execute = true - case 'p': - perms.Private = true - case 's': - perms.Shared = true - } - } - - return &perms, nil -} - -// parseProcMap will attempt to parse a single line within a proc/[pid]/maps -// buffer. -func parseProcMap(text string) (*ProcMap, error) { - fields := strings.Fields(text) - if len(fields) < 5 { - return nil, fmt.Errorf("%w: truncated procmap entry", ErrFileParse) - } - - saddr, eaddr, err := parseAddresses(fields[0]) - if err != nil { - return nil, err - } - - perms, err := parsePermissions(fields[1]) - if err != nil { - return nil, err - } - - offset, err := strconv.ParseInt(fields[2], 16, 0) - if err != nil { - return nil, err - } - - device, err := parseDevice(fields[3]) - if err != nil { - return nil, err - } - - inode, err := strconv.ParseUint(fields[4], 10, 0) - if err != nil { - return nil, err - } - - pathname := "" - - if len(fields) >= 5 { - pathname = strings.Join(fields[5:], " ") - } - - return &ProcMap{ - StartAddr: saddr, - EndAddr: eaddr, - Perms: perms, - Offset: offset, - Dev: device, - Inode: inode, - Pathname: pathname, - }, nil -} - -// ProcMaps reads from /proc/[pid]/maps to get the memory-mappings of the -// process. -func (p Proc) ProcMaps() ([]*ProcMap, error) { - file, err := os.Open(p.path("maps")) - if err != nil { - return nil, err - } - defer file.Close() - - maps := []*ProcMap{} - scan := bufio.NewScanner(file) - - for scan.Scan() { - m, err := parseProcMap(scan.Text()) - if err != nil { - return nil, err - } - - maps = append(maps, m) - } - - return maps, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc_netstat.go b/vendor/github.com/prometheus/procfs/proc_netstat.go deleted file mode 100644 index 7f94cc89145b..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_netstat.go +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// ProcNetstat models the content of /proc//net/netstat. -type ProcNetstat struct { - // The process ID. - PID int - TcpExt - IpExt -} - -type TcpExt struct { // nolint:revive - SyncookiesSent *float64 - SyncookiesRecv *float64 - SyncookiesFailed *float64 - EmbryonicRsts *float64 - PruneCalled *float64 - RcvPruned *float64 - OfoPruned *float64 - OutOfWindowIcmps *float64 - LockDroppedIcmps *float64 - ArpFilter *float64 - TW *float64 - TWRecycled *float64 - TWKilled *float64 - PAWSActive *float64 - PAWSEstab *float64 - DelayedACKs *float64 - DelayedACKLocked *float64 - DelayedACKLost *float64 - ListenOverflows *float64 - ListenDrops *float64 - TCPHPHits *float64 - TCPPureAcks *float64 - TCPHPAcks *float64 - TCPRenoRecovery *float64 - TCPSackRecovery *float64 - TCPSACKReneging *float64 - TCPSACKReorder *float64 - TCPRenoReorder *float64 - TCPTSReorder *float64 - TCPFullUndo *float64 - TCPPartialUndo *float64 - TCPDSACKUndo *float64 - TCPLossUndo *float64 - TCPLostRetransmit *float64 - TCPRenoFailures *float64 - TCPSackFailures *float64 - TCPLossFailures *float64 - TCPFastRetrans *float64 - TCPSlowStartRetrans *float64 - TCPTimeouts *float64 - TCPLossProbes *float64 - TCPLossProbeRecovery *float64 - TCPRenoRecoveryFail *float64 - TCPSackRecoveryFail *float64 - TCPRcvCollapsed *float64 - TCPDSACKOldSent *float64 - TCPDSACKOfoSent *float64 - TCPDSACKRecv *float64 - TCPDSACKOfoRecv *float64 - TCPAbortOnData *float64 - TCPAbortOnClose *float64 - TCPAbortOnMemory *float64 - TCPAbortOnTimeout *float64 - TCPAbortOnLinger *float64 - TCPAbortFailed *float64 - TCPMemoryPressures *float64 - TCPMemoryPressuresChrono *float64 - TCPSACKDiscard *float64 - TCPDSACKIgnoredOld *float64 - TCPDSACKIgnoredNoUndo *float64 - TCPSpuriousRTOs *float64 - TCPMD5NotFound *float64 - TCPMD5Unexpected *float64 - TCPMD5Failure *float64 - TCPSackShifted *float64 - TCPSackMerged *float64 - TCPSackShiftFallback *float64 - TCPBacklogDrop *float64 - PFMemallocDrop *float64 - TCPMinTTLDrop *float64 - TCPDeferAcceptDrop *float64 - IPReversePathFilter *float64 - TCPTimeWaitOverflow *float64 - TCPReqQFullDoCookies *float64 - TCPReqQFullDrop *float64 - TCPRetransFail *float64 - TCPRcvCoalesce *float64 - TCPRcvQDrop *float64 - TCPOFOQueue *float64 - TCPOFODrop *float64 - TCPOFOMerge *float64 - TCPChallengeACK *float64 - TCPSYNChallenge *float64 - TCPFastOpenActive *float64 - TCPFastOpenActiveFail *float64 - TCPFastOpenPassive *float64 - TCPFastOpenPassiveFail *float64 - TCPFastOpenListenOverflow *float64 - TCPFastOpenCookieReqd *float64 - TCPFastOpenBlackhole *float64 - TCPSpuriousRtxHostQueues *float64 - BusyPollRxPackets *float64 - TCPAutoCorking *float64 - TCPFromZeroWindowAdv *float64 - TCPToZeroWindowAdv *float64 - TCPWantZeroWindowAdv *float64 - TCPSynRetrans *float64 - TCPOrigDataSent *float64 - TCPHystartTrainDetect *float64 - TCPHystartTrainCwnd *float64 - TCPHystartDelayDetect *float64 - TCPHystartDelayCwnd *float64 - TCPACKSkippedSynRecv *float64 - TCPACKSkippedPAWS *float64 - TCPACKSkippedSeq *float64 - TCPACKSkippedFinWait2 *float64 - TCPACKSkippedTimeWait *float64 - TCPACKSkippedChallenge *float64 - TCPWinProbe *float64 - TCPKeepAlive *float64 - TCPMTUPFail *float64 - TCPMTUPSuccess *float64 - TCPWqueueTooBig *float64 -} - -type IpExt struct { // nolint:revive - InNoRoutes *float64 - InTruncatedPkts *float64 - InMcastPkts *float64 - OutMcastPkts *float64 - InBcastPkts *float64 - OutBcastPkts *float64 - InOctets *float64 - OutOctets *float64 - InMcastOctets *float64 - OutMcastOctets *float64 - InBcastOctets *float64 - OutBcastOctets *float64 - InCsumErrors *float64 - InNoECTPkts *float64 - InECT1Pkts *float64 - InECT0Pkts *float64 - InCEPkts *float64 - ReasmOverlaps *float64 -} - -func (p Proc) Netstat() (ProcNetstat, error) { - filename := p.path("net/netstat") - data, err := util.ReadFileNoStat(filename) - if err != nil { - return ProcNetstat{PID: p.PID}, err - } - procNetstat, err := parseProcNetstat(bytes.NewReader(data), filename) - procNetstat.PID = p.PID - return procNetstat, err -} - -// parseProcNetstat parses the metrics from proc//net/netstat file -// and returns a ProcNetstat structure. -func parseProcNetstat(r io.Reader, fileName string) (ProcNetstat, error) { - var ( - scanner = bufio.NewScanner(r) - procNetstat = ProcNetstat{} - ) - - for scanner.Scan() { - nameParts := strings.Split(scanner.Text(), " ") - scanner.Scan() - valueParts := strings.Split(scanner.Text(), " ") - // Remove trailing :. - protocol := strings.TrimSuffix(nameParts[0], ":") - if len(nameParts) != len(valueParts) { - return procNetstat, fmt.Errorf("%w: mismatch field count mismatch in %s: %s", - ErrFileParse, fileName, protocol) - } - for i := 1; i < len(nameParts); i++ { - value, err := strconv.ParseFloat(valueParts[i], 64) - if err != nil { - return procNetstat, err - } - key := nameParts[i] - - switch protocol { - case "TcpExt": - switch key { - case "SyncookiesSent": - procNetstat.SyncookiesSent = &value - case "SyncookiesRecv": - procNetstat.SyncookiesRecv = &value - case "SyncookiesFailed": - procNetstat.SyncookiesFailed = &value - case "EmbryonicRsts": - procNetstat.EmbryonicRsts = &value - case "PruneCalled": - procNetstat.PruneCalled = &value - case "RcvPruned": - procNetstat.RcvPruned = &value - case "OfoPruned": - procNetstat.OfoPruned = &value - case "OutOfWindowIcmps": - procNetstat.OutOfWindowIcmps = &value - case "LockDroppedIcmps": - procNetstat.LockDroppedIcmps = &value - case "ArpFilter": - procNetstat.ArpFilter = &value - case "TW": - procNetstat.TW = &value - case "TWRecycled": - procNetstat.TWRecycled = &value - case "TWKilled": - procNetstat.TWKilled = &value - case "PAWSActive": - procNetstat.PAWSActive = &value - case "PAWSEstab": - procNetstat.PAWSEstab = &value - case "DelayedACKs": - procNetstat.DelayedACKs = &value - case "DelayedACKLocked": - procNetstat.DelayedACKLocked = &value - case "DelayedACKLost": - procNetstat.DelayedACKLost = &value - case "ListenOverflows": - procNetstat.ListenOverflows = &value - case "ListenDrops": - procNetstat.ListenDrops = &value - case "TCPHPHits": - procNetstat.TCPHPHits = &value - case "TCPPureAcks": - procNetstat.TCPPureAcks = &value - case "TCPHPAcks": - procNetstat.TCPHPAcks = &value - case "TCPRenoRecovery": - procNetstat.TCPRenoRecovery = &value - case "TCPSackRecovery": - procNetstat.TCPSackRecovery = &value - case "TCPSACKReneging": - procNetstat.TCPSACKReneging = &value - case "TCPSACKReorder": - procNetstat.TCPSACKReorder = &value - case "TCPRenoReorder": - procNetstat.TCPRenoReorder = &value - case "TCPTSReorder": - procNetstat.TCPTSReorder = &value - case "TCPFullUndo": - procNetstat.TCPFullUndo = &value - case "TCPPartialUndo": - procNetstat.TCPPartialUndo = &value - case "TCPDSACKUndo": - procNetstat.TCPDSACKUndo = &value - case "TCPLossUndo": - procNetstat.TCPLossUndo = &value - case "TCPLostRetransmit": - procNetstat.TCPLostRetransmit = &value - case "TCPRenoFailures": - procNetstat.TCPRenoFailures = &value - case "TCPSackFailures": - procNetstat.TCPSackFailures = &value - case "TCPLossFailures": - procNetstat.TCPLossFailures = &value - case "TCPFastRetrans": - procNetstat.TCPFastRetrans = &value - case "TCPSlowStartRetrans": - procNetstat.TCPSlowStartRetrans = &value - case "TCPTimeouts": - procNetstat.TCPTimeouts = &value - case "TCPLossProbes": - procNetstat.TCPLossProbes = &value - case "TCPLossProbeRecovery": - procNetstat.TCPLossProbeRecovery = &value - case "TCPRenoRecoveryFail": - procNetstat.TCPRenoRecoveryFail = &value - case "TCPSackRecoveryFail": - procNetstat.TCPSackRecoveryFail = &value - case "TCPRcvCollapsed": - procNetstat.TCPRcvCollapsed = &value - case "TCPDSACKOldSent": - procNetstat.TCPDSACKOldSent = &value - case "TCPDSACKOfoSent": - procNetstat.TCPDSACKOfoSent = &value - case "TCPDSACKRecv": - procNetstat.TCPDSACKRecv = &value - case "TCPDSACKOfoRecv": - procNetstat.TCPDSACKOfoRecv = &value - case "TCPAbortOnData": - procNetstat.TCPAbortOnData = &value - case "TCPAbortOnClose": - procNetstat.TCPAbortOnClose = &value - case "TCPDeferAcceptDrop": - procNetstat.TCPDeferAcceptDrop = &value - case "IPReversePathFilter": - procNetstat.IPReversePathFilter = &value - case "TCPTimeWaitOverflow": - procNetstat.TCPTimeWaitOverflow = &value - case "TCPReqQFullDoCookies": - procNetstat.TCPReqQFullDoCookies = &value - case "TCPReqQFullDrop": - procNetstat.TCPReqQFullDrop = &value - case "TCPRetransFail": - procNetstat.TCPRetransFail = &value - case "TCPRcvCoalesce": - procNetstat.TCPRcvCoalesce = &value - case "TCPRcvQDrop": - procNetstat.TCPRcvQDrop = &value - case "TCPOFOQueue": - procNetstat.TCPOFOQueue = &value - case "TCPOFODrop": - procNetstat.TCPOFODrop = &value - case "TCPOFOMerge": - procNetstat.TCPOFOMerge = &value - case "TCPChallengeACK": - procNetstat.TCPChallengeACK = &value - case "TCPSYNChallenge": - procNetstat.TCPSYNChallenge = &value - case "TCPFastOpenActive": - procNetstat.TCPFastOpenActive = &value - case "TCPFastOpenActiveFail": - procNetstat.TCPFastOpenActiveFail = &value - case "TCPFastOpenPassive": - procNetstat.TCPFastOpenPassive = &value - case "TCPFastOpenPassiveFail": - procNetstat.TCPFastOpenPassiveFail = &value - case "TCPFastOpenListenOverflow": - procNetstat.TCPFastOpenListenOverflow = &value - case "TCPFastOpenCookieReqd": - procNetstat.TCPFastOpenCookieReqd = &value - case "TCPFastOpenBlackhole": - procNetstat.TCPFastOpenBlackhole = &value - case "TCPSpuriousRtxHostQueues": - procNetstat.TCPSpuriousRtxHostQueues = &value - case "BusyPollRxPackets": - procNetstat.BusyPollRxPackets = &value - case "TCPAutoCorking": - procNetstat.TCPAutoCorking = &value - case "TCPFromZeroWindowAdv": - procNetstat.TCPFromZeroWindowAdv = &value - case "TCPToZeroWindowAdv": - procNetstat.TCPToZeroWindowAdv = &value - case "TCPWantZeroWindowAdv": - procNetstat.TCPWantZeroWindowAdv = &value - case "TCPSynRetrans": - procNetstat.TCPSynRetrans = &value - case "TCPOrigDataSent": - procNetstat.TCPOrigDataSent = &value - case "TCPHystartTrainDetect": - procNetstat.TCPHystartTrainDetect = &value - case "TCPHystartTrainCwnd": - procNetstat.TCPHystartTrainCwnd = &value - case "TCPHystartDelayDetect": - procNetstat.TCPHystartDelayDetect = &value - case "TCPHystartDelayCwnd": - procNetstat.TCPHystartDelayCwnd = &value - case "TCPACKSkippedSynRecv": - procNetstat.TCPACKSkippedSynRecv = &value - case "TCPACKSkippedPAWS": - procNetstat.TCPACKSkippedPAWS = &value - case "TCPACKSkippedSeq": - procNetstat.TCPACKSkippedSeq = &value - case "TCPACKSkippedFinWait2": - procNetstat.TCPACKSkippedFinWait2 = &value - case "TCPACKSkippedTimeWait": - procNetstat.TCPACKSkippedTimeWait = &value - case "TCPACKSkippedChallenge": - procNetstat.TCPACKSkippedChallenge = &value - case "TCPWinProbe": - procNetstat.TCPWinProbe = &value - case "TCPKeepAlive": - procNetstat.TCPKeepAlive = &value - case "TCPMTUPFail": - procNetstat.TCPMTUPFail = &value - case "TCPMTUPSuccess": - procNetstat.TCPMTUPSuccess = &value - case "TCPWqueueTooBig": - procNetstat.TCPWqueueTooBig = &value - } - case "IpExt": - switch key { - case "InNoRoutes": - procNetstat.InNoRoutes = &value - case "InTruncatedPkts": - procNetstat.InTruncatedPkts = &value - case "InMcastPkts": - procNetstat.InMcastPkts = &value - case "OutMcastPkts": - procNetstat.OutMcastPkts = &value - case "InBcastPkts": - procNetstat.InBcastPkts = &value - case "OutBcastPkts": - procNetstat.OutBcastPkts = &value - case "InOctets": - procNetstat.InOctets = &value - case "OutOctets": - procNetstat.OutOctets = &value - case "InMcastOctets": - procNetstat.InMcastOctets = &value - case "OutMcastOctets": - procNetstat.OutMcastOctets = &value - case "InBcastOctets": - procNetstat.InBcastOctets = &value - case "OutBcastOctets": - procNetstat.OutBcastOctets = &value - case "InCsumErrors": - procNetstat.InCsumErrors = &value - case "InNoECTPkts": - procNetstat.InNoECTPkts = &value - case "InECT1Pkts": - procNetstat.InECT1Pkts = &value - case "InECT0Pkts": - procNetstat.InECT0Pkts = &value - case "InCEPkts": - procNetstat.InCEPkts = &value - case "ReasmOverlaps": - procNetstat.ReasmOverlaps = &value - } - } - } - } - return procNetstat, scanner.Err() -} diff --git a/vendor/github.com/prometheus/procfs/proc_ns.go b/vendor/github.com/prometheus/procfs/proc_ns.go deleted file mode 100644 index 5fc0eb9e2f9f..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_ns.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "fmt" - "os" - "strconv" - "strings" -) - -// Namespace represents a single namespace of a process. -type Namespace struct { - Type string // Namespace type. - Inode uint32 // Inode number of the namespace. If two processes are in the same namespace their inodes will match. -} - -// Namespaces contains all of the namespaces that the process is contained in. -type Namespaces map[string]Namespace - -// Namespaces reads from /proc//ns/* to get the namespaces of which the -// process is a member. -func (p Proc) Namespaces() (Namespaces, error) { - d, err := os.Open(p.path("ns")) - if err != nil { - return nil, err - } - defer d.Close() - - names, err := d.Readdirnames(-1) - if err != nil { - return nil, fmt.Errorf("%w: failed to read contents of ns dir: %w", ErrFileRead, err) - } - - ns := make(Namespaces, len(names)) - for _, name := range names { - target, err := os.Readlink(p.path("ns", name)) - if err != nil { - return nil, err - } - - fields := strings.SplitN(target, ":", 2) - if len(fields) != 2 { - return nil, fmt.Errorf("%w: namespace type and inode from %q", ErrFileParse, target) - } - - typ := fields[0] - inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32) - if err != nil { - return nil, fmt.Errorf("%w: inode from %q: %w", ErrFileParse, fields[1], err) - } - - ns[name] = Namespace{typ, uint32(inode)} - } - - return ns, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc_psi.go b/vendor/github.com/prometheus/procfs/proc_psi.go deleted file mode 100644 index cc2c5de873e0..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_psi.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -// The PSI / pressure interface is described at -// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/accounting/psi.txt -// Each resource (cpu, io, memory, ...) is exposed as a single file. -// Each file may contain up to two lines, one for "some" pressure and one for "full" pressure. -// Each line contains several averages (over n seconds) and a total in µs. -// -// Example io pressure file: -// > some avg10=0.06 avg60=0.21 avg300=0.99 total=8537362 -// > full avg10=0.00 avg60=0.13 avg300=0.96 total=8183134 - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -const lineFormat = "avg10=%f avg60=%f avg300=%f total=%d" - -// PSILine is a single line of values as returned by `/proc/pressure/*`. -// -// The Avg entries are averages over n seconds, as a percentage. -// The Total line is in microseconds. -type PSILine struct { - Avg10 float64 - Avg60 float64 - Avg300 float64 - Total uint64 -} - -// PSIStats represent pressure stall information from /proc/pressure/* -// -// "Some" indicates the share of time in which at least some tasks are stalled. -// "Full" indicates the share of time in which all non-idle tasks are stalled simultaneously. -type PSIStats struct { - Some *PSILine - Full *PSILine -} - -// PSIStatsForResource reads pressure stall information for the specified -// resource from /proc/pressure/. At time of writing this can be -// either "cpu", "memory" or "io". -func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) { - data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource))) - if err != nil { - return PSIStats{}, fmt.Errorf("%w: psi_stats: unavailable for %q: %w", ErrFileRead, resource, err) - } - - return parsePSIStats(bytes.NewReader(data)) -} - -// parsePSIStats parses the specified file for pressure stall information. -func parsePSIStats(r io.Reader) (PSIStats, error) { - psiStats := PSIStats{} - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - l := scanner.Text() - prefix := strings.Split(l, " ")[0] - switch prefix { - case "some": - psi := PSILine{} - _, err := fmt.Sscanf(l, fmt.Sprintf("some %s", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total) - if err != nil { - return PSIStats{}, err - } - psiStats.Some = &psi - case "full": - psi := PSILine{} - _, err := fmt.Sscanf(l, fmt.Sprintf("full %s", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total) - if err != nil { - return PSIStats{}, err - } - psiStats.Full = &psi - default: - // If we encounter a line with an unknown prefix, ignore it and move on - // Should new measurement types be added in the future we'll simply ignore them instead - // of erroring on retrieval - continue - } - } - - return psiStats, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc_smaps.go b/vendor/github.com/prometheus/procfs/proc_smaps.go deleted file mode 100644 index f637309b3d18..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_smaps.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows - -package procfs - -import ( - "bufio" - "errors" - "os" - "regexp" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -var ( - // Match the header line before each mapped zone in `/proc/pid/smaps`. - procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`) -) - -type ProcSMapsRollup struct { - // Amount of the mapping that is currently resident in RAM. - Rss uint64 - // Process's proportional share of this mapping. - Pss uint64 - // Size in bytes of clean shared pages. - SharedClean uint64 - // Size in bytes of dirty shared pages. - SharedDirty uint64 - // Size in bytes of clean private pages. - PrivateClean uint64 - // Size in bytes of dirty private pages. - PrivateDirty uint64 - // Amount of memory currently marked as referenced or accessed. - Referenced uint64 - // Amount of memory that does not belong to any file. - Anonymous uint64 - // Amount would-be-anonymous memory currently on swap. - Swap uint64 - // Process's proportional memory on swap. - SwapPss uint64 -} - -// ProcSMapsRollup reads from /proc/[pid]/smaps_rollup to get summed memory information of the -// process. -// -// If smaps_rollup does not exists (require kernel >= 4.15), the content of /proc/pid/smaps will -// we read and summed. -func (p Proc) ProcSMapsRollup() (ProcSMapsRollup, error) { - data, err := util.ReadFileNoStat(p.path("smaps_rollup")) - if err != nil && os.IsNotExist(err) { - return p.procSMapsRollupManual() - } - if err != nil { - return ProcSMapsRollup{}, err - } - - lines := strings.Split(string(data), "\n") - smaps := ProcSMapsRollup{} - - // skip first line which don't contains information we need - lines = lines[1:] - for _, line := range lines { - if line == "" { - continue - } - - if err := smaps.parseLine(line); err != nil { - return ProcSMapsRollup{}, err - } - } - - return smaps, nil -} - -// Read /proc/pid/smaps and do the roll-up in Go code. -func (p Proc) procSMapsRollupManual() (ProcSMapsRollup, error) { - file, err := os.Open(p.path("smaps")) - if err != nil { - return ProcSMapsRollup{}, err - } - defer file.Close() - - smaps := ProcSMapsRollup{} - scan := bufio.NewScanner(file) - - for scan.Scan() { - line := scan.Text() - - if procSMapsHeaderLine.MatchString(line) { - continue - } - - if err := smaps.parseLine(line); err != nil { - return ProcSMapsRollup{}, err - } - } - - return smaps, nil -} - -func (s *ProcSMapsRollup) parseLine(line string) error { - kv := strings.SplitN(line, ":", 2) - if len(kv) != 2 { - return errors.New("invalid net/dev line, missing colon") - } - - k := kv[0] - if k == "VmFlags" { - return nil - } - - v := strings.TrimSpace(kv[1]) - v = strings.TrimSuffix(v, " kB") - - vKBytes, err := strconv.ParseUint(v, 10, 64) - if err != nil { - return err - } - vBytes := vKBytes * 1024 - - s.addValue(k, vBytes) - - return nil -} - -func (s *ProcSMapsRollup) addValue(k string, vUintBytes uint64) { - switch k { - case "Rss": - s.Rss += vUintBytes - case "Pss": - s.Pss += vUintBytes - case "Shared_Clean": - s.SharedClean += vUintBytes - case "Shared_Dirty": - s.SharedDirty += vUintBytes - case "Private_Clean": - s.PrivateClean += vUintBytes - case "Private_Dirty": - s.PrivateDirty += vUintBytes - case "Referenced": - s.Referenced += vUintBytes - case "Anonymous": - s.Anonymous += vUintBytes - case "Swap": - s.Swap += vUintBytes - case "SwapPss": - s.SwapPss += vUintBytes - } -} diff --git a/vendor/github.com/prometheus/procfs/proc_snmp.go b/vendor/github.com/prometheus/procfs/proc_snmp.go deleted file mode 100644 index 8d9a9bcd67aa..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_snmp.go +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// ProcSnmp models the content of /proc//net/snmp. -type ProcSnmp struct { - // The process ID. - PID int - Ip - Icmp - IcmpMsg - Tcp - Udp - UdpLite -} - -type Ip struct { // nolint:revive - Forwarding *float64 - DefaultTTL *float64 - InReceives *float64 - InHdrErrors *float64 - InAddrErrors *float64 - ForwDatagrams *float64 - InUnknownProtos *float64 - InDiscards *float64 - InDelivers *float64 - OutRequests *float64 - OutDiscards *float64 - OutNoRoutes *float64 - ReasmTimeout *float64 - ReasmReqds *float64 - ReasmOKs *float64 - ReasmFails *float64 - FragOKs *float64 - FragFails *float64 - FragCreates *float64 -} - -type Icmp struct { // nolint:revive - InMsgs *float64 - InErrors *float64 - InCsumErrors *float64 - InDestUnreachs *float64 - InTimeExcds *float64 - InParmProbs *float64 - InSrcQuenchs *float64 - InRedirects *float64 - InEchos *float64 - InEchoReps *float64 - InTimestamps *float64 - InTimestampReps *float64 - InAddrMasks *float64 - InAddrMaskReps *float64 - OutMsgs *float64 - OutErrors *float64 - OutDestUnreachs *float64 - OutTimeExcds *float64 - OutParmProbs *float64 - OutSrcQuenchs *float64 - OutRedirects *float64 - OutEchos *float64 - OutEchoReps *float64 - OutTimestamps *float64 - OutTimestampReps *float64 - OutAddrMasks *float64 - OutAddrMaskReps *float64 -} - -type IcmpMsg struct { - InType3 *float64 - OutType3 *float64 -} - -type Tcp struct { // nolint:revive - RtoAlgorithm *float64 - RtoMin *float64 - RtoMax *float64 - MaxConn *float64 - ActiveOpens *float64 - PassiveOpens *float64 - AttemptFails *float64 - EstabResets *float64 - CurrEstab *float64 - InSegs *float64 - OutSegs *float64 - RetransSegs *float64 - InErrs *float64 - OutRsts *float64 - InCsumErrors *float64 -} - -type Udp struct { // nolint:revive - InDatagrams *float64 - NoPorts *float64 - InErrors *float64 - OutDatagrams *float64 - RcvbufErrors *float64 - SndbufErrors *float64 - InCsumErrors *float64 - IgnoredMulti *float64 -} - -type UdpLite struct { // nolint:revive - InDatagrams *float64 - NoPorts *float64 - InErrors *float64 - OutDatagrams *float64 - RcvbufErrors *float64 - SndbufErrors *float64 - InCsumErrors *float64 - IgnoredMulti *float64 -} - -func (p Proc) Snmp() (ProcSnmp, error) { - filename := p.path("net/snmp") - data, err := util.ReadFileNoStat(filename) - if err != nil { - return ProcSnmp{PID: p.PID}, err - } - procSnmp, err := parseSnmp(bytes.NewReader(data), filename) - procSnmp.PID = p.PID - return procSnmp, err -} - -// parseSnmp parses the metrics from proc//net/snmp file -// and returns a map contains those metrics (e.g. {"Ip": {"Forwarding": 2}}). -func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) { - var ( - scanner = bufio.NewScanner(r) - procSnmp = ProcSnmp{} - ) - - for scanner.Scan() { - nameParts := strings.Split(scanner.Text(), " ") - scanner.Scan() - valueParts := strings.Split(scanner.Text(), " ") - // Remove trailing :. - protocol := strings.TrimSuffix(nameParts[0], ":") - if len(nameParts) != len(valueParts) { - return procSnmp, fmt.Errorf("%w: mismatch field count mismatch in %s: %s", - ErrFileParse, fileName, protocol) - } - for i := 1; i < len(nameParts); i++ { - value, err := strconv.ParseFloat(valueParts[i], 64) - if err != nil { - return procSnmp, err - } - key := nameParts[i] - - switch protocol { - case "Ip": - switch key { - case "Forwarding": - procSnmp.Forwarding = &value - case "DefaultTTL": - procSnmp.DefaultTTL = &value - case "InReceives": - procSnmp.InReceives = &value - case "InHdrErrors": - procSnmp.InHdrErrors = &value - case "InAddrErrors": - procSnmp.InAddrErrors = &value - case "ForwDatagrams": - procSnmp.ForwDatagrams = &value - case "InUnknownProtos": - procSnmp.InUnknownProtos = &value - case "InDiscards": - procSnmp.InDiscards = &value - case "InDelivers": - procSnmp.InDelivers = &value - case "OutRequests": - procSnmp.OutRequests = &value - case "OutDiscards": - procSnmp.OutDiscards = &value - case "OutNoRoutes": - procSnmp.OutNoRoutes = &value - case "ReasmTimeout": - procSnmp.ReasmTimeout = &value - case "ReasmReqds": - procSnmp.ReasmReqds = &value - case "ReasmOKs": - procSnmp.ReasmOKs = &value - case "ReasmFails": - procSnmp.ReasmFails = &value - case "FragOKs": - procSnmp.FragOKs = &value - case "FragFails": - procSnmp.FragFails = &value - case "FragCreates": - procSnmp.FragCreates = &value - } - case "Icmp": - switch key { - case "InMsgs": - procSnmp.InMsgs = &value - case "InErrors": - procSnmp.Icmp.InErrors = &value - case "InCsumErrors": - procSnmp.Icmp.InCsumErrors = &value - case "InDestUnreachs": - procSnmp.InDestUnreachs = &value - case "InTimeExcds": - procSnmp.InTimeExcds = &value - case "InParmProbs": - procSnmp.InParmProbs = &value - case "InSrcQuenchs": - procSnmp.InSrcQuenchs = &value - case "InRedirects": - procSnmp.InRedirects = &value - case "InEchos": - procSnmp.InEchos = &value - case "InEchoReps": - procSnmp.InEchoReps = &value - case "InTimestamps": - procSnmp.InTimestamps = &value - case "InTimestampReps": - procSnmp.InTimestampReps = &value - case "InAddrMasks": - procSnmp.InAddrMasks = &value - case "InAddrMaskReps": - procSnmp.InAddrMaskReps = &value - case "OutMsgs": - procSnmp.OutMsgs = &value - case "OutErrors": - procSnmp.OutErrors = &value - case "OutDestUnreachs": - procSnmp.OutDestUnreachs = &value - case "OutTimeExcds": - procSnmp.OutTimeExcds = &value - case "OutParmProbs": - procSnmp.OutParmProbs = &value - case "OutSrcQuenchs": - procSnmp.OutSrcQuenchs = &value - case "OutRedirects": - procSnmp.OutRedirects = &value - case "OutEchos": - procSnmp.OutEchos = &value - case "OutEchoReps": - procSnmp.OutEchoReps = &value - case "OutTimestamps": - procSnmp.OutTimestamps = &value - case "OutTimestampReps": - procSnmp.OutTimestampReps = &value - case "OutAddrMasks": - procSnmp.OutAddrMasks = &value - case "OutAddrMaskReps": - procSnmp.OutAddrMaskReps = &value - } - case "IcmpMsg": - switch key { - case "InType3": - procSnmp.InType3 = &value - case "OutType3": - procSnmp.OutType3 = &value - } - case "Tcp": - switch key { - case "RtoAlgorithm": - procSnmp.RtoAlgorithm = &value - case "RtoMin": - procSnmp.RtoMin = &value - case "RtoMax": - procSnmp.RtoMax = &value - case "MaxConn": - procSnmp.MaxConn = &value - case "ActiveOpens": - procSnmp.ActiveOpens = &value - case "PassiveOpens": - procSnmp.PassiveOpens = &value - case "AttemptFails": - procSnmp.AttemptFails = &value - case "EstabResets": - procSnmp.EstabResets = &value - case "CurrEstab": - procSnmp.CurrEstab = &value - case "InSegs": - procSnmp.InSegs = &value - case "OutSegs": - procSnmp.OutSegs = &value - case "RetransSegs": - procSnmp.RetransSegs = &value - case "InErrs": - procSnmp.InErrs = &value - case "OutRsts": - procSnmp.OutRsts = &value - case "InCsumErrors": - procSnmp.Tcp.InCsumErrors = &value - } - case "Udp": - switch key { - case "InDatagrams": - procSnmp.Udp.InDatagrams = &value - case "NoPorts": - procSnmp.Udp.NoPorts = &value - case "InErrors": - procSnmp.Udp.InErrors = &value - case "OutDatagrams": - procSnmp.Udp.OutDatagrams = &value - case "RcvbufErrors": - procSnmp.Udp.RcvbufErrors = &value - case "SndbufErrors": - procSnmp.Udp.SndbufErrors = &value - case "InCsumErrors": - procSnmp.Udp.InCsumErrors = &value - case "IgnoredMulti": - procSnmp.Udp.IgnoredMulti = &value - } - case "UdpLite": - switch key { - case "InDatagrams": - procSnmp.UdpLite.InDatagrams = &value - case "NoPorts": - procSnmp.UdpLite.NoPorts = &value - case "InErrors": - procSnmp.UdpLite.InErrors = &value - case "OutDatagrams": - procSnmp.UdpLite.OutDatagrams = &value - case "RcvbufErrors": - procSnmp.UdpLite.RcvbufErrors = &value - case "SndbufErrors": - procSnmp.UdpLite.SndbufErrors = &value - case "InCsumErrors": - procSnmp.UdpLite.InCsumErrors = &value - case "IgnoredMulti": - procSnmp.UdpLite.IgnoredMulti = &value - } - } - } - } - return procSnmp, scanner.Err() -} diff --git a/vendor/github.com/prometheus/procfs/proc_snmp6.go b/vendor/github.com/prometheus/procfs/proc_snmp6.go deleted file mode 100644 index 841fef464925..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_snmp6.go +++ /dev/null @@ -1,381 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "errors" - "io" - "os" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// ProcSnmp6 models the content of /proc//net/snmp6. -type ProcSnmp6 struct { - // The process ID. - PID int - Ip6 - Icmp6 - Udp6 - UdpLite6 -} - -type Ip6 struct { // nolint:revive - InReceives *float64 - InHdrErrors *float64 - InTooBigErrors *float64 - InNoRoutes *float64 - InAddrErrors *float64 - InUnknownProtos *float64 - InTruncatedPkts *float64 - InDiscards *float64 - InDelivers *float64 - OutForwDatagrams *float64 - OutRequests *float64 - OutDiscards *float64 - OutNoRoutes *float64 - ReasmTimeout *float64 - ReasmReqds *float64 - ReasmOKs *float64 - ReasmFails *float64 - FragOKs *float64 - FragFails *float64 - FragCreates *float64 - InMcastPkts *float64 - OutMcastPkts *float64 - InOctets *float64 - OutOctets *float64 - InMcastOctets *float64 - OutMcastOctets *float64 - InBcastOctets *float64 - OutBcastOctets *float64 - InNoECTPkts *float64 - InECT1Pkts *float64 - InECT0Pkts *float64 - InCEPkts *float64 -} - -type Icmp6 struct { - InMsgs *float64 - InErrors *float64 - OutMsgs *float64 - OutErrors *float64 - InCsumErrors *float64 - InDestUnreachs *float64 - InPktTooBigs *float64 - InTimeExcds *float64 - InParmProblems *float64 - InEchos *float64 - InEchoReplies *float64 - InGroupMembQueries *float64 - InGroupMembResponses *float64 - InGroupMembReductions *float64 - InRouterSolicits *float64 - InRouterAdvertisements *float64 - InNeighborSolicits *float64 - InNeighborAdvertisements *float64 - InRedirects *float64 - InMLDv2Reports *float64 - OutDestUnreachs *float64 - OutPktTooBigs *float64 - OutTimeExcds *float64 - OutParmProblems *float64 - OutEchos *float64 - OutEchoReplies *float64 - OutGroupMembQueries *float64 - OutGroupMembResponses *float64 - OutGroupMembReductions *float64 - OutRouterSolicits *float64 - OutRouterAdvertisements *float64 - OutNeighborSolicits *float64 - OutNeighborAdvertisements *float64 - OutRedirects *float64 - OutMLDv2Reports *float64 - InType1 *float64 - InType134 *float64 - InType135 *float64 - InType136 *float64 - InType143 *float64 - OutType133 *float64 - OutType135 *float64 - OutType136 *float64 - OutType143 *float64 -} - -type Udp6 struct { // nolint:revive - InDatagrams *float64 - NoPorts *float64 - InErrors *float64 - OutDatagrams *float64 - RcvbufErrors *float64 - SndbufErrors *float64 - InCsumErrors *float64 - IgnoredMulti *float64 -} - -type UdpLite6 struct { // nolint:revive - InDatagrams *float64 - NoPorts *float64 - InErrors *float64 - OutDatagrams *float64 - RcvbufErrors *float64 - SndbufErrors *float64 - InCsumErrors *float64 -} - -func (p Proc) Snmp6() (ProcSnmp6, error) { - filename := p.path("net/snmp6") - data, err := util.ReadFileNoStat(filename) - if err != nil { - // On systems with IPv6 disabled, this file won't exist. - // Do nothing. - if errors.Is(err, os.ErrNotExist) { - return ProcSnmp6{PID: p.PID}, nil - } - - return ProcSnmp6{PID: p.PID}, err - } - - procSnmp6, err := parseSNMP6Stats(bytes.NewReader(data)) - procSnmp6.PID = p.PID - return procSnmp6, err -} - -// parseSnmp6 parses the metrics from proc//net/snmp6 file -// and returns a map contains those metrics. -func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) { - var ( - scanner = bufio.NewScanner(r) - procSnmp6 = ProcSnmp6{} - ) - - for scanner.Scan() { - stat := strings.Fields(scanner.Text()) - if len(stat) < 2 { - continue - } - // Expect to have "6" in metric name, skip line otherwise - if sixIndex := strings.Index(stat[0], "6"); sixIndex != -1 { - protocol := stat[0][:sixIndex+1] - key := stat[0][sixIndex+1:] - value, err := strconv.ParseFloat(stat[1], 64) - if err != nil { - return procSnmp6, err - } - - switch protocol { - case "Ip6": - switch key { - case "InReceives": - procSnmp6.InReceives = &value - case "InHdrErrors": - procSnmp6.InHdrErrors = &value - case "InTooBigErrors": - procSnmp6.InTooBigErrors = &value - case "InNoRoutes": - procSnmp6.InNoRoutes = &value - case "InAddrErrors": - procSnmp6.InAddrErrors = &value - case "InUnknownProtos": - procSnmp6.InUnknownProtos = &value - case "InTruncatedPkts": - procSnmp6.InTruncatedPkts = &value - case "InDiscards": - procSnmp6.InDiscards = &value - case "InDelivers": - procSnmp6.InDelivers = &value - case "OutForwDatagrams": - procSnmp6.OutForwDatagrams = &value - case "OutRequests": - procSnmp6.OutRequests = &value - case "OutDiscards": - procSnmp6.OutDiscards = &value - case "OutNoRoutes": - procSnmp6.OutNoRoutes = &value - case "ReasmTimeout": - procSnmp6.ReasmTimeout = &value - case "ReasmReqds": - procSnmp6.ReasmReqds = &value - case "ReasmOKs": - procSnmp6.ReasmOKs = &value - case "ReasmFails": - procSnmp6.ReasmFails = &value - case "FragOKs": - procSnmp6.FragOKs = &value - case "FragFails": - procSnmp6.FragFails = &value - case "FragCreates": - procSnmp6.FragCreates = &value - case "InMcastPkts": - procSnmp6.InMcastPkts = &value - case "OutMcastPkts": - procSnmp6.OutMcastPkts = &value - case "InOctets": - procSnmp6.InOctets = &value - case "OutOctets": - procSnmp6.OutOctets = &value - case "InMcastOctets": - procSnmp6.InMcastOctets = &value - case "OutMcastOctets": - procSnmp6.OutMcastOctets = &value - case "InBcastOctets": - procSnmp6.InBcastOctets = &value - case "OutBcastOctets": - procSnmp6.OutBcastOctets = &value - case "InNoECTPkts": - procSnmp6.InNoECTPkts = &value - case "InECT1Pkts": - procSnmp6.InECT1Pkts = &value - case "InECT0Pkts": - procSnmp6.InECT0Pkts = &value - case "InCEPkts": - procSnmp6.InCEPkts = &value - - } - case "Icmp6": - switch key { - case "InMsgs": - procSnmp6.InMsgs = &value - case "InErrors": - procSnmp6.Icmp6.InErrors = &value - case "OutMsgs": - procSnmp6.OutMsgs = &value - case "OutErrors": - procSnmp6.OutErrors = &value - case "InCsumErrors": - procSnmp6.Icmp6.InCsumErrors = &value - case "InDestUnreachs": - procSnmp6.InDestUnreachs = &value - case "InPktTooBigs": - procSnmp6.InPktTooBigs = &value - case "InTimeExcds": - procSnmp6.InTimeExcds = &value - case "InParmProblems": - procSnmp6.InParmProblems = &value - case "InEchos": - procSnmp6.InEchos = &value - case "InEchoReplies": - procSnmp6.InEchoReplies = &value - case "InGroupMembQueries": - procSnmp6.InGroupMembQueries = &value - case "InGroupMembResponses": - procSnmp6.InGroupMembResponses = &value - case "InGroupMembReductions": - procSnmp6.InGroupMembReductions = &value - case "InRouterSolicits": - procSnmp6.InRouterSolicits = &value - case "InRouterAdvertisements": - procSnmp6.InRouterAdvertisements = &value - case "InNeighborSolicits": - procSnmp6.InNeighborSolicits = &value - case "InNeighborAdvertisements": - procSnmp6.InNeighborAdvertisements = &value - case "InRedirects": - procSnmp6.InRedirects = &value - case "InMLDv2Reports": - procSnmp6.InMLDv2Reports = &value - case "OutDestUnreachs": - procSnmp6.OutDestUnreachs = &value - case "OutPktTooBigs": - procSnmp6.OutPktTooBigs = &value - case "OutTimeExcds": - procSnmp6.OutTimeExcds = &value - case "OutParmProblems": - procSnmp6.OutParmProblems = &value - case "OutEchos": - procSnmp6.OutEchos = &value - case "OutEchoReplies": - procSnmp6.OutEchoReplies = &value - case "OutGroupMembQueries": - procSnmp6.OutGroupMembQueries = &value - case "OutGroupMembResponses": - procSnmp6.OutGroupMembResponses = &value - case "OutGroupMembReductions": - procSnmp6.OutGroupMembReductions = &value - case "OutRouterSolicits": - procSnmp6.OutRouterSolicits = &value - case "OutRouterAdvertisements": - procSnmp6.OutRouterAdvertisements = &value - case "OutNeighborSolicits": - procSnmp6.OutNeighborSolicits = &value - case "OutNeighborAdvertisements": - procSnmp6.OutNeighborAdvertisements = &value - case "OutRedirects": - procSnmp6.OutRedirects = &value - case "OutMLDv2Reports": - procSnmp6.OutMLDv2Reports = &value - case "InType1": - procSnmp6.InType1 = &value - case "InType134": - procSnmp6.InType134 = &value - case "InType135": - procSnmp6.InType135 = &value - case "InType136": - procSnmp6.InType136 = &value - case "InType143": - procSnmp6.InType143 = &value - case "OutType133": - procSnmp6.OutType133 = &value - case "OutType135": - procSnmp6.OutType135 = &value - case "OutType136": - procSnmp6.OutType136 = &value - case "OutType143": - procSnmp6.OutType143 = &value - } - case "Udp6": - switch key { - case "InDatagrams": - procSnmp6.Udp6.InDatagrams = &value - case "NoPorts": - procSnmp6.Udp6.NoPorts = &value - case "InErrors": - procSnmp6.Udp6.InErrors = &value - case "OutDatagrams": - procSnmp6.Udp6.OutDatagrams = &value - case "RcvbufErrors": - procSnmp6.Udp6.RcvbufErrors = &value - case "SndbufErrors": - procSnmp6.Udp6.SndbufErrors = &value - case "InCsumErrors": - procSnmp6.Udp6.InCsumErrors = &value - case "IgnoredMulti": - procSnmp6.IgnoredMulti = &value - } - case "UdpLite6": - switch key { - case "InDatagrams": - procSnmp6.UdpLite6.InDatagrams = &value - case "NoPorts": - procSnmp6.UdpLite6.NoPorts = &value - case "InErrors": - procSnmp6.UdpLite6.InErrors = &value - case "OutDatagrams": - procSnmp6.UdpLite6.OutDatagrams = &value - case "RcvbufErrors": - procSnmp6.UdpLite6.RcvbufErrors = &value - case "SndbufErrors": - procSnmp6.UdpLite6.SndbufErrors = &value - case "InCsumErrors": - procSnmp6.UdpLite6.InCsumErrors = &value - } - } - } - } - return procSnmp6, scanner.Err() -} diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go deleted file mode 100644 index 02e3f9e316af..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_stat.go +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bytes" - "fmt" - "os" - - "github.com/prometheus/procfs/internal/util" -) - -// Originally, this USER_HZ value was dynamically retrieved via a sysconf call -// which required cgo. However, that caused a lot of problems regarding -// cross-compilation. Alternatives such as running a binary to determine the -// value, or trying to derive it in some other way were all problematic. After -// much research it was determined that USER_HZ is actually hardcoded to 100 on -// all Go-supported platforms as of the time of this writing. This is why we -// decided to hardcode it here as well. It is not impossible that there could -// be systems with exceptions, but they should be very exotic edge cases, and -// in that case, the worst outcome will be two misreported metrics. -// -// See also the following discussions: -// -// - https://github.com/prometheus/node_exporter/issues/52 -// - https://github.com/prometheus/procfs/pull/2 -// - http://stackoverflow.com/questions/17410841/how-does-user-hz-solve-the-jiffy-scaling-issue -const userHZ = 100 - -// ProcStat provides status information about the process, -// read from /proc/[pid]/stat. -type ProcStat struct { - // The process ID. - PID int - // The filename of the executable. - Comm string - // The process state. - State string - // The PID of the parent of this process. - PPID int - // The process group ID of the process. - PGRP int - // The session ID of the process. - Session int - // The controlling terminal of the process. - TTY int - // The ID of the foreground process group of the controlling terminal of - // the process. - TPGID int - // The kernel flags word of the process. - Flags uint - // The number of minor faults the process has made which have not required - // loading a memory page from disk. - MinFlt uint - // The number of minor faults that the process's waited-for children have - // made. - CMinFlt uint - // The number of major faults the process has made which have required - // loading a memory page from disk. - MajFlt uint - // The number of major faults that the process's waited-for children have - // made. - CMajFlt uint - // Amount of time that this process has been scheduled in user mode, - // measured in clock ticks. - UTime uint - // Amount of time that this process has been scheduled in kernel mode, - // measured in clock ticks. - STime uint - // Amount of time that this process's waited-for children have been - // scheduled in user mode, measured in clock ticks. - CUTime int - // Amount of time that this process's waited-for children have been - // scheduled in kernel mode, measured in clock ticks. - CSTime int - // For processes running a real-time scheduling policy, this is the negated - // scheduling priority, minus one. - Priority int - // The nice value, a value in the range 19 (low priority) to -20 (high - // priority). - Nice int - // Number of threads in this process. - NumThreads int - // The time the process started after system boot, the value is expressed - // in clock ticks. - Starttime uint64 - // Virtual memory size in bytes. - VSize uint - // Resident set size in pages. - RSS int - // Soft limit in bytes on the rss of the process. - RSSLimit uint64 - // The address above which program text can run. - StartCode uint64 - // The address below which program text can run. - EndCode uint64 - // The address of the start (i.e., bottom) of the stack. - StartStack uint64 - // CPU number last executed on. - Processor uint - // Real-time scheduling priority, a number in the range 1 to 99 for processes - // scheduled under a real-time policy, or 0, for non-real-time processes. - RTPriority uint - // Scheduling policy. - Policy uint - // Aggregated block I/O delays, measured in clock ticks (centiseconds). - DelayAcctBlkIOTicks uint64 - // Guest time of the process (time spent running a virtual CPU for a guest - // operating system), measured in clock ticks. - GuestTime int - // Guest time of the process's children, measured in clock ticks. - CGuestTime int - - proc FS -} - -// NewStat returns the current status information of the process. -// -// Deprecated: Use p.Stat() instead. -func (p Proc) NewStat() (ProcStat, error) { - return p.Stat() -} - -// Stat returns the current status information of the process. -func (p Proc) Stat() (ProcStat, error) { - data, err := util.ReadFileNoStat(p.path("stat")) - if err != nil { - return ProcStat{}, err - } - - var ( - ignoreInt64 int64 - ignoreUint64 uint64 - - s = ProcStat{PID: p.PID, proc: p.fs} - l = bytes.Index(data, []byte("(")) - r = bytes.LastIndex(data, []byte(")")) - ) - - if l < 0 || r < 0 { - return ProcStat{}, fmt.Errorf("%w: unexpected format, couldn't extract comm %q", ErrFileParse, data) - } - - s.Comm = string(data[l+1 : r]) - - // Check the following resources for the details about the particular stat - // fields and their data types: - // * https://man7.org/linux/man-pages/man5/proc.5.html - // * https://man7.org/linux/man-pages/man3/scanf.3.html - _, err = fmt.Fscan( - bytes.NewBuffer(data[r+2:]), - &s.State, - &s.PPID, - &s.PGRP, - &s.Session, - &s.TTY, - &s.TPGID, - &s.Flags, - &s.MinFlt, - &s.CMinFlt, - &s.MajFlt, - &s.CMajFlt, - &s.UTime, - &s.STime, - &s.CUTime, - &s.CSTime, - &s.Priority, - &s.Nice, - &s.NumThreads, - &ignoreInt64, - &s.Starttime, - &s.VSize, - &s.RSS, - &s.RSSLimit, - &s.StartCode, - &s.EndCode, - &s.StartStack, - &ignoreUint64, - &ignoreUint64, - &ignoreUint64, - &ignoreUint64, - &ignoreUint64, - &ignoreUint64, - &ignoreUint64, - &ignoreUint64, - &ignoreUint64, - &ignoreInt64, - &s.Processor, - &s.RTPriority, - &s.Policy, - &s.DelayAcctBlkIOTicks, - &s.GuestTime, - &s.CGuestTime, - ) - if err != nil { - return ProcStat{}, err - } - - return s, nil -} - -// VirtualMemory returns the virtual memory size in bytes. -func (s ProcStat) VirtualMemory() uint { - return s.VSize -} - -// ResidentMemory returns the resident memory size in bytes. -func (s ProcStat) ResidentMemory() int { - return s.RSS * os.Getpagesize() -} - -// StartTime returns the unix timestamp of the process in seconds. -func (s ProcStat) StartTime() (float64, error) { - stat, err := s.proc.Stat() - if err != nil { - return 0, err - } - return float64(stat.BootTime) + (float64(s.Starttime) / userHZ), nil -} - -// CPUTime returns the total CPU user and system time in seconds. -func (s ProcStat) CPUTime() float64 { - return float64(s.UTime+s.STime) / userHZ -} diff --git a/vendor/github.com/prometheus/procfs/proc_statm.go b/vendor/github.com/prometheus/procfs/proc_statm.go deleted file mode 100644 index 6bcc97ec9c22..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_statm.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "os" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// - https://man7.org/linux/man-pages/man5/proc_pid_statm.5.html - -// ProcStatm Provides memory usage information for a process, measured in memory pages. -// Read from /proc/[pid]/statm. -type ProcStatm struct { - // The process ID. - PID int - // total program size (same as VmSize in status) - Size uint64 - // resident set size (same as VmRSS in status) - Resident uint64 - // number of resident shared pages (i.e., backed by a file) - Shared uint64 - // text (code) - Text uint64 - // library (unused since Linux 2.6; always 0) - Lib uint64 - // data + stack - Data uint64 - // dirty pages (unused since Linux 2.6; always 0) - Dt uint64 -} - -// NewStatm returns the current status information of the process. -// -// Deprecated: Use p.Statm() instead. -func (p Proc) NewStatm() (ProcStatm, error) { - return p.Statm() -} - -// Statm returns the current memory usage information of the process. -func (p Proc) Statm() (ProcStatm, error) { - data, err := util.ReadFileNoStat(p.path("statm")) - if err != nil { - return ProcStatm{}, err - } - - statmSlice, err := parseStatm(data) - if err != nil { - return ProcStatm{}, err - } - - procStatm := ProcStatm{ - PID: p.PID, - Size: statmSlice[0], - Resident: statmSlice[1], - Shared: statmSlice[2], - Text: statmSlice[3], - Lib: statmSlice[4], - Data: statmSlice[5], - Dt: statmSlice[6], - } - - return procStatm, nil -} - -// parseStatm return /proc/[pid]/statm data to uint64 slice. -func parseStatm(data []byte) ([]uint64, error) { - var statmSlice []uint64 - statmItems := strings.Fields(string(data)) - for i := range statmItems { - statmItem, err := strconv.ParseUint(statmItems[i], 10, 64) - if err != nil { - return nil, err - } - statmSlice = append(statmSlice, statmItem) - } - return statmSlice, nil -} - -// SizeBytes returns the process of total program size in bytes. -func (s ProcStatm) SizeBytes() uint64 { - return s.Size * uint64(os.Getpagesize()) -} - -// ResidentBytes returns the process of resident set size in bytes. -func (s ProcStatm) ResidentBytes() uint64 { - return s.Resident * uint64(os.Getpagesize()) -} - -// SHRBytes returns the process of share memory size in bytes. -func (s ProcStatm) SHRBytes() uint64 { - return s.Shared * uint64(os.Getpagesize()) -} - -// TextBytes returns the process of text (code) size in bytes. -func (s ProcStatm) TextBytes() uint64 { - return s.Text * uint64(os.Getpagesize()) -} - -// DataBytes returns the process of data + stack size in bytes. -func (s ProcStatm) DataBytes() uint64 { - return s.Data * uint64(os.Getpagesize()) -} diff --git a/vendor/github.com/prometheus/procfs/proc_status.go b/vendor/github.com/prometheus/procfs/proc_status.go deleted file mode 100644 index 12d65581c82b..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_status.go +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bytes" - "math/bits" - "slices" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// ProcStatus provides status information about the process, -// read from /proc/[pid]/status. -type ProcStatus struct { - // The process ID. - PID int - // The process name. - Name string - - // Thread group ID. - TGID int - // List of Pid namespace. - NSpids []uint64 - - // Peak virtual memory size. - VmPeak uint64 // nolint:revive - // Virtual memory size. - VmSize uint64 // nolint:revive - // Locked memory size. - VmLck uint64 // nolint:revive - // Pinned memory size. - VmPin uint64 // nolint:revive - // Peak resident set size. - VmHWM uint64 // nolint:revive - // Resident set size (sum of RssAnnon RssFile and RssShmem). - VmRSS uint64 // nolint:revive - // Size of resident anonymous memory. - RssAnon uint64 // nolint:revive - // Size of resident file mappings. - RssFile uint64 // nolint:revive - // Size of resident shared memory. - RssShmem uint64 // nolint:revive - // Size of data segments. - VmData uint64 // nolint:revive - // Size of stack segments. - VmStk uint64 // nolint:revive - // Size of text segments. - VmExe uint64 // nolint:revive - // Shared library code size. - VmLib uint64 // nolint:revive - // Page table entries size. - VmPTE uint64 // nolint:revive - // Size of second-level page tables. - VmPMD uint64 // nolint:revive - // Swapped-out virtual memory size by anonymous private. - VmSwap uint64 // nolint:revive - // Size of hugetlb memory portions - HugetlbPages uint64 - - // Number of voluntary context switches. - VoluntaryCtxtSwitches uint64 - // Number of involuntary context switches. - NonVoluntaryCtxtSwitches uint64 - - // UIDs of the process (Real, effective, saved set, and filesystem UIDs) - UIDs [4]uint64 - // GIDs of the process (Real, effective, saved set, and filesystem GIDs) - GIDs [4]uint64 - - // CpusAllowedList: List of cpu cores processes are allowed to run on. - CpusAllowedList []uint64 - - // CapInh is the bitmap of inheritable capabilities - // - // See: https://www.kernel.org/doc/man-pages/online/pages/man7/capabilities.7.html - CapInh uint64 - // CapPrm is the bitmap of permitted capabilities - CapPrm uint64 - // CapEff is the bitmap of effective capabilities - CapEff uint64 - // CapBnd is the bitmap of bounding capabilities - CapBnd uint64 - // CapAmb is the bitmap of ambient capabilities - CapAmb uint64 -} - -// NewStatus returns the current status information of the process. -func (p Proc) NewStatus() (ProcStatus, error) { - data, err := util.ReadFileNoStat(p.path("status")) - if err != nil { - return ProcStatus{}, err - } - - s := ProcStatus{PID: p.PID} - - for line := range strings.SplitSeq(string(data), "\n") { - if !bytes.Contains([]byte(line), []byte(":")) { - continue - } - - kv := strings.SplitN(line, ":", 2) - - // removes spaces - k := strings.TrimSpace(kv[0]) - v := strings.TrimSpace(kv[1]) - // removes "kB" - v = strings.TrimSuffix(v, " kB") - - // value to int when possible - // we can skip error check here, 'cause vKBytes is not used when value is a string - vKBytes, _ := strconv.ParseUint(v, 10, 64) - // convert kB to B - vBytes := vKBytes * 1024 - - err = s.fillStatus(k, v, vKBytes, vBytes) - if err != nil { - return ProcStatus{}, err - } - } - - return s, nil -} - -func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) error { - switch k { - case "Tgid": - s.TGID = int(vUint) - case "Name": - s.Name = vString - case "Uid": - var err error - for i, v := range strings.Split(vString, "\t") { - s.UIDs[i], err = strconv.ParseUint(v, 10, bits.UintSize) - if err != nil { - return err - } - } - case "Gid": - var err error - for i, v := range strings.Split(vString, "\t") { - s.GIDs[i], err = strconv.ParseUint(v, 10, bits.UintSize) - if err != nil { - return err - } - } - case "NSpid": - nspids, err := calcNSPidsList(vString) - if err != nil { - return err - } - s.NSpids = nspids - case "VmPeak": - s.VmPeak = vUintBytes - case "VmSize": - s.VmSize = vUintBytes - case "VmLck": - s.VmLck = vUintBytes - case "VmPin": - s.VmPin = vUintBytes - case "VmHWM": - s.VmHWM = vUintBytes - case "VmRSS": - s.VmRSS = vUintBytes - case "RssAnon": - s.RssAnon = vUintBytes - case "RssFile": - s.RssFile = vUintBytes - case "RssShmem": - s.RssShmem = vUintBytes - case "VmData": - s.VmData = vUintBytes - case "VmStk": - s.VmStk = vUintBytes - case "VmExe": - s.VmExe = vUintBytes - case "VmLib": - s.VmLib = vUintBytes - case "VmPTE": - s.VmPTE = vUintBytes - case "VmPMD": - s.VmPMD = vUintBytes - case "VmSwap": - s.VmSwap = vUintBytes - case "HugetlbPages": - s.HugetlbPages = vUintBytes - case "voluntary_ctxt_switches": - s.VoluntaryCtxtSwitches = vUint - case "nonvoluntary_ctxt_switches": - s.NonVoluntaryCtxtSwitches = vUint - case "Cpus_allowed_list": - s.CpusAllowedList = calcCpusAllowedList(vString) - case "CapInh": - var err error - s.CapInh, err = strconv.ParseUint(vString, 16, 64) - if err != nil { - return err - } - case "CapPrm": - var err error - s.CapPrm, err = strconv.ParseUint(vString, 16, 64) - if err != nil { - return err - } - case "CapEff": - var err error - s.CapEff, err = strconv.ParseUint(vString, 16, 64) - if err != nil { - return err - } - case "CapBnd": - var err error - s.CapBnd, err = strconv.ParseUint(vString, 16, 64) - if err != nil { - return err - } - case "CapAmb": - var err error - s.CapAmb, err = strconv.ParseUint(vString, 16, 64) - if err != nil { - return err - } - } - - return nil -} - -// TotalCtxtSwitches returns the total context switch. -func (s ProcStatus) TotalCtxtSwitches() uint64 { - return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches -} - -func calcCpusAllowedList(cpuString string) []uint64 { - s := strings.Split(cpuString, ",") - - var g []uint64 - - for _, cpu := range s { - // parse cpu ranges, example: 1-3=[1,2,3] - if l := strings.Split(strings.TrimSpace(cpu), "-"); len(l) > 1 { - startCPU, _ := strconv.ParseUint(l[0], 10, 64) - endCPU, _ := strconv.ParseUint(l[1], 10, 64) - - for i := startCPU; i <= endCPU; i++ { - g = append(g, i) - } - } else if len(l) == 1 { - cpu, _ := strconv.ParseUint(l[0], 10, 64) - g = append(g, cpu) - } - - } - - slices.Sort(g) - return g -} - -func calcNSPidsList(nspidsString string) ([]uint64, error) { - s := strings.Split(nspidsString, "\t") - var nspids []uint64 - - for _, nspid := range s { - nspid, err := strconv.ParseUint(nspid, 10, 64) - if err != nil { - return nil, err - } - nspids = append(nspids, nspid) - } - - return nspids, nil -} diff --git a/vendor/github.com/prometheus/procfs/proc_sys.go b/vendor/github.com/prometheus/procfs/proc_sys.go deleted file mode 100644 index 52658a4d52d4..000000000000 --- a/vendor/github.com/prometheus/procfs/proc_sys.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "fmt" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -func sysctlToPath(sysctl string) string { - return strings.ReplaceAll(sysctl, ".", "/") -} - -func (fs FS) SysctlStrings(sysctl string) ([]string, error) { - value, err := util.SysReadFile(fs.proc.Path("sys", sysctlToPath(sysctl))) - if err != nil { - return nil, err - } - return strings.Fields(value), nil - -} - -func (fs FS) SysctlInts(sysctl string) ([]int, error) { - fields, err := fs.SysctlStrings(sysctl) - if err != nil { - return nil, err - } - - values := make([]int, len(fields)) - for i, f := range fields { - vp := util.NewValueParser(f) - values[i] = vp.Int() - if err := vp.Err(); err != nil { - return nil, fmt.Errorf("%w: field %d in sysctl %s is not a valid int: %w", ErrFileParse, i, sysctl, err) - } - } - return values, nil -} diff --git a/vendor/github.com/prometheus/procfs/schedstat.go b/vendor/github.com/prometheus/procfs/schedstat.go deleted file mode 100644 index fafd8dff740b..000000000000 --- a/vendor/github.com/prometheus/procfs/schedstat.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "errors" - "os" - "regexp" - "strconv" -) - -var ( - cpuLineRE = regexp.MustCompile(`cpu(\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+)`) - procLineRE = regexp.MustCompile(`(\d+) (\d+) (\d+)`) -) - -// Schedstat contains scheduler statistics from /proc/schedstat -// -// See -// https://www.kernel.org/doc/Documentation/scheduler/sched-stats.txt -// for a detailed description of what these numbers mean. -// -// Note the current kernel documentation claims some of the time units are in -// jiffies when they are actually in nanoseconds since 2.6.23 with the -// introduction of CFS. A fix to the documentation is pending. See -// https://lore.kernel.org/patchwork/project/lkml/list/?series=403473 -type Schedstat struct { - CPUs []*SchedstatCPU -} - -// SchedstatCPU contains the values from one "cpu" line. -type SchedstatCPU struct { - CPUNum string - - RunningNanoseconds uint64 - WaitingNanoseconds uint64 - RunTimeslices uint64 -} - -// ProcSchedstat contains the values from `/proc//schedstat`. -type ProcSchedstat struct { - RunningNanoseconds uint64 - WaitingNanoseconds uint64 - RunTimeslices uint64 -} - -// Schedstat reads data from `/proc/schedstat`. -func (fs FS) Schedstat() (*Schedstat, error) { - file, err := os.Open(fs.proc.Path("schedstat")) - if err != nil { - return nil, err - } - defer file.Close() - - stats := &Schedstat{} - scanner := bufio.NewScanner(file) - - for scanner.Scan() { - match := cpuLineRE.FindStringSubmatch(scanner.Text()) - if match != nil { - cpu := &SchedstatCPU{} - cpu.CPUNum = match[1] - - cpu.RunningNanoseconds, err = strconv.ParseUint(match[8], 10, 64) - if err != nil { - continue - } - - cpu.WaitingNanoseconds, err = strconv.ParseUint(match[9], 10, 64) - if err != nil { - continue - } - - cpu.RunTimeslices, err = strconv.ParseUint(match[10], 10, 64) - if err != nil { - continue - } - - stats.CPUs = append(stats.CPUs, cpu) - } - } - - return stats, nil -} - -func parseProcSchedstat(contents string) (ProcSchedstat, error) { - var ( - stats ProcSchedstat - err error - ) - match := procLineRE.FindStringSubmatch(contents) - - if match != nil { - stats.RunningNanoseconds, err = strconv.ParseUint(match[1], 10, 64) - if err != nil { - return stats, err - } - - stats.WaitingNanoseconds, err = strconv.ParseUint(match[2], 10, 64) - if err != nil { - return stats, err - } - - stats.RunTimeslices, err = strconv.ParseUint(match[3], 10, 64) - return stats, err - } - - return stats, errors.New("could not parse schedstat") -} diff --git a/vendor/github.com/prometheus/procfs/slab.go b/vendor/github.com/prometheus/procfs/slab.go deleted file mode 100644 index 32a04678ad0b..000000000000 --- a/vendor/github.com/prometheus/procfs/slab.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "regexp" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -var ( - slabSpace = regexp.MustCompile(`\s+`) - slabVer = regexp.MustCompile(`slabinfo -`) - slabHeader = regexp.MustCompile(`# name`) -) - -// Slab represents a slab pool in the kernel. -type Slab struct { - Name string - ObjActive int64 - ObjNum int64 - ObjSize int64 - ObjPerSlab int64 - PagesPerSlab int64 - // tunables - Limit int64 - Batch int64 - SharedFactor int64 - SlabActive int64 - SlabNum int64 - SharedAvail int64 -} - -// SlabInfo represents info for all slabs. -type SlabInfo struct { - Slabs []*Slab -} - -func shouldParseSlab(line string) bool { - if slabVer.MatchString(line) { - return false - } - if slabHeader.MatchString(line) { - return false - } - return true -} - -// parseV21SlabEntry is used to parse a line from /proc/slabinfo version 2.1. -func parseV21SlabEntry(line string) (*Slab, error) { - // First cleanup whitespace. - l := slabSpace.ReplaceAllString(line, " ") - s := strings.Split(l, " ") - if len(s) != 16 { - return nil, fmt.Errorf("%w: unable to parse: %q", ErrFileParse, line) - } - var err error - i := &Slab{Name: s[0]} - i.ObjActive, err = strconv.ParseInt(s[1], 10, 64) - if err != nil { - return nil, err - } - i.ObjNum, err = strconv.ParseInt(s[2], 10, 64) - if err != nil { - return nil, err - } - i.ObjSize, err = strconv.ParseInt(s[3], 10, 64) - if err != nil { - return nil, err - } - i.ObjPerSlab, err = strconv.ParseInt(s[4], 10, 64) - if err != nil { - return nil, err - } - i.PagesPerSlab, err = strconv.ParseInt(s[5], 10, 64) - if err != nil { - return nil, err - } - i.Limit, err = strconv.ParseInt(s[8], 10, 64) - if err != nil { - return nil, err - } - i.Batch, err = strconv.ParseInt(s[9], 10, 64) - if err != nil { - return nil, err - } - i.SharedFactor, err = strconv.ParseInt(s[10], 10, 64) - if err != nil { - return nil, err - } - i.SlabActive, err = strconv.ParseInt(s[13], 10, 64) - if err != nil { - return nil, err - } - i.SlabNum, err = strconv.ParseInt(s[14], 10, 64) - if err != nil { - return nil, err - } - i.SharedAvail, err = strconv.ParseInt(s[15], 10, 64) - if err != nil { - return nil, err - } - return i, nil -} - -// parseSlabInfo21 is used to parse a slabinfo 2.1 file. -func parseSlabInfo21(r *bytes.Reader) (SlabInfo, error) { - scanner := bufio.NewScanner(r) - s := SlabInfo{Slabs: []*Slab{}} - for scanner.Scan() { - line := scanner.Text() - if !shouldParseSlab(line) { - continue - } - slab, err := parseV21SlabEntry(line) - if err != nil { - return s, err - } - s.Slabs = append(s.Slabs, slab) - } - return s, nil -} - -// SlabInfo reads data from `/proc/slabinfo`. -func (fs FS) SlabInfo() (SlabInfo, error) { - // TODO: Consider passing options to allow for parsing different - // slabinfo versions. However, slabinfo 2.1 has been stable since - // kernel 2.6.10 and later. - data, err := util.ReadFileNoStat(fs.proc.Path("slabinfo")) - if err != nil { - return SlabInfo{}, err - } - - return parseSlabInfo21(bytes.NewReader(data)) -} diff --git a/vendor/github.com/prometheus/procfs/softirqs.go b/vendor/github.com/prometheus/procfs/softirqs.go deleted file mode 100644 index 47b73a7297b3..000000000000 --- a/vendor/github.com/prometheus/procfs/softirqs.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Softirqs represents the softirq statistics. -type Softirqs struct { - Hi []uint64 - Timer []uint64 - NetTx []uint64 - NetRx []uint64 - Block []uint64 - IRQPoll []uint64 - Tasklet []uint64 - Sched []uint64 - HRTimer []uint64 - RCU []uint64 -} - -func (fs FS) Softirqs() (Softirqs, error) { - fileName := fs.proc.Path("softirqs") - data, err := util.ReadFileNoStat(fileName) - if err != nil { - return Softirqs{}, err - } - - reader := bytes.NewReader(data) - - return parseSoftirqs(reader) -} - -func parseSoftirqs(r io.Reader) (Softirqs, error) { - var ( - softirqs = Softirqs{} - scanner = bufio.NewScanner(r) - ) - - if !scanner.Scan() { - return Softirqs{}, fmt.Errorf("%w: softirqs empty", ErrFileRead) - } - - for scanner.Scan() { - parts := strings.Fields(scanner.Text()) - var err error - - // require at least one cpu - if len(parts) < 2 { - continue - } - switch parts[0] { - case "HI:": - perCPU := parts[1:] - softirqs.Hi = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.Hi[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (HI%d): %w", ErrFileParse, count, i, err) - } - } - case "TIMER:": - perCPU := parts[1:] - softirqs.Timer = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.Timer[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (TIMER%d): %w", ErrFileParse, count, i, err) - } - } - case "NET_TX:": - perCPU := parts[1:] - softirqs.NetTx = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.NetTx[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (NET_TX%d): %w", ErrFileParse, count, i, err) - } - } - case "NET_RX:": - perCPU := parts[1:] - softirqs.NetRx = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.NetRx[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (NET_RX%d): %w", ErrFileParse, count, i, err) - } - } - case "BLOCK:": - perCPU := parts[1:] - softirqs.Block = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.Block[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (BLOCK%d): %w", ErrFileParse, count, i, err) - } - } - case "IRQ_POLL:": - perCPU := parts[1:] - softirqs.IRQPoll = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.IRQPoll[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (IRQ_POLL%d): %w", ErrFileParse, count, i, err) - } - } - case "TASKLET:": - perCPU := parts[1:] - softirqs.Tasklet = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.Tasklet[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (TASKLET%d): %w", ErrFileParse, count, i, err) - } - } - case "SCHED:": - perCPU := parts[1:] - softirqs.Sched = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.Sched[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (SCHED%d): %w", ErrFileParse, count, i, err) - } - } - case "HRTIMER:": - perCPU := parts[1:] - softirqs.HRTimer = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.HRTimer[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (HRTIMER%d): %w", ErrFileParse, count, i, err) - } - } - case "RCU:": - perCPU := parts[1:] - softirqs.RCU = make([]uint64, len(perCPU)) - for i, count := range perCPU { - if softirqs.RCU[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (RCU%d): %w", ErrFileParse, count, i, err) - } - } - } - } - - if err := scanner.Err(); err != nil { - return Softirqs{}, fmt.Errorf("%w: couldn't parse softirqs: %w", ErrFileParse, err) - } - - return softirqs, scanner.Err() -} diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go deleted file mode 100644 index 593ad0f62f05..000000000000 --- a/vendor/github.com/prometheus/procfs/stat.go +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/fs" - "github.com/prometheus/procfs/internal/util" -) - -// CPUStat shows how much time the cpu spend in various stages. -type CPUStat struct { - User float64 - Nice float64 - System float64 - Idle float64 - Iowait float64 - IRQ float64 - SoftIRQ float64 - Steal float64 - Guest float64 - GuestNice float64 -} - -// SoftIRQStat represent the softirq statistics as exported in the procfs stat file. -// A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html -// It is possible to get per-cpu stats by reading `/proc/softirqs`. -type SoftIRQStat struct { - Hi uint64 - Timer uint64 - NetTx uint64 - NetRx uint64 - Block uint64 - BlockIoPoll uint64 - Tasklet uint64 - Sched uint64 - Hrtimer uint64 - Rcu uint64 -} - -// Stat represents kernel/system statistics. -type Stat struct { - // Boot time in seconds since the Epoch. - BootTime uint64 - // Summed up cpu statistics. - CPUTotal CPUStat - // Per-CPU statistics. - CPU map[int64]CPUStat - // Number of times interrupts were handled, which contains numbered and unnumbered IRQs. - IRQTotal uint64 - // Number of times a numbered IRQ was triggered. - IRQ []uint64 - // Number of times a context switch happened. - ContextSwitches uint64 - // Number of times a process was created. - ProcessCreated uint64 - // Number of processes currently running. - ProcessesRunning uint64 - // Number of processes currently blocked (waiting for IO). - ProcessesBlocked uint64 - // Number of times a softirq was scheduled. - SoftIRQTotal uint64 - // Detailed softirq statistics. - SoftIRQ SoftIRQStat -} - -// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum). -func parseCPUStat(line string) (CPUStat, int64, error) { - cpuStat := CPUStat{} - var cpu string - - count, err := fmt.Sscanf(line, "%s %f %f %f %f %f %f %f %f %f %f", - &cpu, - &cpuStat.User, &cpuStat.Nice, &cpuStat.System, &cpuStat.Idle, - &cpuStat.Iowait, &cpuStat.IRQ, &cpuStat.SoftIRQ, &cpuStat.Steal, - &cpuStat.Guest, &cpuStat.GuestNice) - - if err != nil && !errors.Is(err, io.EOF) { - return CPUStat{}, -1, fmt.Errorf("%w: couldn't parse %q (cpu): %w", ErrFileParse, line, err) - } - if count == 0 { - return CPUStat{}, -1, fmt.Errorf("%w: couldn't parse %q (cpu): 0 elements parsed", ErrFileParse, line) - } - - cpuStat.User /= userHZ - cpuStat.Nice /= userHZ - cpuStat.System /= userHZ - cpuStat.Idle /= userHZ - cpuStat.Iowait /= userHZ - cpuStat.IRQ /= userHZ - cpuStat.SoftIRQ /= userHZ - cpuStat.Steal /= userHZ - cpuStat.Guest /= userHZ - cpuStat.GuestNice /= userHZ - - if cpu == "cpu" { - return cpuStat, -1, nil - } - - cpuID, err := strconv.ParseInt(cpu[3:], 10, 64) - if err != nil { - return CPUStat{}, -1, fmt.Errorf("%w: couldn't parse %q (cpu/cpuid): %w", ErrFileParse, line, err) - } - - return cpuStat, cpuID, nil -} - -// Parse a softirq line. -func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) { - softIRQStat := SoftIRQStat{} - var total uint64 - var prefix string - - _, err := fmt.Sscanf(line, "%s %d %d %d %d %d %d %d %d %d %d %d", - &prefix, &total, - &softIRQStat.Hi, &softIRQStat.Timer, &softIRQStat.NetTx, &softIRQStat.NetRx, - &softIRQStat.Block, &softIRQStat.BlockIoPoll, - &softIRQStat.Tasklet, &softIRQStat.Sched, - &softIRQStat.Hrtimer, &softIRQStat.Rcu) - - if err != nil { - return SoftIRQStat{}, 0, fmt.Errorf("%w: couldn't parse %q (softirq): %w", ErrFileParse, line, err) - } - - return softIRQStat, total, nil -} - -// NewStat returns information about current cpu/process statistics. -// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt -// -// Deprecated: Use fs.Stat() instead. -func NewStat() (Stat, error) { - fs, err := NewFS(fs.DefaultProcMountPoint) - if err != nil { - return Stat{}, err - } - return fs.Stat() -} - -// NewStat returns information about current cpu/process statistics. -// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt -// -// Deprecated: Use fs.Stat() instead. -func (fs FS) NewStat() (Stat, error) { - return fs.Stat() -} - -// Stat returns information about current cpu/process statistics. -// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt -func (fs FS) Stat() (Stat, error) { - fileName := fs.proc.Path("stat") - data, err := util.ReadFileNoStat(fileName) - if err != nil { - return Stat{}, err - } - procStat, err := parseStat(bytes.NewReader(data), fileName) - if err != nil { - return Stat{}, err - } - return procStat, nil -} - -// parseStat parses the metrics from /proc/[pid]/stat. -func parseStat(r io.Reader, fileName string) (Stat, error) { - var ( - scanner = bufio.NewScanner(r) - stat = Stat{ - CPU: make(map[int64]CPUStat), - } - err error - ) - - // Increase default scanner buffer to handle very long `intr` lines. - buf := make([]byte, 0, 8*1024) - scanner.Buffer(buf, 1024*1024) - - for scanner.Scan() { - line := scanner.Text() - parts := strings.Fields(scanner.Text()) - // require at least - if len(parts) < 2 { - continue - } - switch { - case parts[0] == "btime": - if stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q (btime): %w", ErrFileParse, parts[1], err) - } - case parts[0] == "intr": - if stat.IRQTotal, err = strconv.ParseUint(parts[1], 10, 64); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q (intr): %w", ErrFileParse, parts[1], err) - } - numberedIRQs := parts[2:] - stat.IRQ = make([]uint64, len(numberedIRQs)) - for i, count := range numberedIRQs { - if stat.IRQ[i], err = strconv.ParseUint(count, 10, 64); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q (intr%d): %w", ErrFileParse, count, i, err) - } - } - case parts[0] == "ctxt": - if stat.ContextSwitches, err = strconv.ParseUint(parts[1], 10, 64); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q (ctxt): %w", ErrFileParse, parts[1], err) - } - case parts[0] == "processes": - if stat.ProcessCreated, err = strconv.ParseUint(parts[1], 10, 64); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q (processes): %w", ErrFileParse, parts[1], err) - } - case parts[0] == "procs_running": - if stat.ProcessesRunning, err = strconv.ParseUint(parts[1], 10, 64); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q (procs_running): %w", ErrFileParse, parts[1], err) - } - case parts[0] == "procs_blocked": - if stat.ProcessesBlocked, err = strconv.ParseUint(parts[1], 10, 64); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q (procs_blocked): %w", ErrFileParse, parts[1], err) - } - case parts[0] == "softirq": - softIRQStats, total, err := parseSoftIRQStat(line) - if err != nil { - return Stat{}, err - } - stat.SoftIRQTotal = total - stat.SoftIRQ = softIRQStats - case strings.HasPrefix(parts[0], "cpu"): - cpuStat, cpuID, err := parseCPUStat(line) - if err != nil { - return Stat{}, err - } - if cpuID == -1 { - stat.CPUTotal = cpuStat - } else { - stat.CPU[cpuID] = cpuStat - } - } - } - - if err := scanner.Err(); err != nil { - return Stat{}, fmt.Errorf("%w: couldn't parse %q: %w", ErrFileParse, fileName, err) - } - - return stat, nil -} diff --git a/vendor/github.com/prometheus/procfs/swaps.go b/vendor/github.com/prometheus/procfs/swaps.go deleted file mode 100644 index ee17bf4888cd..000000000000 --- a/vendor/github.com/prometheus/procfs/swaps.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "bufio" - "bytes" - "fmt" - "strconv" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Swap represents an entry in /proc/swaps. -type Swap struct { - Filename string - Type string - Size int - Used int - Priority int -} - -// Swaps returns a slice of all configured swap devices on the system. -func (fs FS) Swaps() ([]*Swap, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("swaps")) - if err != nil { - return nil, err - } - return parseSwaps(data) -} - -func parseSwaps(info []byte) ([]*Swap, error) { - swaps := []*Swap{} - scanner := bufio.NewScanner(bytes.NewReader(info)) - scanner.Scan() // ignore header line - for scanner.Scan() { - swapString := scanner.Text() - parsedSwap, err := parseSwapString(swapString) - if err != nil { - return nil, err - } - swaps = append(swaps, parsedSwap) - } - - err := scanner.Err() - return swaps, err -} - -func parseSwapString(swapString string) (*Swap, error) { - var err error - - swapFields := strings.Fields(swapString) - swapLength := len(swapFields) - if swapLength < 5 { - return nil, fmt.Errorf("%w: too few fields in swap string: %s", ErrFileParse, swapString) - } - - swap := &Swap{ - Filename: swapFields[0], - Type: swapFields[1], - } - - swap.Size, err = strconv.Atoi(swapFields[2]) - if err != nil { - return nil, fmt.Errorf("%w: invalid swap size: %s: %w", ErrFileParse, swapFields[2], err) - } - swap.Used, err = strconv.Atoi(swapFields[3]) - if err != nil { - return nil, fmt.Errorf("%w: invalid swap used: %s: %w", ErrFileParse, swapFields[3], err) - } - swap.Priority, err = strconv.Atoi(swapFields[4]) - if err != nil { - return nil, fmt.Errorf("%w: invalid swap priority: %s: %w", ErrFileParse, swapFields[4], err) - } - - return swap, nil -} diff --git a/vendor/github.com/prometheus/procfs/thread.go b/vendor/github.com/prometheus/procfs/thread.go deleted file mode 100644 index 0cfbb5418445..000000000000 --- a/vendor/github.com/prometheus/procfs/thread.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package procfs - -import ( - "fmt" - "os" - "strconv" - - fsi "github.com/prometheus/procfs/internal/fs" -) - -// Provide access to /proc/PID/task/TID files, for thread specific values. Since -// such files have the same structure as /proc/PID/ ones, the data structures -// and the parsers for the latter may be reused. - -// AllThreads returns a list of all currently available threads under /proc/PID. -func AllThreads(pid int) (Procs, error) { - fs, err := NewFS(DefaultMountPoint) - if err != nil { - return Procs{}, err - } - return fs.AllThreads(pid) -} - -// AllThreads returns a list of all currently available threads for PID. -func (fs FS) AllThreads(pid int) (Procs, error) { - taskPath := fs.proc.Path(strconv.Itoa(pid), "task") - d, err := os.Open(taskPath) - if err != nil { - return Procs{}, err - } - defer d.Close() - - names, err := d.Readdirnames(-1) - if err != nil { - return Procs{}, fmt.Errorf("%w: could not read %q: %w", ErrFileRead, d.Name(), err) - } - - t := Procs{} - for _, n := range names { - tid, err := strconv.ParseInt(n, 10, 64) - if err != nil { - continue - } - - t = append(t, Proc{PID: int(tid), fs: FS{fsi.FS(taskPath), fs.isReal}}) - } - - return t, nil -} - -// Thread returns a process for a given PID, TID. -func (fs FS) Thread(pid, tid int) (Proc, error) { - taskPath := fs.proc.Path(strconv.Itoa(pid), "task") - if _, err := os.Stat(taskPath); err != nil { - return Proc{}, err - } - return Proc{PID: tid, fs: FS{fsi.FS(taskPath), fs.isReal}}, nil -} - -// Thread returns a process for a given TID of Proc. -func (proc Proc) Thread(tid int) (Proc, error) { - tfs := FS{fsi.FS(proc.path("task")), proc.fs.isReal} - if _, err := os.Stat(tfs.proc.Path(strconv.Itoa(tid))); err != nil { - return Proc{}, err - } - return Proc{PID: tid, fs: tfs}, nil -} diff --git a/vendor/github.com/prometheus/procfs/ttar b/vendor/github.com/prometheus/procfs/ttar deleted file mode 100644 index 19ef02b8d4e1..000000000000 --- a/vendor/github.com/prometheus/procfs/ttar +++ /dev/null @@ -1,413 +0,0 @@ -#!/usr/bin/env bash - -# Purpose: plain text tar format -# Limitations: - only suitable for text files, directories, and symlinks -# - stores only filename, content, and mode -# - not designed for untrusted input -# -# Note: must work with bash version 3.2 (macOS) - -# Copyright 2017 Roger Luethi -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -o nounset - -# Sanitize environment (for instance, standard sorting of glob matches) -export LC_ALL=C - -path="" -CMD="" -ARG_STRING="$*" - -#------------------------------------------------------------------------------ -# Not all sed implementations can work on null bytes. In order to make ttar -# work out of the box on macOS, use Python as a stream editor. - -USE_PYTHON=0 - -PYTHON_CREATE_FILTER=$(cat << 'PCF' -#!/usr/bin/env python - -import re -import sys - -for line in sys.stdin: - line = re.sub(r'EOF', r'\EOF', line) - line = re.sub(r'NULLBYTE', r'\NULLBYTE', line) - line = re.sub('\x00', r'NULLBYTE', line) - sys.stdout.write(line) -PCF -) - -PYTHON_EXTRACT_FILTER=$(cat << 'PEF' -#!/usr/bin/env python - -import re -import sys - -for line in sys.stdin: - line = re.sub(r'(?/dev/null; then - echo "ERROR Python not found. Aborting." - exit 2 - fi - USE_PYTHON=1 - fi -} - -#------------------------------------------------------------------------------ - -function usage { - bname=$(basename "$0") - cat << USAGE -Usage: $bname [-C

] -c -f (create archive) - $bname -t -f (list archive contents) - $bname [-C ] -x -f (extract archive) - -Options: - -C (change directory) - -v (verbose) - --recursive-unlink (recursively delete existing directory if path - collides with file or directory to extract) - -Example: Change to sysfs directory, create ttar file from fixtures directory - $bname -C sysfs -c -f sysfs/fixtures.ttar fixtures/ -USAGE -exit "$1" -} - -function vecho { - if [ "${VERBOSE:-}" == "yes" ]; then - echo >&7 "$@" - fi -} - -function set_cmd { - if [ -n "$CMD" ]; then - echo "ERROR: more than one command given" - echo - usage 2 - fi - CMD=$1 -} - -unset VERBOSE -unset RECURSIVE_UNLINK - -while getopts :cf:-:htxvC: opt; do - case $opt in - c) - set_cmd "create" - ;; - f) - ARCHIVE=$OPTARG - ;; - h) - usage 0 - ;; - t) - set_cmd "list" - ;; - x) - set_cmd "extract" - ;; - v) - VERBOSE=yes - exec 7>&1 - ;; - C) - CDIR=$OPTARG - ;; - -) - case $OPTARG in - recursive-unlink) - RECURSIVE_UNLINK="yes" - ;; - *) - echo -e "Error: invalid option -$OPTARG" - echo - usage 1 - ;; - esac - ;; - *) - echo >&2 "ERROR: invalid option -$OPTARG" - echo - usage 1 - ;; - esac -done - -# Remove processed options from arguments -shift $(( OPTIND - 1 )); - -if [ "${CMD:-}" == "" ]; then - echo >&2 "ERROR: no command given" - echo - usage 1 -elif [ "${ARCHIVE:-}" == "" ]; then - echo >&2 "ERROR: no archive name given" - echo - usage 1 -fi - -function list { - local path="" - local size=0 - local line_no=0 - local ttar_file=$1 - if [ -n "${2:-}" ]; then - echo >&2 "ERROR: too many arguments." - echo - usage 1 - fi - if [ ! -e "$ttar_file" ]; then - echo >&2 "ERROR: file not found ($ttar_file)" - echo - usage 1 - fi - while read -r line; do - line_no=$(( line_no + 1 )) - if [ $size -gt 0 ]; then - size=$(( size - 1 )) - continue - fi - if [[ $line =~ ^Path:\ (.*)$ ]]; then - path=${BASH_REMATCH[1]} - elif [[ $line =~ ^Lines:\ (.*)$ ]]; then - size=${BASH_REMATCH[1]} - echo "$path" - elif [[ $line =~ ^Directory:\ (.*)$ ]]; then - path=${BASH_REMATCH[1]} - echo "$path/" - elif [[ $line =~ ^SymlinkTo:\ (.*)$ ]]; then - echo "$path -> ${BASH_REMATCH[1]}" - fi - done < "$ttar_file" -} - -function extract { - local path="" - local size=0 - local line_no=0 - local ttar_file=$1 - if [ -n "${2:-}" ]; then - echo >&2 "ERROR: too many arguments." - echo - usage 1 - fi - if [ ! -e "$ttar_file" ]; then - echo >&2 "ERROR: file not found ($ttar_file)" - echo - usage 1 - fi - while IFS= read -r line; do - line_no=$(( line_no + 1 )) - local eof_without_newline - if [ "$size" -gt 0 ]; then - if [[ "$line" =~ [^\\]EOF ]]; then - # An EOF not preceded by a backslash indicates that the line - # does not end with a newline - eof_without_newline=1 - else - eof_without_newline=0 - fi - # Replace NULLBYTE with null byte if at beginning of line - # Replace NULLBYTE with null byte unless preceded by backslash - # Remove one backslash in front of NULLBYTE (if any) - # Remove EOF unless preceded by backslash - # Remove one backslash in front of EOF - if [ $USE_PYTHON -eq 1 ]; then - echo -n "$line" | python -c "$PYTHON_EXTRACT_FILTER" >> "$path" - else - # The repeated pattern makes up for sed's lack of negative - # lookbehind assertions (for consecutive null bytes). - echo -n "$line" | \ - sed -e 's/^NULLBYTE/\x0/g; - s/\([^\\]\)NULLBYTE/\1\x0/g; - s/\([^\\]\)NULLBYTE/\1\x0/g; - s/\\NULLBYTE/NULLBYTE/g; - s/\([^\\]\)EOF/\1/g; - s/\\EOF/EOF/g; - ' >> "$path" - fi - if [[ "$eof_without_newline" -eq 0 ]]; then - echo >> "$path" - fi - size=$(( size - 1 )) - continue - fi - if [[ $line =~ ^Path:\ (.*)$ ]]; then - path=${BASH_REMATCH[1]} - if [ -L "$path" ]; then - rm "$path" - elif [ -d "$path" ]; then - if [ "${RECURSIVE_UNLINK:-}" == "yes" ]; then - rm -r "$path" - else - # Safe because symlinks to directories are dealt with above - rmdir "$path" - fi - elif [ -e "$path" ]; then - rm "$path" - fi - elif [[ $line =~ ^Lines:\ (.*)$ ]]; then - size=${BASH_REMATCH[1]} - # Create file even if it is zero-length. - touch "$path" - vecho " $path" - elif [[ $line =~ ^Mode:\ (.*)$ ]]; then - mode=${BASH_REMATCH[1]} - chmod "$mode" "$path" - vecho "$mode" - elif [[ $line =~ ^Directory:\ (.*)$ ]]; then - path=${BASH_REMATCH[1]} - mkdir -p "$path" - vecho " $path/" - elif [[ $line =~ ^SymlinkTo:\ (.*)$ ]]; then - ln -s "${BASH_REMATCH[1]}" "$path" - vecho " $path -> ${BASH_REMATCH[1]}" - elif [[ $line =~ ^# ]]; then - # Ignore comments between files - continue - else - echo >&2 "ERROR: Unknown keyword on line $line_no: $line" - exit 1 - fi - done < "$ttar_file" -} - -function div { - echo "# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" \ - "- - - - - -" -} - -function get_mode { - local mfile=$1 - if [ -z "${STAT_OPTION:-}" ]; then - if stat -c '%a' "$mfile" >/dev/null 2>&1; then - # GNU stat - STAT_OPTION='-c' - STAT_FORMAT='%a' - else - # BSD stat - STAT_OPTION='-f' - # Octal output, user/group/other (omit file type, sticky bit) - STAT_FORMAT='%OLp' - fi - fi - stat "${STAT_OPTION}" "${STAT_FORMAT}" "$mfile" -} - -function _create { - shopt -s nullglob - local mode - local eof_without_newline - while (( "$#" )); do - file=$1 - if [ -L "$file" ]; then - echo "Path: $file" - symlinkTo=$(readlink "$file") - echo "SymlinkTo: $symlinkTo" - vecho " $file -> $symlinkTo" - div - elif [ -d "$file" ]; then - # Strip trailing slash (if there is one) - file=${file%/} - echo "Directory: $file" - mode=$(get_mode "$file") - echo "Mode: $mode" - vecho "$mode $file/" - div - # Find all files and dirs, including hidden/dot files - for x in "$file/"{*,.[^.]*}; do - _create "$x" - done - elif [ -f "$file" ]; then - echo "Path: $file" - lines=$(wc -l "$file"|awk '{print $1}') - eof_without_newline=0 - if [[ "$(wc -c "$file"|awk '{print $1}')" -gt 0 ]] && \ - [[ "$(tail -c 1 "$file" | wc -l)" -eq 0 ]]; then - eof_without_newline=1 - lines=$((lines+1)) - fi - echo "Lines: $lines" - # Add backslash in front of EOF - # Add backslash in front of NULLBYTE - # Replace null byte with NULLBYTE - if [ $USE_PYTHON -eq 1 ]; then - < "$file" python -c "$PYTHON_CREATE_FILTER" - else - < "$file" \ - sed 's/EOF/\\EOF/g; - s/NULLBYTE/\\NULLBYTE/g; - s/\x0/NULLBYTE/g; - ' - fi - if [[ "$eof_without_newline" -eq 1 ]]; then - # Finish line with EOF to indicate that the original line did - # not end with a linefeed - echo "EOF" - fi - mode=$(get_mode "$file") - echo "Mode: $mode" - vecho "$mode $file" - div - else - echo >&2 "ERROR: file not found ($file in $(pwd))" - exit 2 - fi - shift - done -} - -function create { - ttar_file=$1 - shift - if [ -z "${1:-}" ]; then - echo >&2 "ERROR: missing arguments." - echo - usage 1 - fi - if [ -e "$ttar_file" ]; then - rm "$ttar_file" - fi - exec > "$ttar_file" - echo "# Archive created by ttar $ARG_STRING" - _create "$@" -} - -test_environment - -if [ -n "${CDIR:-}" ]; then - if [[ "$ARCHIVE" != /* ]]; then - # Relative path: preserve the archive's location before changing - # directory - ARCHIVE="$(pwd)/$ARCHIVE" - fi - cd "$CDIR" -fi - -"$CMD" "$ARCHIVE" "$@" diff --git a/vendor/github.com/prometheus/procfs/vm.go b/vendor/github.com/prometheus/procfs/vm.go deleted file mode 100644 index 52180c03e260..000000000000 --- a/vendor/github.com/prometheus/procfs/vm.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows - -package procfs - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// The VM interface is described at -// -// https://www.kernel.org/doc/Documentation/sysctl/vm.txt -// -// Each setting is exposed as a single file. -// Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array -// and numa_zonelist_order (deprecated) which is a string. -type VM struct { - AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes - BlockDump *int64 // /proc/sys/vm/block_dump - CompactUnevictableAllowed *int64 // /proc/sys/vm/compact_unevictable_allowed - DirtyBackgroundBytes *int64 // /proc/sys/vm/dirty_background_bytes - DirtyBackgroundRatio *int64 // /proc/sys/vm/dirty_background_ratio - DirtyBytes *int64 // /proc/sys/vm/dirty_bytes - DirtyExpireCentisecs *int64 // /proc/sys/vm/dirty_expire_centisecs - DirtyRatio *int64 // /proc/sys/vm/dirty_ratio - DirtytimeExpireSeconds *int64 // /proc/sys/vm/dirtytime_expire_seconds - DirtyWritebackCentisecs *int64 // /proc/sys/vm/dirty_writeback_centisecs - DropCaches *int64 // /proc/sys/vm/drop_caches - ExtfragThreshold *int64 // /proc/sys/vm/extfrag_threshold - HugetlbShmGroup *int64 // /proc/sys/vm/hugetlb_shm_group - LaptopMode *int64 // /proc/sys/vm/laptop_mode - LegacyVaLayout *int64 // /proc/sys/vm/legacy_va_layout - LowmemReserveRatio []*int64 // /proc/sys/vm/lowmem_reserve_ratio - MaxMapCount *int64 // /proc/sys/vm/max_map_count - MemoryFailureEarlyKill *int64 // /proc/sys/vm/memory_failure_early_kill - MemoryFailureRecovery *int64 // /proc/sys/vm/memory_failure_recovery - MinFreeKbytes *int64 // /proc/sys/vm/min_free_kbytes - MinSlabRatio *int64 // /proc/sys/vm/min_slab_ratio - MinUnmappedRatio *int64 // /proc/sys/vm/min_unmapped_ratio - MmapMinAddr *int64 // /proc/sys/vm/mmap_min_addr - NrHugepages *int64 // /proc/sys/vm/nr_hugepages - NrHugepagesMempolicy *int64 // /proc/sys/vm/nr_hugepages_mempolicy - NrOvercommitHugepages *int64 // /proc/sys/vm/nr_overcommit_hugepages - NumaStat *int64 // /proc/sys/vm/numa_stat - NumaZonelistOrder string // /proc/sys/vm/numa_zonelist_order - OomDumpTasks *int64 // /proc/sys/vm/oom_dump_tasks - OomKillAllocatingTask *int64 // /proc/sys/vm/oom_kill_allocating_task - OvercommitKbytes *int64 // /proc/sys/vm/overcommit_kbytes - OvercommitMemory *int64 // /proc/sys/vm/overcommit_memory - OvercommitRatio *int64 // /proc/sys/vm/overcommit_ratio - PageCluster *int64 // /proc/sys/vm/page-cluster - PanicOnOom *int64 // /proc/sys/vm/panic_on_oom - PercpuPagelistFraction *int64 // /proc/sys/vm/percpu_pagelist_fraction - StatInterval *int64 // /proc/sys/vm/stat_interval - Swappiness *int64 // /proc/sys/vm/swappiness - UserReserveKbytes *int64 // /proc/sys/vm/user_reserve_kbytes - VfsCachePressure *int64 // /proc/sys/vm/vfs_cache_pressure - WatermarkBoostFactor *int64 // /proc/sys/vm/watermark_boost_factor - WatermarkScaleFactor *int64 // /proc/sys/vm/watermark_scale_factor - ZoneReclaimMode *int64 // /proc/sys/vm/zone_reclaim_mode -} - -// VM reads the VM statistics from the specified `proc` filesystem. -func (fs FS) VM() (*VM, error) { - path := fs.proc.Path("sys/vm") - file, err := os.Stat(path) - if err != nil { - return nil, err - } - if !file.Mode().IsDir() { - return nil, fmt.Errorf("%w: %s is not a directory", ErrFileRead, path) - } - - files, err := os.ReadDir(path) - if err != nil { - return nil, err - } - - var vm VM - for _, f := range files { - if f.IsDir() { - continue - } - - name := filepath.Join(path, f.Name()) - // ignore errors on read, as there are some write only - // in /proc/sys/vm - value, err := util.SysReadFile(name) - if err != nil { - continue - } - vp := util.NewValueParser(value) - - switch f.Name() { - case "admin_reserve_kbytes": - vm.AdminReserveKbytes = vp.PInt64() - case "block_dump": - vm.BlockDump = vp.PInt64() - case "compact_unevictable_allowed": - vm.CompactUnevictableAllowed = vp.PInt64() - case "dirty_background_bytes": - vm.DirtyBackgroundBytes = vp.PInt64() - case "dirty_background_ratio": - vm.DirtyBackgroundRatio = vp.PInt64() - case "dirty_bytes": - vm.DirtyBytes = vp.PInt64() - case "dirty_expire_centisecs": - vm.DirtyExpireCentisecs = vp.PInt64() - case "dirty_ratio": - vm.DirtyRatio = vp.PInt64() - case "dirtytime_expire_seconds": - vm.DirtytimeExpireSeconds = vp.PInt64() - case "dirty_writeback_centisecs": - vm.DirtyWritebackCentisecs = vp.PInt64() - case "drop_caches": - vm.DropCaches = vp.PInt64() - case "extfrag_threshold": - vm.ExtfragThreshold = vp.PInt64() - case "hugetlb_shm_group": - vm.HugetlbShmGroup = vp.PInt64() - case "laptop_mode": - vm.LaptopMode = vp.PInt64() - case "legacy_va_layout": - vm.LegacyVaLayout = vp.PInt64() - case "lowmem_reserve_ratio": - stringSlice := strings.Fields(value) - pint64Slice := make([]*int64, 0, len(stringSlice)) - for _, value := range stringSlice { - vp := util.NewValueParser(value) - pint64Slice = append(pint64Slice, vp.PInt64()) - } - vm.LowmemReserveRatio = pint64Slice - case "max_map_count": - vm.MaxMapCount = vp.PInt64() - case "memory_failure_early_kill": - vm.MemoryFailureEarlyKill = vp.PInt64() - case "memory_failure_recovery": - vm.MemoryFailureRecovery = vp.PInt64() - case "min_free_kbytes": - vm.MinFreeKbytes = vp.PInt64() - case "min_slab_ratio": - vm.MinSlabRatio = vp.PInt64() - case "min_unmapped_ratio": - vm.MinUnmappedRatio = vp.PInt64() - case "mmap_min_addr": - vm.MmapMinAddr = vp.PInt64() - case "nr_hugepages": - vm.NrHugepages = vp.PInt64() - case "nr_hugepages_mempolicy": - vm.NrHugepagesMempolicy = vp.PInt64() - case "nr_overcommit_hugepages": - vm.NrOvercommitHugepages = vp.PInt64() - case "numa_stat": - vm.NumaStat = vp.PInt64() - case "numa_zonelist_order": - vm.NumaZonelistOrder = value - case "oom_dump_tasks": - vm.OomDumpTasks = vp.PInt64() - case "oom_kill_allocating_task": - vm.OomKillAllocatingTask = vp.PInt64() - case "overcommit_kbytes": - vm.OvercommitKbytes = vp.PInt64() - case "overcommit_memory": - vm.OvercommitMemory = vp.PInt64() - case "overcommit_ratio": - vm.OvercommitRatio = vp.PInt64() - case "page-cluster": - vm.PageCluster = vp.PInt64() - case "panic_on_oom": - vm.PanicOnOom = vp.PInt64() - case "percpu_pagelist_fraction": - vm.PercpuPagelistFraction = vp.PInt64() - case "stat_interval": - vm.StatInterval = vp.PInt64() - case "swappiness": - vm.Swappiness = vp.PInt64() - case "user_reserve_kbytes": - vm.UserReserveKbytes = vp.PInt64() - case "vfs_cache_pressure": - vm.VfsCachePressure = vp.PInt64() - case "watermark_boost_factor": - vm.WatermarkBoostFactor = vp.PInt64() - case "watermark_scale_factor": - vm.WatermarkScaleFactor = vp.PInt64() - case "zone_reclaim_mode": - vm.ZoneReclaimMode = vp.PInt64() - } - if err := vp.Err(); err != nil { - return nil, err - } - } - - return &vm, nil -} diff --git a/vendor/github.com/prometheus/procfs/zoneinfo.go b/vendor/github.com/prometheus/procfs/zoneinfo.go deleted file mode 100644 index 63d1898bc830..000000000000 --- a/vendor/github.com/prometheus/procfs/zoneinfo.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows - -package procfs - -import ( - "bytes" - "fmt" - "os" - "regexp" - "strings" - - "github.com/prometheus/procfs/internal/util" -) - -// Zoneinfo holds info parsed from /proc/zoneinfo. -type Zoneinfo struct { - Node string - Zone string - NrFreePages *int64 - Min *int64 - Low *int64 - High *int64 - Scanned *int64 - Spanned *int64 - Present *int64 - Managed *int64 - NrActiveAnon *int64 - NrInactiveAnon *int64 - NrIsolatedAnon *int64 - NrAnonPages *int64 - NrAnonTransparentHugepages *int64 - NrActiveFile *int64 - NrInactiveFile *int64 - NrIsolatedFile *int64 - NrFilePages *int64 - NrSlabReclaimable *int64 - NrSlabUnreclaimable *int64 - NrMlockStack *int64 - NrKernelStack *int64 - NrMapped *int64 - NrDirty *int64 - NrWriteback *int64 - NrUnevictable *int64 - NrShmem *int64 - NrDirtied *int64 - NrWritten *int64 - NumaHit *int64 - NumaMiss *int64 - NumaForeign *int64 - NumaInterleave *int64 - NumaLocal *int64 - NumaOther *int64 - Protection []*int64 -} - -var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`) - -// Zoneinfo parses an zoneinfo-file (/proc/zoneinfo) and returns a slice of -// structs containing the relevant info. More information available here: -// https://www.kernel.org/doc/Documentation/sysctl/vm.txt -func (fs FS) Zoneinfo() ([]Zoneinfo, error) { - data, err := os.ReadFile(fs.proc.Path("zoneinfo")) - if err != nil { - return nil, fmt.Errorf("%w: error reading zoneinfo %q: %w", ErrFileRead, fs.proc.Path("zoneinfo"), err) - } - zoneinfo, err := parseZoneinfo(data) - if err != nil { - return nil, fmt.Errorf("%w: error parsing zoneinfo %q: %w", ErrFileParse, fs.proc.Path("zoneinfo"), err) - } - return zoneinfo, nil -} - -func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) { - - zoneinfo := []Zoneinfo{} - - for block := range bytes.SplitSeq(zoneinfoData, []byte("\nNode")) { - var zoneinfoElement Zoneinfo - for line := range strings.SplitSeq(string(block), "\n") { - - if nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil { - zoneinfoElement.Node = nodeZone[1] - zoneinfoElement.Zone = nodeZone[2] - continue - } - if strings.HasPrefix(strings.TrimSpace(line), "per-node stats") { - continue - } - parts := strings.Fields(strings.TrimSpace(line)) - if len(parts) < 2 { - continue - } - vp := util.NewValueParser(parts[1]) - switch parts[0] { - case "nr_free_pages": - zoneinfoElement.NrFreePages = vp.PInt64() - case "min": - zoneinfoElement.Min = vp.PInt64() - case "low": - zoneinfoElement.Low = vp.PInt64() - case "high": - zoneinfoElement.High = vp.PInt64() - case "scanned": - zoneinfoElement.Scanned = vp.PInt64() - case "spanned": - zoneinfoElement.Spanned = vp.PInt64() - case "present": - zoneinfoElement.Present = vp.PInt64() - case "managed": - zoneinfoElement.Managed = vp.PInt64() - case "nr_active_anon": - zoneinfoElement.NrActiveAnon = vp.PInt64() - case "nr_inactive_anon": - zoneinfoElement.NrInactiveAnon = vp.PInt64() - case "nr_isolated_anon": - zoneinfoElement.NrIsolatedAnon = vp.PInt64() - case "nr_anon_pages": - zoneinfoElement.NrAnonPages = vp.PInt64() - case "nr_anon_transparent_hugepages": - zoneinfoElement.NrAnonTransparentHugepages = vp.PInt64() - case "nr_active_file": - zoneinfoElement.NrActiveFile = vp.PInt64() - case "nr_inactive_file": - zoneinfoElement.NrInactiveFile = vp.PInt64() - case "nr_isolated_file": - zoneinfoElement.NrIsolatedFile = vp.PInt64() - case "nr_file_pages": - zoneinfoElement.NrFilePages = vp.PInt64() - case "nr_slab_reclaimable": - zoneinfoElement.NrSlabReclaimable = vp.PInt64() - case "nr_slab_unreclaimable": - zoneinfoElement.NrSlabUnreclaimable = vp.PInt64() - case "nr_mlock_stack": - zoneinfoElement.NrMlockStack = vp.PInt64() - case "nr_kernel_stack": - zoneinfoElement.NrKernelStack = vp.PInt64() - case "nr_mapped": - zoneinfoElement.NrMapped = vp.PInt64() - case "nr_dirty": - zoneinfoElement.NrDirty = vp.PInt64() - case "nr_writeback": - zoneinfoElement.NrWriteback = vp.PInt64() - case "nr_unevictable": - zoneinfoElement.NrUnevictable = vp.PInt64() - case "nr_shmem": - zoneinfoElement.NrShmem = vp.PInt64() - case "nr_dirtied": - zoneinfoElement.NrDirtied = vp.PInt64() - case "nr_written": - zoneinfoElement.NrWritten = vp.PInt64() - case "numa_hit": - zoneinfoElement.NumaHit = vp.PInt64() - case "numa_miss": - zoneinfoElement.NumaMiss = vp.PInt64() - case "numa_foreign": - zoneinfoElement.NumaForeign = vp.PInt64() - case "numa_interleave": - zoneinfoElement.NumaInterleave = vp.PInt64() - case "numa_local": - zoneinfoElement.NumaLocal = vp.PInt64() - case "numa_other": - zoneinfoElement.NumaOther = vp.PInt64() - case "protection:": - protectionParts := strings.Split(line, ":") - protectionValues := strings.Replace(protectionParts[1], "(", "", 1) - protectionValues = strings.Replace(protectionValues, ")", "", 1) - protectionValues = strings.TrimSpace(protectionValues) - protectionStringMap := strings.Split(protectionValues, ", ") - val, err := util.ParsePInt64s(protectionStringMap) - if err == nil { - zoneinfoElement.Protection = val - } - } - - } - - zoneinfo = append(zoneinfo, zoneinfoElement) - } - return zoneinfo, nil -} diff --git a/vendor/github.com/segmentio/asm/LICENSE b/vendor/github.com/segmentio/asm/LICENSE index 29e1ab6b05fc..5e93dab62120 100644 --- a/vendor/github.com/segmentio/asm/LICENSE +++ b/vendor/github.com/segmentio/asm/LICENSE @@ -1,21 +1,16 @@ -MIT License +MIT No Attribution -Copyright (c) 2021 Segment +Copyright 2023 Segment -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/segmentio/asm/base64/decode_arm64.s b/vendor/github.com/segmentio/asm/base64/decode_arm64.s index 4374d5ce171a..67d206f8cc79 100644 --- a/vendor/github.com/segmentio/asm/base64/decode_arm64.s +++ b/vendor/github.com/segmentio/asm/base64/decode_arm64.s @@ -130,7 +130,12 @@ loop: ADVANCE_LOOP(loop) // Store results and continue done: - RETURN() + // RETURN() replacing the macro to please go vet. + SUB R0, R3; + SUB R1, R4; + MOVD R3, ret+56(FP); + MOVD R4, ret1+64(FP); + RET // func decodeStdARM64(dst []byte, src []byte, lut *int8) (int, int) @@ -145,7 +150,12 @@ loop: ADVANCE_LOOP(loop) // Store results and continue done: - RETURN() + // RETURN() replacing the macro to please go vet. + SUB R0, R3; + SUB R1, R4; + MOVD R3, ret+56(FP); + MOVD R4, ret1+64(FP); + RET DATA ·mask_lut+0x00(SB)/1, $0xa8 diff --git a/vendor/github.com/valyala/fastjson/arena.go b/vendor/github.com/valyala/fastjson/arena.go index 9fe21a48c8c6..1a512d5f35ac 100644 --- a/vendor/github.com/valyala/fastjson/arena.go +++ b/vendor/github.com/valyala/fastjson/arena.go @@ -8,10 +8,10 @@ import ( // // Typical Arena lifecycle: // -// 1) Construct Values via the Arena and Value.Set* calls. -// 2) Marshal the constructed Values with Value.MarshalTo call. -// 3) Reset all the constructed Values at once by Arena.Reset call. -// 4) Go to 1 and re-use the Arena. +// 1. Construct Values via the Arena and Value.Set* calls. +// 2. Marshal the constructed Values with Value.MarshalTo call. +// 3. Reset all the constructed Values at once by Arena.Reset call. +// 4. Go to 1 and re-use the Arena. // // It is unsafe calling Arena methods from concurrent goroutines. // Use per-goroutine Arenas or ArenaPool instead. diff --git a/vendor/github.com/valyala/fastjson/doc.go b/vendor/github.com/valyala/fastjson/doc.go index 8076189cfe91..3dbff364d157 100644 --- a/vendor/github.com/valyala/fastjson/doc.go +++ b/vendor/github.com/valyala/fastjson/doc.go @@ -4,6 +4,5 @@ Package fastjson provides fast JSON parsing. Arbitrary JSON may be parsed by fastjson without the need for creating structs or for generating go code. Just parse JSON and get the required fields with Get* functions. - */ package fastjson diff --git a/vendor/github.com/valyala/fastjson/fuzz.go b/vendor/github.com/valyala/fastjson/fuzz.go index 9130797c700f..d9da1f1abc97 100644 --- a/vendor/github.com/valyala/fastjson/fuzz.go +++ b/vendor/github.com/valyala/fastjson/fuzz.go @@ -1,3 +1,4 @@ +//go:build gofuzz // +build gofuzz package fastjson diff --git a/vendor/github.com/valyala/fastjson/pool.go b/vendor/github.com/valyala/fastjson/pool.go index 00cfb42fa623..3f40fb4e210e 100644 --- a/vendor/github.com/valyala/fastjson/pool.go +++ b/vendor/github.com/valyala/fastjson/pool.go @@ -48,5 +48,6 @@ func (ap *ArenaPool) Get() *Arena { // // a and objects created by a cannot be used after a is put into ap. func (ap *ArenaPool) Put(a *Arena) { + a.Reset() ap.pool.Put(a) } diff --git a/vendor/github.com/valyala/fastjson/update.go b/vendor/github.com/valyala/fastjson/update.go index f8099bdbb917..795b7fbd6ddf 100644 --- a/vendor/github.com/valyala/fastjson/update.go +++ b/vendor/github.com/valyala/fastjson/update.go @@ -106,5 +106,8 @@ func (v *Value) SetArrayItem(idx int, value *Value) { for idx >= len(v.a) { v.a = append(v.a, valueNull) } + if value == nil { + value = valueNull + } v.a[idx] = value } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/argmap.go b/vendor/github.com/vektah/gqlparser/v2/ast/argmap.go index 43f6a3d6fc6f..1b65c276935f 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/argmap.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/argmap.go @@ -1,11 +1,15 @@ package ast -func arg2map(defs ArgumentDefinitionList, args ArgumentList, vars map[string]interface{}) map[string]interface{} { - result := map[string]interface{}{} +func arg2map( + defs ArgumentDefinitionList, + args ArgumentList, + vars map[string]any, +) map[string]any { + result := map[string]any{} var err error for _, argDef := range defs { - var val interface{} + var val any var hasValue bool if argValue := args.ForName(argDef.Name); argValue != nil { diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/definition.go b/vendor/github.com/vektah/gqlparser/v2/ast/definition.go index 9ceebf1beee6..426db7588c9d 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/definition.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/definition.go @@ -1,5 +1,7 @@ package ast +import "slices" + type DefinitionKind string const ( @@ -54,12 +56,7 @@ func (d *Definition) IsInputType() bool { } func (d *Definition) OneOf(types ...string) bool { - for _, t := range types { - if d.Name == t { - return true - } - } - return false + return slices.Contains(types, d.Name) } type FieldDefinition struct { diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/directive.go b/vendor/github.com/vektah/gqlparser/v2/ast/directive.go index b11867c2e4bc..de8d984028b6 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/directive.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/directive.go @@ -3,7 +3,7 @@ package ast type DirectiveLocation string const ( - // Executable + // Executable. LocationQuery DirectiveLocation = `QUERY` LocationMutation DirectiveLocation = `MUTATION` LocationSubscription DirectiveLocation = `SUBSCRIPTION` @@ -12,7 +12,7 @@ const ( LocationFragmentSpread DirectiveLocation = `FRAGMENT_SPREAD` LocationInlineFragment DirectiveLocation = `INLINE_FRAGMENT` - // Type System + // Type System. LocationSchema DirectiveLocation = `SCHEMA` LocationScalar DirectiveLocation = `SCALAR` LocationObject DirectiveLocation = `OBJECT` @@ -38,6 +38,9 @@ type Directive struct { Location DirectiveLocation } -func (d *Directive) ArgumentMap(vars map[string]interface{}) map[string]interface{} { +func (d *Directive) ArgumentMap(vars map[string]any) map[string]any { + if d.Definition == nil { + return nil + } return arg2map(d.Definition.Arguments, d.Arguments, vars) } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/document.go b/vendor/github.com/vektah/gqlparser/v2/ast/document.go index e2520ffb7c95..66d55b43b432 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/document.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/document.go @@ -42,7 +42,7 @@ type Schema struct { Comment *CommentGroup } -// AddTypes is the helper to add types definition to the schema +// AddTypes is the helper to add types definition to the schema. func (s *Schema) AddTypes(defs ...*Definition) { if s.Types == nil { s.Types = make(map[string]*Definition) @@ -56,7 +56,7 @@ func (s *Schema) AddPossibleType(name string, def *Definition) { s.PossibleTypes[name] = append(s.PossibleTypes[name], def) } -// GetPossibleTypes will enumerate all the definitions for a given interface or union +// GetPossibleTypes will enumerate all the definitions for a given interface or union. func (s *Schema) GetPossibleTypes(def *Definition) []*Definition { return s.PossibleTypes[def.Name] } @@ -65,7 +65,8 @@ func (s *Schema) AddImplements(name string, iface *Definition) { s.Implements[name] = append(s.Implements[name], iface) } -// GetImplements returns all the interface and union definitions that the given definition satisfies +// GetImplements returns all the interface and union definitions that the given definition +// satisfies. func (s *Schema) GetImplements(def *Definition) []*Definition { return s.Implements[def.Name] } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/dumper.go b/vendor/github.com/vektah/gqlparser/v2/ast/dumper.go index e9ea88a12a5a..26cf693d9c65 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/dumper.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/dumper.go @@ -8,8 +8,8 @@ import ( "strings" ) -// Dump turns ast into a stable string format for assertions in tests -func Dump(i interface{}) string { +// Dump turns ast into a stable string format for assertions in tests. +func Dump(i any) string { v := reflect.ValueOf(i) d := dumper{Buffer: &bytes.Buffer{}} @@ -126,7 +126,6 @@ func isZero(v reflect.Value) bool { return v.IsNil() case reflect.Func, reflect.Map: return v.IsNil() - case reflect.Array, reflect.Slice: if v.IsNil() { return true @@ -144,10 +143,13 @@ func isZero(v reflect.Value) bool { return z case reflect.String: return v.String() == "" + case reflect.Bool: + // Never consider Bool field as zero value. + // Always include them in AST dump. + return false + default: + return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) } - - // Compare other types directly: - return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type())) } func (d *dumper) dumpPtr(v reflect.Value) { diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/path.go b/vendor/github.com/vektah/gqlparser/v2/ast/path.go index f40aa953ddd6..63f53a67a2d1 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/path.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/path.go @@ -27,7 +27,7 @@ func (path Path) String() string { for i, v := range path { switch v := v.(type) { case PathIndex: - str.WriteString(fmt.Sprintf("[%d]", v)) + fmt.Fprintf(&str, "[%d]", v) case PathName: if i != 0 { str.WriteByte('.') @@ -41,7 +41,7 @@ func (path Path) String() string { } func (path *Path) UnmarshalJSON(b []byte) error { - var vs []interface{} + var vs []any err := json.Unmarshal(b, &vs) if err != nil { return err diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/selection.go b/vendor/github.com/vektah/gqlparser/v2/ast/selection.go index 1858dc213621..b6e6890d2229 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/selection.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/selection.go @@ -36,6 +36,9 @@ type Argument struct { Comment *CommentGroup } -func (f *Field) ArgumentMap(vars map[string]interface{}) map[string]interface{} { +func (f *Field) ArgumentMap(vars map[string]any) map[string]any { + if f.Definition == nil { + return nil + } return arg2map(f.Definition.Arguments, f.Arguments, vars) } diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/source.go b/vendor/github.com/vektah/gqlparser/v2/ast/source.go index 2949f83f7bba..213a63a3c5d2 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/source.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/source.go @@ -1,6 +1,6 @@ package ast -// Source covers a single *.graphql file +// Source covers a single *.graphql file. type Source struct { // Name is the filename of the source Name string diff --git a/vendor/github.com/vektah/gqlparser/v2/ast/value.go b/vendor/github.com/vektah/gqlparser/v2/ast/value.go index 45fa8016b5ea..83b471633d08 100644 --- a/vendor/github.com/vektah/gqlparser/v2/ast/value.go +++ b/vendor/github.com/vektah/gqlparser/v2/ast/value.go @@ -29,9 +29,10 @@ type Value struct { Comment *CommentGroup // Require validation - Definition *Definition - VariableDefinition *VariableDefinition - ExpectedType *Type + Definition *Definition + VariableDefinition *VariableDefinition + ExpectedType *Type + ExpectedTypeHasDefault bool } type ChildValue struct { @@ -41,7 +42,7 @@ type ChildValue struct { Comment *CommentGroup } -func (v *Value) Value(vars map[string]interface{}) (interface{}, error) { +func (v *Value) Value(vars map[string]any) (any, error) { if v == nil { return nil, nil } @@ -65,7 +66,7 @@ func (v *Value) Value(vars map[string]interface{}) (interface{}, error) { case NullValue: return nil, nil case ListValue: - var val []interface{} + var val []any for _, elem := range v.Children { elemVal, err := elem.Value.Value(vars) if err != nil { @@ -75,7 +76,7 @@ func (v *Value) Value(vars map[string]interface{}) (interface{}, error) { } return val, nil case ObjectValue: - val := map[string]interface{}{} + val := map[string]any{} for _, elem := range v.Children { elemVal, err := elem.Value.Value(vars) if err != nil { diff --git a/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go b/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go index d9f202887155..b2ba01bbe5d0 100644 --- a/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go +++ b/vendor/github.com/vektah/gqlparser/v2/gqlerror/error.go @@ -11,12 +11,12 @@ import ( // Error is the standard graphql error type described in https://spec.graphql.org/draft/#sec-Errors type Error struct { - Err error `json:"-"` - Message string `json:"message"` - Path ast.Path `json:"path,omitempty"` - Locations []Location `json:"locations,omitempty"` - Extensions map[string]interface{} `json:"extensions,omitempty"` - Rule string `json:"-"` + Err error `json:"-"` + Message string `json:"message"` + Path ast.Path `json:"path,omitempty"` + Locations []Location `json:"locations,omitempty"` + Extensions map[string]any `json:"extensions,omitempty"` + Rule string `json:"-"` } func (err *Error) SetFile(file string) { @@ -24,7 +24,7 @@ func (err *Error) SetFile(file string) { return } if err.Extensions == nil { - err.Extensions = map[string]interface{}{} + err.Extensions = map[string]any{} } err.Extensions["file"] = file @@ -99,7 +99,7 @@ func (errs List) Is(target error) bool { return false } -func (errs List) As(target interface{}) bool { +func (errs List) As(target any) bool { for _, err := range errs { if errors.As(err, target) { return true @@ -141,7 +141,8 @@ func WrapIfUnwrapped(err error) *Error { if err == nil { return nil } - if gqlErr, ok := err.(*Error); ok { + gqlErr := &Error{} + if errors.As(err, &gqlErr) { return gqlErr } return &Error{ @@ -150,20 +151,20 @@ func WrapIfUnwrapped(err error) *Error { } } -func Errorf(message string, args ...interface{}) *Error { +func Errorf(message string, args ...any) *Error { return &Error{ Message: fmt.Sprintf(message, args...), } } -func ErrorPathf(path ast.Path, message string, args ...interface{}) *Error { +func ErrorPathf(path ast.Path, message string, args ...any) *Error { return &Error{ Message: fmt.Sprintf(message, args...), Path: path, } } -func ErrorPosf(pos *ast.Position, message string, args ...interface{}) *Error { +func ErrorPosf(pos *ast.Position, message string, args ...any) *Error { if pos == nil { return ErrorLocf( "", @@ -182,10 +183,10 @@ func ErrorPosf(pos *ast.Position, message string, args ...interface{}) *Error { ) } -func ErrorLocf(file string, line int, col int, message string, args ...interface{}) *Error { - var extensions map[string]interface{} +func ErrorLocf(file string, line, col int, message string, args ...any) *Error { + var extensions map[string]any if file != "" { - extensions = map[string]interface{}{"file": file} + extensions = map[string]any{"file": file} } return &Error{ Message: fmt.Sprintf(message, args...), diff --git a/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go b/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go index 1cbb4a03085a..7a82a42b33a8 100644 --- a/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go +++ b/vendor/github.com/vektah/gqlparser/v2/lexer/lexer.go @@ -2,13 +2,14 @@ package lexer import ( "bytes" + "slices" "unicode/utf8" "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" ) -// Lexer turns graphql request and schema strings into tokens +// Lexer turns graphql request and schema strings into tokens. type Lexer struct { *ast.Source // An offset into the string in bytes @@ -32,7 +33,7 @@ func New(src *ast.Source) Lexer { } } -// take one rune from input and advance end +// take one rune from input and advance end. func (s *Lexer) peek() (rune, int) { return utf8.DecodeRuneInString(s.Input[s.end:]) } @@ -55,7 +56,7 @@ func (s *Lexer) makeValueToken(kind Type, value string) (Token, error) { }, nil } -func (s *Lexer) makeError(format string, args ...interface{}) (Token, *gqlerror.Error) { +func (s *Lexer) makeError(format string, args ...any) (Token, *gqlerror.Error) { column := s.endRunes - s.lineStartRunes + 1 return Token{ Kind: Invalid, @@ -122,7 +123,59 @@ func (s *Lexer) ReadToken() (Token, error) { case '#': return s.readComment() - case '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': + case '_', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z': return s.readName() case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': @@ -144,14 +197,16 @@ func (s *Lexer) ReadToken() (Token, error) { } if r == '\'' { - return s.makeError(`Unexpected single quote character ('), did you mean to use a double quote (")?`) + return s.makeError( + `Unexpected single quote character ('), did you mean to use a double quote (")?`, + ) } return s.makeError(`Cannot parse the unexpected character "%s".`, string(r)) } // ws reads from body starting at startPosition until it finds a non-whitespace -// or commented character, and updates the token end to include all whitespace +// or commented character, and updates the token end to include all whitespace. func (s *Lexer) ws() { for s.end < len(s.Input) { switch s.Input[s.end] { @@ -189,7 +244,7 @@ func (s *Lexer) ws() { // readComment from the input // -// #[\u0009\u0020-\uFFFF]* +// #[\u0009\u0020-\uFFFF]*. func (s *Lexer) readComment() (Token, error) { for s.end < len(s.Input) { r, w := s.peek() @@ -256,23 +311,21 @@ func (s *Lexer) readNumber() (Token, error) { return s.makeToken(Int) } -// acceptByte if it matches any of given bytes, returning true if it found anything +// acceptByte if it matches any of given bytes, returning true if it found anything. func (s *Lexer) acceptByte(bytes ...uint8) bool { if s.end >= len(s.Input) { return false } - for _, accepted := range bytes { - if s.Input[s.end] == accepted { - s.end++ - s.endRunes++ - return true - } + if slices.Contains(bytes, s.Input[s.end]) { + s.end++ + s.endRunes++ + return true } return false } -// acceptDigits from the input, returning the number of digits it found +// acceptDigits from the input, returning the number of digits it found. func (s *Lexer) acceptDigits() int { consumed := 0 for s.end < len(s.Input) && s.Input[s.end] >= '0' && s.Input[s.end] <= '9' { @@ -285,7 +338,7 @@ func (s *Lexer) acceptDigits() int { } // describeNext peeks at the input and returns a human readable string. This should will alloc -// and should only be used in errors +// and should only be used in errors. func (s *Lexer) describeNext() string { if s.end < len(s.Input) { return `"` + string(s.Input[s.end]) + `"` @@ -295,7 +348,7 @@ func (s *Lexer) describeNext() string { // readString from the input // -// "([^"\\\u000A\u000D]|(\\(u[0-9a-fA-F]{4}|["\\/bfnrt])))*" +// "([^"\\\u000A\u000D]|(\\(u[0-9a-fA-F]{4}|["\\/bfnrt])))*". func (s *Lexer) readString() (Token, error) { inputLen := len(s.Input) @@ -332,7 +385,8 @@ func (s *Lexer) readString() (Token, error) { case '"': t, err := s.makeToken(String) - // the token should not include the quotes in its value, but should cover them in its position + // the token should not include the quotes in its value, but should cover them in its + // position t.Pos.Start-- t.Pos.End++ @@ -370,7 +424,10 @@ func (s *Lexer) readString() (Token, error) { if !ok { s.end++ s.endRunes++ - return s.makeError("Invalid character escape sequence: \\%s.", s.Input[s.end:s.end+5]) + return s.makeError( + "Invalid character escape sequence: \\%s.", + s.Input[s.end:s.end+5], + ) } buf.WriteRune(r) s.end += 6 @@ -405,7 +462,7 @@ func (s *Lexer) readString() (Token, error) { // readBlockString from the input // -// """("?"?(\\"""|\\(?!=""")|[^"\\]))*""" +// """("?"?(\\"""|\\(?!=""")|[^"\\]))*""". func (s *Lexer) readBlockString() (Token, error) { inputLen := len(s.Input) @@ -433,7 +490,7 @@ func (s *Lexer) readBlockString() (Token, error) { // If we have at least 3 quotes, use the last 3 as the closing quote if quoteCount >= 3 { // Add any extra quotes to the buffer (except the last 3) - for j := 0; j < quoteCount-3; j++ { + for range quoteCount - 3 { buf.WriteByte('"') } @@ -508,7 +565,7 @@ func unhex(b string) (v rune, ok bool) { // readName from the input // -// [_A-Za-z][_0-9A-Za-z]* +// [_A-Za-z][_0-9A-Za-z]*. func (s *Lexer) readName() (Token, error) { for s.end < len(s.Input) { r, w := s.peek() diff --git a/vendor/github.com/vektah/gqlparser/v2/parser/parser.go b/vendor/github.com/vektah/gqlparser/v2/parser/parser.go index 2aba983796ec..b6a306406c64 100644 --- a/vendor/github.com/vektah/gqlparser/v2/parser/parser.go +++ b/vendor/github.com/vektah/gqlparser/v2/parser/parser.go @@ -91,7 +91,7 @@ func (p *parser) peek() lexer.Token { return p.peekToken } -func (p *parser) error(tok lexer.Token, format string, args ...interface{}) { +func (p *parser) error(tok lexer.Token, format string, args ...any) { if p.err != nil { return } @@ -165,7 +165,7 @@ func (p *parser) unexpectedToken(tok lexer.Token) { p.error(tok, "Unexpected %s", tok.String()) } -func (p *parser) many(start lexer.Type, end lexer.Type, cb func()) { +func (p *parser) many(start, end lexer.Type, cb func()) { hasDef := p.skip(start) if !hasDef { return @@ -177,7 +177,7 @@ func (p *parser) many(start lexer.Type, end lexer.Type, cb func()) { p.next() } -func (p *parser) some(start lexer.Type, end lexer.Type, cb func()) *ast.CommentGroup { +func (p *parser) some(start, end lexer.Type, cb func()) *ast.CommentGroup { hasDef := p.skip(start) if !hasDef { return nil diff --git a/vendor/github.com/vektah/gqlparser/v2/parser/query.go b/vendor/github.com/vektah/gqlparser/v2/parser/query.go index 47ac214a91fa..271a2ffe819a 100644 --- a/vendor/github.com/vektah/gqlparser/v2/parser/query.go +++ b/vendor/github.com/vektah/gqlparser/v2/parser/query.go @@ -1,9 +1,8 @@ package parser import ( - "github.com/vektah/gqlparser/v2/lexer" - . "github.com/vektah/gqlparser/v2/ast" //nolint:staticcheck // bad, yeah + "github.com/vektah/gqlparser/v2/lexer" ) func ParseQuery(source *Source) (*QueryDocument, error) { @@ -259,7 +258,12 @@ func (p *parser) parseValueLiteral(isConst bool) *Value { p.unexpectedError() return nil } - return &Value{Position: &token.Pos, Comment: p.comment, Raw: p.parseVariable(), Kind: Variable} + return &Value{ + Position: &token.Pos, + Comment: p.comment, + Raw: p.parseVariable(), + Kind: Variable, + } case lexer.Int: kind = IntValue case lexer.Float: diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/core/helpers.go b/vendor/github.com/vektah/gqlparser/v2/validator/core/helpers.go index b395a8402bee..f977d00a8162 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/core/helpers.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/core/helpers.go @@ -8,11 +8,12 @@ import ( "strings" "github.com/agnivade/levenshtein" + "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" ) -func Message(msg string, args ...interface{}) ErrorOption { +func Message(msg string, args ...any) ErrorOption { return func(err *gqlerror.Error) { err.Message += fmt.Sprintf(msg, args...) } @@ -33,7 +34,7 @@ func At(position *ast.Position) ErrorOption { } } -func SuggestListQuoted(prefix string, typed string, suggestions []string) ErrorOption { +func SuggestListQuoted(prefix, typed string, suggestions []string) ErrorOption { suggested := SuggestionList(typed, suggestions) return func(err *gqlerror.Error) { if len(suggested) > 0 { @@ -42,7 +43,7 @@ func SuggestListQuoted(prefix string, typed string, suggestions []string) ErrorO } } -func SuggestListUnquoted(prefix string, typed string, suggestions []string) ErrorOption { +func SuggestListUnquoted(prefix, typed string, suggestions []string) ErrorOption { suggested := SuggestionList(typed, suggestions) return func(err *gqlerror.Error) { if len(suggested) > 0 { @@ -51,7 +52,7 @@ func SuggestListUnquoted(prefix string, typed string, suggestions []string) Erro } } -func Suggestf(suggestion string, args ...interface{}) ErrorOption { +func Suggestf(suggestion string, args ...any) ErrorOption { return func(err *gqlerror.Error) { err.Message += " Did you mean " + fmt.Sprintf(suggestion, args...) + "?" } @@ -117,12 +118,8 @@ func SuggestionList(input string, options []string) []string { func calcThreshold(a string) (threshold int) { // the logic is copied from here // https://github.com/graphql/graphql-js/blob/47bd8c8897c72d3efc17ecb1599a95cee6bac5e8/src/jsutils/suggestionList.ts#L14 - threshold = int(math.Floor(float64(len(a))*0.4) + 1) - - if threshold < 1 { - threshold = 1 - } - return + threshold = max(int(math.Floor(float64(len(a))*0.4)+1), 1) + return threshold } // Computes the lexical distance between strings A and B. @@ -136,7 +133,7 @@ func calcThreshold(a string) (threshold int) { // as a single edit which helps identify mis-cased values with an edit distance // of 1. // -// This distance can be useful for detecting typos in input or sorting +// This distance can be useful for detecting typos in input or sorting. func lexicalDistance(a, b string) int { if a == b { return 0 diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/core/walk.go b/vendor/github.com/vektah/gqlparser/v2/validator/core/walk.go index 09a3016fd4ca..4e4c9b30f110 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/core/walk.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/core/walk.go @@ -142,7 +142,11 @@ func (w *Walker) walkFragment(it *ast.FragmentDefinition) { } } -func (w *Walker) walkDirectives(parentDef *ast.Definition, directives []*ast.Directive, location ast.DirectiveLocation) { +func (w *Walker) walkDirectives( + parentDef *ast.Definition, + directives []*ast.Directive, + location ast.DirectiveLocation, +) { for _, dir := range directives { def := w.Schema.Directives[dir.Name] dir.Definition = def @@ -182,6 +186,8 @@ func (w *Walker) walkValue(value *ast.Value) { fieldDef := value.Definition.Fields.ForName(child.Name) if fieldDef != nil { child.Value.ExpectedType = fieldDef.Type + child.Value.ExpectedTypeHasDefault = fieldDef.DefaultValue != nil && + fieldDef.DefaultValue.Kind != ast.NullValue child.Value.Definition = w.Schema.Types[fieldDef.Type.Name()] } } @@ -208,6 +214,8 @@ func (w *Walker) walkValue(value *ast.Value) { func (w *Walker) walkArgument(argDef *ast.ArgumentDefinition, arg *ast.Argument) { if argDef != nil { arg.Value.ExpectedType = argDef.Type + arg.Value.ExpectedTypeHasDefault = argDef.DefaultValue != nil && + argDef.DefaultValue.Kind != ast.NullValue arg.Value.Definition = w.Schema.Types[argDef.Type.Name()] } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go index e4a67eb0cdbf..1c6f55877ea6 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fields_on_correct_type.go @@ -3,10 +3,8 @@ package rules import ( "fmt" "sort" - "strings" "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -17,12 +15,24 @@ func ruleFuncFieldsOnCorrectType(observers *Events, addError AddErrFunc, disable return } - message := fmt.Sprintf(`Cannot query field "%s" on type "%s".`, field.Name, field.ObjectDefinition.Name) + message := fmt.Sprintf( + `Cannot query field "%s" on type "%s".`, + field.Name, + field.ObjectDefinition.Name, + ) if !disableSuggestion { - if suggestedTypeNames := getSuggestedTypeNames(walker, field.ObjectDefinition, field.Name); suggestedTypeNames != nil { - message += " Did you mean to use an inline fragment on " + QuotedOrList(suggestedTypeNames...) + "?" - } else if suggestedFieldNames := getSuggestedFieldNames(field.ObjectDefinition, field.Name); suggestedFieldNames != nil { + if suggestedTypeNames := getSuggestedTypeNames( + walker, + field.ObjectDefinition, + field.Name, + ); suggestedTypeNames != nil { + message += " Did you mean to use an inline fragment on " + QuotedOrList( + suggestedTypeNames...) + "?" + } else if suggestedFieldNames := getSuggestedFieldNames( + field.ObjectDefinition, + field.Name, + ); suggestedFieldNames != nil { message += " Did you mean " + QuotedOrList(suggestedFieldNames...) + "?" } } @@ -89,7 +99,7 @@ func getSuggestedTypeNames(walker *Walker, parent *ast.Definition, name string) if diff != 0 { return diff < 0 } - return strings.Compare(typeA, typeB) < 0 + return typeA < typeB }) return suggestedTypes @@ -99,8 +109,8 @@ func getSuggestedTypeNames(walker *Walker, parent *ast.Definition, name string) // where max is set to the slice’s length, // we ensure that appending elements results // in a slice backed by a distinct array. -// This method prevents the shared array issue -func concatSlice(first []string, second []string) []string { +// This method prevents the shared array issue. +func concatSlice(first, second []string) []string { n := len(first) return append(first[:n:n], second...) } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go index 8fb2692589fa..bd1f84944b0f 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/fragments_on_composite_types.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -18,7 +17,10 @@ var FragmentsOnCompositeTypesRule = Rule{ return } - message := fmt.Sprintf(`Fragment cannot condition on non composite type "%s".`, inlineFragment.TypeCondition) + message := fmt.Sprintf( + `Fragment cannot condition on non composite type "%s".`, + inlineFragment.TypeCondition, + ) addError( Message("%s", message), @@ -27,11 +29,16 @@ var FragmentsOnCompositeTypesRule = Rule{ }) observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) { - if fragment.Definition == nil || fragment.TypeCondition == "" || fragment.Definition.IsCompositeType() { + if fragment.Definition == nil || fragment.TypeCondition == "" || + fragment.Definition.IsCompositeType() { return } - message := fmt.Sprintf(`Fragment "%s" cannot condition on non composite type "%s".`, fragment.Name, fragment.TypeCondition) + message := fmt.Sprintf( + `Fragment "%s" cannot condition on non composite type "%s".`, + fragment.Name, + fragment.TypeCondition, + ) addError( Message("%s", message), diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go index 4c065a715e6c..af7ca6db17fb 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_argument_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -21,7 +20,12 @@ func ruleFuncKnownArgumentNames(observers *Events, addError AddErrFunc, disableS if disableSuggestion { addError( - Message(`Unknown argument "%s" on field "%s.%s".`, arg.Name, field.ObjectDefinition.Name, field.Name), + Message( + `Unknown argument "%s" on field "%s.%s".`, + arg.Name, + field.ObjectDefinition.Name, + field.Name, + ), At(field.Position), ) } else { @@ -30,7 +34,12 @@ func ruleFuncKnownArgumentNames(observers *Events, addError AddErrFunc, disableS suggestions = append(suggestions, argDef.Name) } addError( - Message(`Unknown argument "%s" on field "%s.%s".`, arg.Name, field.ObjectDefinition.Name, field.Name), + Message( + `Unknown argument "%s" on field "%s.%s".`, + arg.Name, + field.ObjectDefinition.Name, + field.Name, + ), SuggestListQuoted("Did you mean", arg.Name, suggestions), At(field.Position), ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go index 2430d29b23cc..b81b93ed72c7 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_directives.go @@ -1,8 +1,9 @@ package rules import ( - "github.com/vektah/gqlparser/v2/ast" + "slices" + "github.com/vektah/gqlparser/v2/ast" //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -25,10 +26,8 @@ var KnownDirectivesRule = Rule{ return } - for _, loc := range directive.Definition.Locations { - if loc == directive.Location { - return - } + if slices.Contains(directive.Definition.Locations, directive.Location) { + return } // position must be exists if directive.Definition != nil @@ -40,7 +39,11 @@ var KnownDirectivesRule = Rule{ if !seen[tmp] { addError( - Message(`Directive "@%s" may not be used on %s.`, directive.Name, directive.Location), + Message( + `Directive "@%s" may not be used on %s.`, + directive.Name, + directive.Location, + ), At(directive.Position), ) seen[tmp] = true diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go index c9b9f90d4a59..c55cd658c4a1 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_fragment_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go index b67da68ce7ad..bc2d2d00b9dd 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_root_type.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go index a0f10fba756c..5a85d3bfe752 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/known_type_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go index dfa851c57743..890f71f7ed96 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/lone_anonymous_operation.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/max_introspection_depth.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/max_introspection_depth.go index 651b23b4e345..012a47448d24 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/max_introspection_depth.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/max_introspection_depth.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -29,7 +28,11 @@ var MaxIntrospectionDepth = Rule{ }, } -func checkDepthSelectionSet(selectionSet ast.SelectionSet, visitedFragments map[string]bool, depth int) bool { +func checkDepthSelectionSet( + selectionSet ast.SelectionSet, + visitedFragments map[string]bool, + depth int, +) bool { for _, child := range selectionSet { if field, ok := child.(*ast.Field); ok { if checkDepthField(field, visitedFragments, depth) { @@ -63,7 +66,11 @@ func checkDepthField(field *ast.Field, visitedFragments map[string]bool, depth i return checkDepthSelectionSet(field.SelectionSet, visitedFragments, depth) } -func checkDepthFragmentSpread(fragmentSpread *ast.FragmentSpread, visitedFragments map[string]bool, depth int) bool { +func checkDepthFragmentSpread( + fragmentSpread *ast.FragmentSpread, + visitedFragments map[string]bool, + depth int, +) bool { fragmentName := fragmentSpread.Name if visited, ok := visitedFragments[fragmentName]; ok && visited { // Fragment cycles are handled by `NoFragmentCyclesRule`. diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go index fb3ac6ad3c68..ead6ae9152da 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_fragment_cycles.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -55,7 +54,11 @@ var NoFragmentCyclesRule = Rule{ via = fmt.Sprintf(" via %s", strings.Join(fragmentNames, ", ")) } addError( - Message(`Cannot spread fragment "%s" within itself%s.`, spreadName, via), + Message( + `Cannot spread fragment "%s" within itself%s.`, + spreadName, + via, + ), At(spreadNode.Position), ) } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go index 562d7f19cee5..76cafb805a10 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_undefined_variables.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -11,13 +10,18 @@ var NoUndefinedVariablesRule = Rule{ Name: "NoUndefinedVariables", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnValue(func(walker *Walker, value *ast.Value) { - if walker.CurrentOperation == nil || value.Kind != ast.Variable || value.VariableDefinition != nil { + if walker.CurrentOperation == nil || value.Kind != ast.Variable || + value.VariableDefinition != nil { return } if walker.CurrentOperation.Name != "" { addError( - Message(`Variable "%s" is not defined by operation "%s".`, value, walker.CurrentOperation.Name), + Message( + `Variable "%s" is not defined by operation "%s".`, + value, + walker.CurrentOperation.Name, + ), At(value.Position), ) } else { diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go index 6d27e11e9e33..d28389a42ee2 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_fragments.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go index a4ce07090c0b..b393c5b27288 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/no_unused_variables.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -18,7 +17,11 @@ var NoUnusedVariablesRule = Rule{ if operation.Name != "" { addError( - Message(`Variable "$%s" is never used in operation "%s".`, varDef.Variable, operation.Name), + Message( + `Variable "$%s" is never used in operation "%s".`, + varDef.Variable, + operation.Name, + ), At(varDef.Position), ) } else { diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go index 9e843e760b46..77014e3ec739 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/overlapping_fields_can_be_merged.go @@ -6,7 +6,6 @@ import ( "reflect" "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -82,7 +81,8 @@ var OverlappingFieldsCanBeMergedRule = Rule{ }) observers.OnField(func(walker *Walker, field *ast.Field) { if walker.CurrentOperation == nil { - // When checking both Operation and Fragment, errors are duplicated when processing FragmentDefinition referenced from Operation + // When checking both Operation and Fragment, errors are duplicated when processing + // FragmentDefinition referenced from Operation return } m.walker = walker @@ -112,7 +112,11 @@ type pairSet struct { data map[string]map[string]bool } -func (pairSet *pairSet) Add(a *ast.FragmentSpread, b *ast.FragmentSpread, areMutuallyExclusive bool) { +func (pairSet *pairSet) Add( + a *ast.FragmentSpread, + b *ast.FragmentSpread, + areMutuallyExclusive bool, +) { add := func(a *ast.FragmentSpread, b *ast.FragmentSpread) { m := pairSet.data[a.Name] if m == nil { @@ -125,7 +129,11 @@ func (pairSet *pairSet) Add(a *ast.FragmentSpread, b *ast.FragmentSpread, areMut add(b, a) } -func (pairSet *pairSet) Has(a *ast.FragmentSpread, b *ast.FragmentSpread, areMutuallyExclusive bool) bool { +func (pairSet *pairSet) Has( + a *ast.FragmentSpread, + b *ast.FragmentSpread, + areMutuallyExclusive bool, +) bool { am, ok := pairSet.data[a.Name] if !ok { return false @@ -224,7 +232,11 @@ func (m *ConflictMessage) addFieldsConflictMessage(addError AddErrFunc) { var buf bytes.Buffer m.String(&buf) addError( - Message(`Fields "%s" conflict because %s. Use different aliases on the fields to fetch both if this was intentional.`, m.ResponseName, buf.String()), + Message( + `Fields "%s" conflict because %s. Use different aliases on the fields to fetch both if this was intentional.`, + m.ResponseName, + buf.String(), + ), At(m.Position), ) } @@ -240,7 +252,9 @@ type overlappingFieldsCanBeMergedManager struct { comparedFragments map[string]bool } -func (m *overlappingFieldsCanBeMergedManager) findConflictsWithinSelectionSet(selectionSet ast.SelectionSet) []*ConflictMessage { +func (m *overlappingFieldsCanBeMergedManager) findConflictsWithinSelectionSet( + selectionSet ast.SelectionSet, +) []*ConflictMessage { if len(selectionSet) == 0 { return nil } @@ -271,7 +285,12 @@ func (m *overlappingFieldsCanBeMergedManager) findConflictsWithinSelectionSet(se return conflicts.Conflicts } -func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFieldsAndFragment(conflicts *conflictMessageContainer, areMutuallyExclusive bool, fieldsMap *sequentialFieldsMap, fragmentSpread *ast.FragmentSpread) { +func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFieldsAndFragment( + conflicts *conflictMessageContainer, + areMutuallyExclusive bool, + fieldsMap *sequentialFieldsMap, + fragmentSpread *ast.FragmentSpread, +) { if m.comparedFragments[fragmentSpread.Name] { return } @@ -299,11 +318,21 @@ func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFieldsAndFr if fragmentSpread.Name == baseFragmentSpread.Name { continue } - m.collectConflictsBetweenFieldsAndFragment(conflicts, areMutuallyExclusive, fieldsMap, fragmentSpread) + m.collectConflictsBetweenFieldsAndFragment( + conflicts, + areMutuallyExclusive, + fieldsMap, + fragmentSpread, + ) } } -func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFragments(conflicts *conflictMessageContainer, areMutuallyExclusive bool, fragmentSpreadA *ast.FragmentSpread, fragmentSpreadB *ast.FragmentSpread) { +func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFragments( + conflicts *conflictMessageContainer, + areMutuallyExclusive bool, + fragmentSpreadA *ast.FragmentSpread, + fragmentSpreadB *ast.FragmentSpread, +) { var check func(fragmentSpreadA *ast.FragmentSpread, fragmentSpreadB *ast.FragmentSpread) check = func(fragmentSpreadA *ast.FragmentSpread, fragmentSpreadB *ast.FragmentSpread) { if fragmentSpreadA.Name == fragmentSpreadB.Name { @@ -322,8 +351,12 @@ func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFragments(c return } - fieldsMapA, fragmentSpreadsA := getFieldsAndFragmentNames(fragmentSpreadA.Definition.SelectionSet) - fieldsMapB, fragmentSpreadsB := getFieldsAndFragmentNames(fragmentSpreadB.Definition.SelectionSet) + fieldsMapA, fragmentSpreadsA := getFieldsAndFragmentNames( + fragmentSpreadA.Definition.SelectionSet, + ) + fieldsMapB, fragmentSpreadsB := getFieldsAndFragmentNames( + fragmentSpreadB.Definition.SelectionSet, + ) // (F) First, collect all conflicts between these two collections of fields // (not including any nested fragments). @@ -344,7 +377,11 @@ func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetweenFragments(c check(fragmentSpreadA, fragmentSpreadB) } -func (m *overlappingFieldsCanBeMergedManager) findConflictsBetweenSubSelectionSets(areMutuallyExclusive bool, selectionSetA ast.SelectionSet, selectionSetB ast.SelectionSet) *conflictMessageContainer { +func (m *overlappingFieldsCanBeMergedManager) findConflictsBetweenSubSelectionSets( + areMutuallyExclusive bool, + selectionSetA ast.SelectionSet, + selectionSetB ast.SelectionSet, +) *conflictMessageContainer { var conflicts conflictMessageContainer fieldsMapA, fragmentSpreadsA := getFieldsAndFragmentNames(selectionSetA) @@ -357,14 +394,24 @@ func (m *overlappingFieldsCanBeMergedManager) findConflictsBetweenSubSelectionSe // those referenced by each fragment name associated with the second. for _, fragmentSpread := range fragmentSpreadsB { m.comparedFragments = make(map[string]bool) - m.collectConflictsBetweenFieldsAndFragment(&conflicts, areMutuallyExclusive, fieldsMapA, fragmentSpread) + m.collectConflictsBetweenFieldsAndFragment( + &conflicts, + areMutuallyExclusive, + fieldsMapA, + fragmentSpread, + ) } // (I) Then collect conflicts between the second collection of fields and // those referenced by each fragment name associated with the first. for _, fragmentSpread := range fragmentSpreadsA { m.comparedFragments = make(map[string]bool) - m.collectConflictsBetweenFieldsAndFragment(&conflicts, areMutuallyExclusive, fieldsMapB, fragmentSpread) + m.collectConflictsBetweenFieldsAndFragment( + &conflicts, + areMutuallyExclusive, + fieldsMapB, + fragmentSpread, + ) } // (J) Also collect conflicts between any fragment names by the first and @@ -372,7 +419,12 @@ func (m *overlappingFieldsCanBeMergedManager) findConflictsBetweenSubSelectionSe // names to each item in the second set of names. for _, fragmentSpreadA := range fragmentSpreadsA { for _, fragmentSpreadB := range fragmentSpreadsB { - m.collectConflictsBetweenFragments(&conflicts, areMutuallyExclusive, fragmentSpreadA, fragmentSpreadB) + m.collectConflictsBetweenFragments( + &conflicts, + areMutuallyExclusive, + fragmentSpreadA, + fragmentSpreadB, + ) } } @@ -383,7 +435,10 @@ func (m *overlappingFieldsCanBeMergedManager) findConflictsBetweenSubSelectionSe return &conflicts } -func (m *overlappingFieldsCanBeMergedManager) collectConflictsWithin(conflicts *conflictMessageContainer, fieldsMap *sequentialFieldsMap) { +func (m *overlappingFieldsCanBeMergedManager) collectConflictsWithin( + conflicts *conflictMessageContainer, + fieldsMap *sequentialFieldsMap, +) { for _, fields := range fieldsMap.Iterator() { for idx, fieldA := range fields { for _, fieldB := range fields[idx+1:] { @@ -396,7 +451,12 @@ func (m *overlappingFieldsCanBeMergedManager) collectConflictsWithin(conflicts * } } -func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetween(conflicts *conflictMessageContainer, parentFieldsAreMutuallyExclusive bool, fieldsMapA *sequentialFieldsMap, fieldsMapB *sequentialFieldsMap) { +func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetween( + conflicts *conflictMessageContainer, + parentFieldsAreMutuallyExclusive bool, + fieldsMapA *sequentialFieldsMap, + fieldsMapB *sequentialFieldsMap, +) { for _, fieldsEntryA := range fieldsMapA.KeyValueIterator() { fieldsB, ok := fieldsMapB.Get(fieldsEntryA.ResponseName) if !ok { @@ -413,7 +473,11 @@ func (m *overlappingFieldsCanBeMergedManager) collectConflictsBetween(conflicts } } -func (m *overlappingFieldsCanBeMergedManager) findConflict(parentFieldsAreMutuallyExclusive bool, fieldA *ast.Field, fieldB *ast.Field) *ConflictMessage { +func (m *overlappingFieldsCanBeMergedManager) findConflict( + parentFieldsAreMutuallyExclusive bool, + fieldA *ast.Field, + fieldB *ast.Field, +) *ConflictMessage { if fieldA.ObjectDefinition == nil || fieldB.ObjectDefinition == nil { return nil } @@ -437,8 +501,12 @@ func (m *overlappingFieldsCanBeMergedManager) findConflict(parentFieldsAreMutual if fieldA.Name != fieldB.Name { return &ConflictMessage{ ResponseName: fieldNameA, - Message: fmt.Sprintf(`"%s" and "%s" are different fields`, fieldA.Name, fieldB.Name), - Position: fieldB.Position, + Message: fmt.Sprintf( + `"%s" and "%s" are different fields`, + fieldA.Name, + fieldB.Name, + ), + Position: fieldB.Position, } } @@ -452,18 +520,27 @@ func (m *overlappingFieldsCanBeMergedManager) findConflict(parentFieldsAreMutual } } - if fieldA.Definition != nil && fieldB.Definition != nil && doTypesConflict(m.walker, fieldA.Definition.Type, fieldB.Definition.Type) { + if fieldA.Definition != nil && fieldB.Definition != nil && + doTypesConflict(m.walker, fieldA.Definition.Type, fieldB.Definition.Type) { return &ConflictMessage{ ResponseName: fieldNameA, - Message: fmt.Sprintf(`they return conflicting types "%s" and "%s"`, fieldA.Definition.Type.String(), fieldB.Definition.Type.String()), - Position: fieldB.Position, + Message: fmt.Sprintf( + `they return conflicting types "%s" and "%s"`, + fieldA.Definition.Type.String(), + fieldB.Definition.Type.String(), + ), + Position: fieldB.Position, } } // Collect and compare sub-fields. Use the same "visited fragment names" list // for both collections so fields in a fragment reference are never // compared to themselves. - conflicts := m.findConflictsBetweenSubSelectionSets(areMutuallyExclusive, fieldA.SelectionSet, fieldB.SelectionSet) + conflicts := m.findConflictsBetweenSubSelectionSets( + areMutuallyExclusive, + fieldA.SelectionSet, + fieldB.SelectionSet, + ) if conflicts == nil { return nil } @@ -474,7 +551,7 @@ func (m *overlappingFieldsCanBeMergedManager) findConflict(parentFieldsAreMutual } } -func sameArguments(args1 []*ast.Argument, args2 []*ast.Argument) bool { +func sameArguments(args1, args2 []*ast.Argument) bool { if len(args1) != len(args2) { return false } @@ -493,7 +570,7 @@ func sameArguments(args1 []*ast.Argument, args2 []*ast.Argument) bool { return true } -func sameValue(value1 *ast.Value, value2 *ast.Value) bool { +func sameValue(value1, value2 *ast.Value) bool { if value1.Kind != value2.Kind { return false } @@ -503,7 +580,7 @@ func sameValue(value1 *ast.Value, value2 *ast.Value) bool { return true } -func doTypesConflict(walker *Walker, type1 *ast.Type, type2 *ast.Type) bool { +func doTypesConflict(walker *Walker, type1, type2 *ast.Type) bool { if type1.Elem != nil { if type2.Elem != nil { return doTypesConflict(walker, type1.Elem, type2.Elem) @@ -522,14 +599,17 @@ func doTypesConflict(walker *Walker, type1 *ast.Type, type2 *ast.Type) bool { t1 := walker.Schema.Types[type1.NamedType] t2 := walker.Schema.Types[type2.NamedType] - if (t1.Kind == ast.Scalar || t1.Kind == ast.Enum) && (t2.Kind == ast.Scalar || t2.Kind == ast.Enum) { + if (t1.Kind == ast.Scalar || t1.Kind == ast.Enum) && + (t2.Kind == ast.Scalar || t2.Kind == ast.Enum) { return t1.Name != t2.Name } return false } -func getFieldsAndFragmentNames(selectionSet ast.SelectionSet) (*sequentialFieldsMap, []*ast.FragmentSpread) { +func getFieldsAndFragmentNames( + selectionSet ast.SelectionSet, +) (*sequentialFieldsMap, []*ast.FragmentSpread) { fieldsMap := sequentialFieldsMap{ data: make(map[string][]*ast.Field), } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go index f932ac8c2e99..94cc6356c624 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -49,7 +48,11 @@ var PossibleFragmentSpreadsRule = Rule{ observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) { validate(walker, inlineFragment.ObjectDefinition, inlineFragment.TypeCondition, func() { addError( - Message(`Fragment cannot be spread here as objects of type "%s" can never be of type "%s".`, inlineFragment.ObjectDefinition.Name, inlineFragment.TypeCondition), + Message( + `Fragment cannot be spread here as objects of type "%s" can never be of type "%s".`, + inlineFragment.ObjectDefinition.Name, + inlineFragment.TypeCondition, + ), At(inlineFragment.Position), ) }) @@ -59,12 +62,22 @@ var PossibleFragmentSpreadsRule = Rule{ if fragmentSpread.Definition == nil { return } - validate(walker, fragmentSpread.ObjectDefinition, fragmentSpread.Definition.TypeCondition, func() { - addError( - Message(`Fragment "%s" cannot be spread here as objects of type "%s" can never be of type "%s".`, fragmentSpread.Name, fragmentSpread.ObjectDefinition.Name, fragmentSpread.Definition.TypeCondition), - At(fragmentSpread.Position), - ) - }) + validate( + walker, + fragmentSpread.ObjectDefinition, + fragmentSpread.Definition.TypeCondition, + func() { + addError( + Message( + `Fragment "%s" cannot be spread here as objects of type "%s" can never be of type "%s".`, + fragmentSpread.Name, + fragmentSpread.ObjectDefinition.Name, + fragmentSpread.Definition.TypeCondition, + ), + At(fragmentSpread.Position), + ) + }, + ) }) }, } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/rules.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/rules.go index 803543ed1752..e94151b06e33 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/rules.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/rules.go @@ -77,6 +77,7 @@ func (r *Rules) AddRule(name string, ruleFunc core.RuleFunc) { // GetInner returns the internal rule map. // If the map is not initialized, it returns an empty map. +// This returns a copy of the rules map, not the original map. func (r *Rules) GetInner() map[string]core.RuleFunc { if r == nil { return nil // impossible nonsense, hopefully @@ -84,7 +85,13 @@ func (r *Rules) GetInner() map[string]core.RuleFunc { if r.rules == nil { return make(map[string]core.RuleFunc) } - return r.rules + + rules := make(map[string]core.RuleFunc) + for k, v := range r.rules { + rules[k] = v + } + + return rules } // RemoveRule removes a rule with the specified name from the rule set. diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go index e4f210d75709..95fd2298f4cd 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/scalar_leafs.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -22,14 +21,22 @@ var ScalarLeafsRule = Rule{ if fieldType.IsLeafType() && len(field.SelectionSet) > 0 { addError( - Message(`Field "%s" must not have a selection since type "%s" has no subfields.`, field.Name, fieldType.Name), + Message( + `Field "%s" must not have a selection since type "%s" has no subfields.`, + field.Name, + fieldType.Name, + ), At(field.Position), ) } if !fieldType.IsLeafType() && len(field.SelectionSet) == 0 { addError( - Message(`Field "%s" of type "%s" must have a selection of subfields.`, field.Name, field.Definition.Type.String()), + Message( + `Field "%s" of type "%s" must have a selection of subfields.`, + field.Name, + field.Definition.Type.String(), + ), Suggestf(`"%s { ... }"`, field.Name), At(field.Position), ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go index feed91d5cebe..2d4322da1b39 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/single_field_subscriptions.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go index 2ed1da2b3435..882a8cb168c8 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_argument_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go index 0f577028142d..a1a0101671b7 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_directives_per_location.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -16,7 +15,10 @@ var UniqueDirectivesPerLocationRule = Rule{ for _, dir := range directives { if dir.Name != "repeatable" && seen[dir.Name] { addError( - Message(`The directive "@%s" can only be used once at this location.`, dir.Name), + Message( + `The directive "@%s" can only be used once at this location.`, + dir.Name, + ), At(dir.Position), ) } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go index 136b0fdb5a25..7b1a40ceb146 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_fragment_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go index 41d8d667aa06..67c92de180de 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_input_field_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go index ae4c54eedea9..199a4b0f5c53 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_operation_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go index 4d4a6a87f727..6a33d0e93687 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/unique_variable_names.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go index 43c1a1bfb558..5126245e5495 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/values_of_correct_type.go @@ -6,7 +6,6 @@ import ( "strconv" "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -19,7 +18,11 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable if value.Kind == ast.NullValue && value.ExpectedType.NonNull { addError( - Message(`Expected value of type "%s", found %s.`, value.ExpectedType.String(), value.String()), + Message( + `Expected value of type "%s", found %s.`, + value.ExpectedType.String(), + value.String(), + ), At(value.Position), ) } @@ -66,13 +69,21 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable if value.Definition.Kind == ast.Enum { if disableSuggestion { addError( - Message(`Enum "%s" cannot represent non-enum value: %s.`, value.ExpectedType.String(), value.String()), + Message( + `Enum "%s" cannot represent non-enum value: %s.`, + value.ExpectedType.String(), + value.String(), + ), At(value.Position), ) } else { rawValStr := fmt.Sprint(rawVal) addError( - Message(`Enum "%s" cannot represent non-enum value: %s.`, value.ExpectedType.String(), value.String()), + Message( + `Enum "%s" cannot represent non-enum value: %s.`, + value.ExpectedType.String(), + value.String(), + ), SuggestListQuoted("Did you mean the enum value", rawValStr, possibleEnums), At(value.Position), ) @@ -92,20 +103,32 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable rawValStr := fmt.Sprint(rawVal) addError( unexpectedTypeMessageOnly(value), - SuggestListUnquoted("Did you mean the enum value", rawValStr, possibleEnums), + SuggestListUnquoted( + "Did you mean the enum value", + rawValStr, + possibleEnums, + ), At(value.Position), ) } } else if value.Definition.EnumValues.ForName(value.Raw) == nil { if disableSuggestion { addError( - Message(`Value "%s" does not exist in "%s" enum.`, value.String(), value.ExpectedType.String()), + Message( + `Value "%s" does not exist in "%s" enum.`, + value.String(), + value.ExpectedType.String(), + ), At(value.Position), ) } else { rawValStr := fmt.Sprint(rawVal) addError( - Message(`Value "%s" does not exist in "%s" enum.`, value.String(), value.ExpectedType.String()), + Message( + `Value "%s" does not exist in "%s" enum.`, + value.String(), + value.ExpectedType.String(), + ), SuggestListQuoted("Did you mean the enum value", rawValStr, possibleEnums), At(value.Position), ) @@ -124,7 +147,12 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable fieldValue := value.Children.ForName(field.Name) if fieldValue == nil && field.DefaultValue == nil { addError( - Message(`Field "%s.%s" of required type "%s" was not provided.`, value.Definition.Name, field.Name, field.Type.String()), + Message( + `Field "%s.%s" of required type "%s" was not provided.`, + value.Definition.Name, + field.Name, + field.Type.String(), + ), At(value.Position), ) continue @@ -137,7 +165,10 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable func() { if len(value.Children) != 1 { addError( - Message(`OneOf Input Object "%s" must specify exactly one key.`, value.Definition.Name), + Message( + `OneOf Input Object "%s" must specify exactly one key.`, + value.Definition.Name, + ), At(value.Position), ) return @@ -147,7 +178,11 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable isNullLiteral := fieldValue == nil || fieldValue.Kind == ast.NullValue if isNullLiteral { addError( - Message(`Field "%s.%s" must be non-null.`, value.Definition.Name, value.Definition.Fields[0].Name), + Message( + `Field "%s.%s" must be non-null.`, + value.Definition.Name, + value.Definition.Fields[0].Name, + ), At(fieldValue.Position), ) return @@ -159,7 +194,11 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable isNullableVariable := !fieldValue.VariableDefinition.Type.NonNull if isNullableVariable { addError( - Message(`Variable "%s" must be non-nullable to be used for OneOf Input Object "%s".`, variableName, value.Definition.Name), + Message( + `Variable "%s" must be non-nullable to be used for OneOf Input Object "%s".`, + variableName, + value.Definition.Name, + ), At(fieldValue.Position), ) } @@ -172,7 +211,11 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable if value.Definition.Fields.ForName(fieldValue.Name) == nil { if disableSuggestion { addError( - Message(`Field "%s" is not defined by type "%s".`, fieldValue.Name, value.Definition.Name), + Message( + `Field "%s" is not defined by type "%s".`, + fieldValue.Name, + value.Definition.Name, + ), At(fieldValue.Position), ) } else { @@ -182,7 +225,11 @@ func ruleFuncValuesOfCorrectType(observers *Events, addError AddErrFunc, disable } addError( - Message(`Field "%s" is not defined by type "%s".`, fieldValue.Name, value.Definition.Name), + Message( + `Field "%s" is not defined by type "%s".`, + fieldValue.Name, + value.Definition.Name, + ), SuggestListQuoted("Did you mean", fieldValue.Name, suggestions), At(fieldValue.Position), ) @@ -223,7 +270,12 @@ func unexpectedTypeMessage(addError AddErrFunc, v *ast.Value) { func unexpectedTypeMessageOnly(v *ast.Value) ErrorOption { switch v.ExpectedType.String() { case "Int", "Int!": - if _, err := strconv.ParseInt(v.Raw, 10, 32); err != nil && errors.Is(err, strconv.ErrRange) { + if _, err := strconv.ParseInt( + v.Raw, + 10, + 32, + ); err != nil && + errors.Is(err, strconv.ErrRange) { return Message(`Int cannot represent non 32-bit signed integer value: %s`, v.String()) } return Message(`Int cannot represent non-integer value: %s`, v.String()) @@ -236,11 +288,20 @@ func unexpectedTypeMessageOnly(v *ast.Value) ErrorOption { 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()) + // 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()) + return Message( + `Enum "%s" cannot represent non-enum value: %s.`, + v.ExpectedType.String(), + v.String(), + ) } - return Message(`Expected value of type "%s", found %s.`, v.ExpectedType.String(), v.String()) + return Message( + `Expected value of type "%s", found %s.`, + v.ExpectedType.String(), + v.String(), + ) } } diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go index 77f116bb50f6..b0670404efd5 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_are_input_types.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go index b2af7e192327..d3d36a293f5c 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/rules/variables_in_allowed_position.go @@ -2,7 +2,6 @@ package rules import ( "github.com/vektah/gqlparser/v2/ast" - //nolint:staticcheck // Validator rules each use dot imports for convenience. . "github.com/vektah/gqlparser/v2/validator/core" ) @@ -11,7 +10,9 @@ var VariablesInAllowedPositionRule = Rule{ Name: "VariablesInAllowedPosition", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnValue(func(walker *Walker, value *ast.Value) { - if value.Kind != ast.Variable || value.ExpectedType == nil || value.VariableDefinition == nil || walker.CurrentOperation == nil { + if value.Kind != ast.Variable || value.ExpectedType == nil || + value.VariableDefinition == nil || + walker.CurrentOperation == nil { return } @@ -19,12 +20,18 @@ var VariablesInAllowedPositionRule = Rule{ // todo: move me into walk // If there is a default non nullable types can be null - if value.VariableDefinition.DefaultValue != nil && value.VariableDefinition.DefaultValue.Kind != ast.NullValue { + if value.VariableDefinition.DefaultValue != nil && + value.VariableDefinition.DefaultValue.Kind != ast.NullValue { if value.ExpectedType.NonNull { tmp.NonNull = false } } + // If the expected type has a default, the given variable can be null + if value.ExpectedTypeHasDefault { + tmp.NonNull = false + } + if !value.VariableDefinition.Type.IsCompatible(&tmp) { addError( Message( diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/schema.go b/vendor/github.com/vektah/gqlparser/v2/validator/schema.go index a8754afc2be8..d40b9f192cfa 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/schema.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/schema.go @@ -1,6 +1,7 @@ package validator import ( + "slices" "sort" "strconv" "strings" @@ -48,7 +49,13 @@ func ValidateSchemaDocument(sd *SchemaDocument) (*Schema, error) { } if def.Kind != ext.Kind { - return nil, gqlerror.ErrorPosf(ext.Position, "Cannot extend type %s because the base type is a %s, not %s.", ext.Name, def.Kind, ext.Kind) + return nil, gqlerror.ErrorPosf( + ext.Position, + "Cannot extend type %s because the base type is a %s, not %s.", + ext.Name, + def.Kind, + ext.Kind, + ) } def.Directives = append(def.Directives, ext.Directives...) @@ -95,14 +102,21 @@ func ValidateSchemaDocument(sd *SchemaDocument) (*Schema, error) { // version of gqlparser, in which case they're in trouble // anyway. default: - return nil, gqlerror.ErrorPosf(dir.Position, "Cannot redeclare directive %s.", dir.Name) + return nil, gqlerror.ErrorPosf( + dir.Position, + "Cannot redeclare directive %s.", + dir.Name, + ) } } schema.Directives[dir.Name] = sd.Directives[i] } if len(sd.Schema) > 1 { - return nil, gqlerror.ErrorPosf(sd.Schema[1].Position, "Cannot have multiple schema entry points, consider schema extensions instead.") + return nil, gqlerror.ErrorPosf( + sd.Schema[1].Position, + "Cannot have multiple schema entry points, consider schema extensions instead.", + ) } if len(sd.Schema) == 1 { @@ -110,7 +124,12 @@ func ValidateSchemaDocument(sd *SchemaDocument) (*Schema, error) { for _, entrypoint := range sd.Schema[0].OperationTypes { def := schema.Types[entrypoint.Type] if def == nil { - return nil, gqlerror.ErrorPosf(entrypoint.Position, "Schema root %s refers to a type %s that does not exist.", entrypoint.Operation, entrypoint.Type) + return nil, gqlerror.ErrorPosf( + entrypoint.Position, + "Schema root %s refers to a type %s that does not exist.", + entrypoint.Operation, + entrypoint.Type, + ) } switch entrypoint.Operation { case Query: @@ -121,7 +140,12 @@ func ValidateSchemaDocument(sd *SchemaDocument) (*Schema, error) { schema.Subscription = def } } - if err := validateDirectives(&schema, sd.Schema[0].Directives, LocationSchema, nil); err != nil { + if err := validateDirectives( + &schema, + sd.Schema[0].Directives, + LocationSchema, + nil, + ); err != nil { return nil, err } schema.SchemaDirectives = append(schema.SchemaDirectives, sd.Schema[0].Directives...) @@ -131,7 +155,12 @@ func ValidateSchemaDocument(sd *SchemaDocument) (*Schema, error) { for _, entrypoint := range ext.OperationTypes { def := schema.Types[entrypoint.Type] if def == nil { - return nil, gqlerror.ErrorPosf(entrypoint.Position, "Schema root %s refers to a type %s that does not exist.", entrypoint.Operation, entrypoint.Type) + return nil, gqlerror.ErrorPosf( + entrypoint.Position, + "Schema root %s refers to a type %s that does not exist.", + entrypoint.Operation, + entrypoint.Type, + ) } switch entrypoint.Operation { case Query: @@ -259,7 +288,13 @@ func validateDefinition(schema *Schema, def *Definition) *gqlerror.Error { return gqlerror.ErrorPosf(def.Position, "Undefined type %s.", strconv.Quote(typ)) } if !isValidKind(typDef.Kind, Object) { - return gqlerror.ErrorPosf(def.Position, "%s type %s must be %s.", def.Kind, strconv.Quote(typ), kindList(Object)) + return gqlerror.ErrorPosf( + def.Position, + "%s type %s must be %s.", + def.Kind, + strconv.Quote(typ), + kindList(Object), + ) } } @@ -272,37 +307,75 @@ func validateDefinition(schema *Schema, def *Definition) *gqlerror.Error { switch def.Kind { case Object, Interface: if len(def.Fields) == 0 { - return gqlerror.ErrorPosf(def.Position, "%s %s: must define one or more fields.", def.Kind, def.Name) + return gqlerror.ErrorPosf( + def.Position, + "%s %s: must define one or more fields.", + def.Kind, + def.Name, + ) } for _, field := range def.Fields { if typ, ok := schema.Types[field.Type.Name()]; ok { if !isValidKind(typ.Kind, Scalar, Object, Interface, Union, Enum) { - return gqlerror.ErrorPosf(field.Position, "%s %s: field must be one of %s.", def.Kind, def.Name, kindList(Scalar, Object, Interface, Union, Enum)) + return gqlerror.ErrorPosf( + field.Position, + "%s %s: field must be one of %s.", + def.Kind, + def.Name, + kindList(Scalar, Object, Interface, Union, Enum), + ) } } } case Enum: if len(def.EnumValues) == 0 { - return gqlerror.ErrorPosf(def.Position, "%s %s: must define one or more unique enum values.", def.Kind, def.Name) + return gqlerror.ErrorPosf( + def.Position, + "%s %s: must define one or more unique enum values.", + def.Kind, + def.Name, + ) } for _, value := range def.EnumValues { for _, nonEnum := range [3]string{"true", "false", "null"} { if value.Name == nonEnum { - return gqlerror.ErrorPosf(def.Position, "%s %s: non-enum value %s.", def.Kind, def.Name, value.Name) + return gqlerror.ErrorPosf( + def.Position, + "%s %s: non-enum value %s.", + def.Kind, + def.Name, + value.Name, + ) } } - if err := validateDirectives(schema, value.Directives, LocationEnumValue, nil); err != nil { + if err := validateDirectives( + schema, + value.Directives, + LocationEnumValue, + nil, + ); err != nil { return err } } case InputObject: if len(def.Fields) == 0 { - return gqlerror.ErrorPosf(def.Position, "%s %s: must define one or more input fields.", def.Kind, def.Name) + return gqlerror.ErrorPosf( + def.Position, + "%s %s: must define one or more input fields.", + def.Kind, + def.Name, + ) } for _, field := range def.Fields { if typ, ok := schema.Types[field.Type.Name()]; ok { if !isValidKind(typ.Kind, Scalar, Enum, InputObject) { - return gqlerror.ErrorPosf(field.Position, "%s %s: field must be one of %s.", typ.Kind, field.Name, kindList(Scalar, Enum, InputObject)) + return gqlerror.ErrorPosf( + field.Position, + "%s %s: field must be one of %s.", + typ.Kind, + field.Name, + kindList(Scalar, Enum, InputObject), + ) } } } @@ -311,7 +384,12 @@ func validateDefinition(schema *Schema, def *Definition) *gqlerror.Error { for idx, field1 := range def.Fields { for _, field2 := range def.Fields[idx+1:] { if field1.Name == field2.Name { - return gqlerror.ErrorPosf(field2.Position, "Field %s.%s can only be defined once.", def.Name, field2.Name) + return gqlerror.ErrorPosf( + field2.Position, + "Field %s.%s can only be defined once.", + def.Name, + field2.Name, + ) } } } @@ -334,7 +412,11 @@ func validateTypeRef(schema *Schema, typ *Type) *gqlerror.Error { return nil } -func validateArgs(schema *Schema, args ArgumentDefinitionList, currentDirective *DirectiveDefinition) *gqlerror.Error { +func validateArgs( + schema *Schema, + args ArgumentDefinitionList, + currentDirective *DirectiveDefinition, +) *gqlerror.Error { for _, arg := range args { if err := validateName(arg.Position, arg.Name); err != nil { // now, GraphQL spec doesn't have reserved argument name @@ -353,45 +435,71 @@ func validateArgs(schema *Schema, args ArgumentDefinitionList, currentDirective def.Kind, ) } - if err := validateDirectives(schema, arg.Directives, LocationArgumentDefinition, currentDirective); err != nil { + if err := validateDirectives( + schema, + arg.Directives, + LocationArgumentDefinition, + currentDirective, + ); err != nil { return err } } return nil } -func validateDirectives(schema *Schema, dirs DirectiveList, location DirectiveLocation, currentDirective *DirectiveDefinition) *gqlerror.Error { +func validateDirectives( + schema *Schema, + dirs DirectiveList, + location DirectiveLocation, + currentDirective *DirectiveDefinition, +) *gqlerror.Error { for _, dir := range dirs { if err := validateName(dir.Position, dir.Name); err != nil { // now, GraphQL spec doesn't have reserved directive name return err } if currentDirective != nil && dir.Name == currentDirective.Name { - return gqlerror.ErrorPosf(dir.Position, "Directive %s cannot refer to itself.", currentDirective.Name) + return gqlerror.ErrorPosf( + dir.Position, + "Directive %s cannot refer to itself.", + currentDirective.Name, + ) } dirDefinition := schema.Directives[dir.Name] if dirDefinition == nil { return gqlerror.ErrorPosf(dir.Position, "Undefined directive %s.", dir.Name) } - validKind := false - for _, dirLocation := range dirDefinition.Locations { - if dirLocation == location { - validKind = true - break - } - } + validKind := slices.Contains(dirDefinition.Locations, location) if !validKind { - return gqlerror.ErrorPosf(dir.Position, "Directive %s is not applicable on %s.", dir.Name, location) + return gqlerror.ErrorPosf( + dir.Position, + "Directive %s is not applicable on %s.", + dir.Name, + location, + ) } for _, arg := range dir.Arguments { if dirDefinition.Arguments.ForName(arg.Name) == nil { - return gqlerror.ErrorPosf(arg.Position, "Undefined argument %s for directive %s.", arg.Name, dir.Name) + return gqlerror.ErrorPosf( + arg.Position, + "Undefined argument %s for directive %s.", + arg.Name, + dir.Name, + ) } } for _, schemaArg := range dirDefinition.Arguments { if schemaArg.Type.NonNull && schemaArg.DefaultValue == nil { - if arg := dir.Arguments.ForName(schemaArg.Name); arg == nil || arg.Value.Kind == NullValue { - return gqlerror.ErrorPosf(dir.Position, "Argument %s for directive %s cannot be null.", schemaArg.Name, dir.Name) + if arg := dir.Arguments.ForName( + schemaArg.Name, + ); arg == nil || + arg.Value.Kind == NullValue { + return gqlerror.ErrorPosf( + dir.Position, + "Argument %s for directive %s cannot be null.", + schemaArg.Name, + dir.Name, + ) } } } @@ -408,7 +516,12 @@ func validateImplements(schema *Schema, def *Definition, intfName string) *gqler return gqlerror.ErrorPosf(def.Position, "Undefined type %s.", strconv.Quote(intfName)) } if intf.Kind != Interface { - return gqlerror.ErrorPosf(def.Position, "%s is a non interface type %s.", strconv.Quote(intfName), intf.Kind) + return gqlerror.ErrorPosf( + def.Position, + "%s is a non interface type %s.", + strconv.Quote(intfName), + intf.Kind, + ) } for _, requiredField := range intf.Fields { foundField := def.Fields.ForName(requiredField.Name) @@ -429,24 +542,37 @@ func validateImplements(schema *Schema, def *Definition, intfName string) *gqler for _, requiredArg := range requiredField.Arguments { foundArg := foundField.Arguments.ForName(requiredArg.Name) if foundArg == nil { - return gqlerror.ErrorPosf(foundField.Position, + return gqlerror.ErrorPosf( + foundField.Position, `For %s to implement %s the field %s must have the same arguments but it is missing %s.`, - def.Name, intf.Name, requiredField.Name, requiredArg.Name, + def.Name, + intf.Name, + requiredField.Name, + requiredArg.Name, ) } if !requiredArg.Type.IsCompatible(foundArg.Type) { - return gqlerror.ErrorPosf(foundArg.Position, + return gqlerror.ErrorPosf( + foundArg.Position, `For %s to implement %s the field %s must have the same arguments but %s has the wrong type.`, - def.Name, intf.Name, requiredField.Name, requiredArg.Name, + def.Name, + intf.Name, + requiredField.Name, + requiredArg.Name, ) } } for _, foundArgs := range foundField.Arguments { - if requiredField.Arguments.ForName(foundArgs.Name) == nil && foundArgs.Type.NonNull && foundArgs.DefaultValue == nil { - return gqlerror.ErrorPosf(foundArgs.Position, + if requiredField.Arguments.ForName(foundArgs.Name) == nil && foundArgs.Type.NonNull && + foundArgs.DefaultValue == nil { + return gqlerror.ErrorPosf( + foundArgs.Position, `For %s to implement %s any additional arguments on %s must be optional or have a default value but %s is required.`, - def.Name, intf.Name, foundField.Name, foundArgs.Name, + def.Name, + intf.Name, + foundField.Name, + foundArgs.Name, ) } } @@ -456,7 +582,11 @@ func validateImplements(schema *Schema, def *Definition, intfName string) *gqler // validateTypeImplementsAncestors // https://github.com/graphql/graphql-js/blob/47bd8c8897c72d3efc17ecb1599a95cee6bac5e8/src/type/validate.ts#L428 -func validateTypeImplementsAncestors(schema *Schema, def *Definition, intfName string) *gqlerror.Error { +func validateTypeImplementsAncestors( + schema *Schema, + def *Definition, + intfName string, +) *gqlerror.Error { intf := schema.Types[intfName] if intf == nil { return gqlerror.ErrorPosf(def.Position, "Undefined type %s.", strconv.Quote(intfName)) @@ -479,15 +609,10 @@ func validateTypeImplementsAncestors(schema *Schema, def *Definition, intfName s } func containsString(slice []string, want string) bool { - for _, str := range slice { - if want == str { - return true - } - } - return false + return slices.Contains(slice, want) } -func isCovariant(schema *Schema, required *Type, actual *Type) bool { +func isCovariant(schema *Schema, required, actual *Type) bool { if required.NonNull && !actual.NonNull { return false } @@ -513,18 +638,17 @@ func isCovariant(schema *Schema, required *Type, actual *Type) bool { func validateName(pos *Position, name string) *gqlerror.Error { if strings.HasPrefix(name, "__") { - return gqlerror.ErrorPosf(pos, `Name "%s" must not begin with "__", which is reserved by GraphQL introspection.`, name) + return gqlerror.ErrorPosf( + pos, + `Name "%s" must not begin with "__", which is reserved by GraphQL introspection.`, + name, + ) } return nil } func isValidKind(kind DefinitionKind, valid ...DefinitionKind) bool { - for _, k := range valid { - if kind == k { - return true - } - } - return false + return slices.Contains(valid, kind) } func kindList(kinds ...DefinitionKind) string { diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/validator.go b/vendor/github.com/vektah/gqlparser/v2/validator/validator.go index 1214ed16e62e..9fb40d6a18dc 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/validator.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/validator.go @@ -2,6 +2,7 @@ package validator import ( "sort" + //nolint:staticcheck // bad, yeah . "github.com/vektah/gqlparser/v2/ast" "github.com/vektah/gqlparser/v2/gqlerror" @@ -24,7 +25,7 @@ var ( OrList = core.OrList ) -// Walk is an alias for core.Walk +// Walk is an alias for core.Walk. func Walk(schema *Schema, document *QueryDocument, observers *Events) { core.Walk(schema, document, observers) } @@ -49,9 +50,9 @@ func AddRule(name string, ruleFunc RuleFunc) { // RemoveRule removes an existing rule from the rule set // if one of the same name exists. -// The rule set is global, so it is not safe for concurrent changes +// The rule set is global, so it is not safe for concurrent changes. func RemoveRule(name string) { - var result []Rule // nolint:prealloc // using initialized with len(rules) produces a race condition + var result []Rule //nolint:prealloc // using initialized with len(rules) produces a race condition for _, r := range specifiedRules { if r.Name == name { continue @@ -64,10 +65,10 @@ func RemoveRule(name string) { // ReplaceRule replaces an existing rule from the rule set // if one of the same name exists. // If no match is found, it will add a new rule to the rule set. -// The rule set is global, so it is not safe for concurrent changes +// The rule set is global, so it is not safe for concurrent changes. func ReplaceRule(name string, ruleFunc RuleFunc) { var found bool - var result []Rule // nolint:prealloc // using initialized with len(rules) produces a race condition + var result []Rule //nolint:prealloc // using initialized with len(rules) produces a race condition for _, r := range specifiedRules { if r.Name == name { found = true @@ -117,7 +118,11 @@ func Validate(schema *Schema, doc *QueryDocument, rules ...Rule) gqlerror.List { return errs } -func ValidateWithRules(schema *Schema, doc *QueryDocument, rules *validatorrules.Rules) gqlerror.List { +func ValidateWithRules( + schema *Schema, + doc *QueryDocument, + rules *validatorrules.Rules, +) gqlerror.List { if rules == nil { rules = validatorrules.NewDefaultRules() } @@ -134,7 +139,7 @@ func ValidateWithRules(schema *Schema, doc *QueryDocument, rules *validatorrules } observers := &core.Events{} - var currentRules []Rule // nolint:prealloc // would require extra local refs for len + var currentRules []Rule //nolint:prealloc // would require extra local refs for len for name, ruleFunc := range rules.GetInner() { currentRules = append(currentRules, Rule{Name: name, RuleFunc: ruleFunc}) // ensure deterministic order evaluation diff --git a/vendor/github.com/vektah/gqlparser/v2/validator/vars.go b/vendor/github.com/vektah/gqlparser/v2/validator/vars.go index 205a7fb51656..50e2cdb29543 100644 --- a/vendor/github.com/vektah/gqlparser/v2/validator/vars.go +++ b/vendor/github.com/vektah/gqlparser/v2/validator/vars.go @@ -2,6 +2,7 @@ package validator import ( "encoding/json" + "errors" "fmt" "reflect" "strconv" @@ -12,11 +13,15 @@ import ( ) //nolint:staticcheck // We do not care about capitalized error strings -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) { - coercedVars := map[string]interface{}{} +// VariableValues coerces and validates variable values. +func VariableValues( + schema *ast.Schema, + op *ast.OperationDefinition, + variables map[string]any, +) (map[string]any, error) { + coercedVars := map[string]any{} validator := varValidator{ path: ast.Path{ast.PathName("variable")}, @@ -60,13 +65,23 @@ func VariableValues(schema *ast.Schema, op *ast.OperationDefinition, variables m case "Int": n, err := jsonNumber.Int64() if err != nil { - return nil, gqlerror.ErrorPathf(validator.path, "cannot use value %d as %s", n, v.Type.NamedType) + return nil, gqlerror.ErrorPathf( + validator.path, + "cannot use value %d as %s", + n, + v.Type.NamedType, + ) } rv = reflect.ValueOf(n) case "Float": f, err := jsonNumber.Float64() if err != nil { - return nil, gqlerror.ErrorPathf(validator.path, "cannot use value %f as %s", f, v.Type.NamedType) + return nil, gqlerror.ErrorPathf( + validator.path, + "cannot use value %f as %s", + f, + v.Type.NamedType, + ) } rv = reflect.ValueOf(f) } @@ -93,7 +108,10 @@ type varValidator struct { schema *ast.Schema } -func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) (reflect.Value, *gqlerror.Error) { +func (v *varValidator) validateVarType( + typ *ast.Type, + val reflect.Value, +) (reflect.Value, *gqlerror.Error) { currentPath := v.path resetPath := func() { v.path = currentPath @@ -137,7 +155,8 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) (reflec switch def.Kind { case ast.Enum: kind := val.Type().Kind() - if kind != reflect.Int && kind != reflect.Int32 && kind != reflect.Int64 && kind != reflect.String { + if kind != reflect.Int && kind != reflect.Int32 && kind != reflect.Int64 && + kind != reflect.String { return val, gqlerror.ErrorPathf(v.path, "enums must be ints or strings") } isValidEnum := false @@ -154,11 +173,17 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) (reflec kind := val.Type().Kind() switch typ.NamedType { case "Int": - if kind == reflect.Int || kind == reflect.Int32 || kind == reflect.Int64 || kind == reflect.Float32 || kind == reflect.Float64 || IsValidIntString(val, kind) { + if kind == reflect.Int || kind == reflect.Int32 || kind == reflect.Int64 || + kind == reflect.Float32 || + kind == reflect.Float64 || + IsValidIntString(val, kind) { return val, nil } case "Float": - if kind == reflect.Float32 || kind == reflect.Float64 || kind == reflect.Int || kind == reflect.Int32 || kind == reflect.Int64 || IsValidFloatString(val, kind) { + if kind == reflect.Float32 || kind == reflect.Float64 || kind == reflect.Int || + kind == reflect.Int32 || + kind == reflect.Int64 || + IsValidFloatString(val, kind) { return val, nil } case "String": @@ -172,7 +197,8 @@ func (v *varValidator) validateVarType(typ *ast.Type, val reflect.Value) (reflec } case "ID": - if kind == reflect.Int || kind == reflect.Int32 || kind == reflect.Int64 || kind == reflect.String { + if kind == reflect.Int || kind == reflect.Int32 || kind == reflect.Int64 || + kind == reflect.String { return val, nil } default: diff --git a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go deleted file mode 100644 index 2ef36bbcf92a..000000000000 --- a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package protodelim marshals and unmarshals varint size-delimited messages. -package protodelim - -import ( - "bufio" - "encoding/binary" - "fmt" - "io" - - "google.golang.org/protobuf/encoding/protowire" - "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/proto" -) - -// MarshalOptions is a configurable varint size-delimited marshaler. -type MarshalOptions struct{ proto.MarshalOptions } - -// MarshalTo writes a varint size-delimited wire-format message to w. -// If w returns an error, MarshalTo returns it unchanged. -func (o MarshalOptions) MarshalTo(w io.Writer, m proto.Message) (int, error) { - msgBytes, err := o.MarshalOptions.Marshal(m) - if err != nil { - return 0, err - } - - sizeBytes := protowire.AppendVarint(nil, uint64(len(msgBytes))) - sizeWritten, err := w.Write(sizeBytes) - if err != nil { - return sizeWritten, err - } - msgWritten, err := w.Write(msgBytes) - if err != nil { - return sizeWritten + msgWritten, err - } - return sizeWritten + msgWritten, nil -} - -// MarshalTo writes a varint size-delimited wire-format message to w -// with the default options. -// -// See the documentation for [MarshalOptions.MarshalTo]. -func MarshalTo(w io.Writer, m proto.Message) (int, error) { - return MarshalOptions{}.MarshalTo(w, m) -} - -// UnmarshalOptions is a configurable varint size-delimited unmarshaler. -type UnmarshalOptions struct { - proto.UnmarshalOptions - - // MaxSize is the maximum size in wire-format bytes of a single message. - // Unmarshaling a message larger than MaxSize will return an error. - // A zero MaxSize will default to 4 MiB. - // Setting MaxSize to -1 disables the limit. - MaxSize int64 -} - -const defaultMaxSize = 4 << 20 // 4 MiB, corresponds to the default gRPC max request/response size - -// SizeTooLargeError is an error that is returned when the unmarshaler encounters a message size -// that is larger than its configured [UnmarshalOptions.MaxSize]. -type SizeTooLargeError struct { - // Size is the varint size of the message encountered - // that was larger than the provided MaxSize. - Size uint64 - - // MaxSize is the MaxSize limit configured in UnmarshalOptions, which Size exceeded. - MaxSize uint64 -} - -func (e *SizeTooLargeError) Error() string { - return fmt.Sprintf("message size %d exceeded unmarshaler's maximum configured size %d", e.Size, e.MaxSize) -} - -// Reader is the interface expected by [UnmarshalFrom]. -// It is implemented by *[bufio.Reader]. -type Reader interface { - io.Reader - io.ByteReader -} - -// UnmarshalFrom parses and consumes a varint size-delimited wire-format message -// from r. -// The provided message must be mutable (e.g., a non-nil pointer to a message). -// -// The error is [io.EOF] error only if no bytes are read. -// If an EOF happens after reading some but not all the bytes, -// UnmarshalFrom returns a non-io.EOF error. -// In particular if r returns a non-io.EOF error, UnmarshalFrom returns it unchanged, -// and if only a size is read with no subsequent message, [io.ErrUnexpectedEOF] is returned. -func (o UnmarshalOptions) UnmarshalFrom(r Reader, m proto.Message) error { - var sizeArr [binary.MaxVarintLen64]byte - sizeBuf := sizeArr[:0] - for i := range sizeArr { - b, err := r.ReadByte() - if err != nil { - // Immediate EOF is unexpected. - if err == io.EOF && i != 0 { - break - } - return err - } - sizeBuf = append(sizeBuf, b) - if b < 0x80 { - break - } - } - size, n := protowire.ConsumeVarint(sizeBuf) - if n < 0 { - return protowire.ParseError(n) - } - - maxSize := o.MaxSize - if maxSize == 0 { - maxSize = defaultMaxSize - } - if maxSize != -1 && size > uint64(maxSize) { - return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: uint64(maxSize)}, "") - } - - var b []byte - var err error - if br, ok := r.(*bufio.Reader); ok { - // Use the []byte from the bufio.Reader instead of having to allocate one. - // This reduces CPU usage and allocated bytes. - b, err = br.Peek(int(size)) - if err == nil { - defer br.Discard(int(size)) - } else { - b = nil - } - } - if b == nil { - b = make([]byte, size) - _, err = io.ReadFull(r, b) - } - - if err == io.EOF { - return io.ErrUnexpectedEOF - } - if err != nil { - return err - } - if err := o.Unmarshal(b, m); err != nil { - return err - } - return nil -} - -// UnmarshalFrom parses and consumes a varint size-delimited wire-format message -// from r with the default options. -// The provided message must be mutable (e.g., a non-nil pointer to a message). -// -// See the documentation for [UnmarshalOptions.UnmarshalFrom]. -func UnmarshalFrom(r Reader, m proto.Message) error { - return UnmarshalOptions{}.UnmarshalFrom(r, m) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index fe5cb77503a3..0605a63fb02f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -160,9 +160,6 @@ github.com/aws/smithy-go/tracing github.com/aws/smithy-go/traits github.com/aws/smithy-go/transport/http github.com/aws/smithy-go/transport/http/internal/io -# github.com/beorn7/perks v1.0.1 -## explicit; go 1.11 -github.com/beorn7/perks/quantile # github.com/blang/semver v3.5.1+incompatible ## explicit github.com/blang/semver @@ -364,9 +361,6 @@ github.com/fvbommel/sortorder # github.com/fxamacker/cbor/v2 v2.9.0 ## explicit; go 1.20 github.com/fxamacker/cbor/v2 -# github.com/go-ini/ini v1.67.0 -## explicit -github.com/go-ini/ini # github.com/go-logr/logr v1.4.3 ## explicit; go 1.18 github.com/go-logr/logr @@ -599,14 +593,14 @@ github.com/lestrrat-go/dsig-secp256k1 # github.com/lestrrat-go/httpcc v1.0.1 ## explicit; go 1.16 github.com/lestrrat-go/httpcc -# github.com/lestrrat-go/httprc/v3 v3.0.1 +# github.com/lestrrat-go/httprc/v3 v3.0.2 ## explicit; go 1.23.0 github.com/lestrrat-go/httprc/v3 github.com/lestrrat-go/httprc/v3/errsink github.com/lestrrat-go/httprc/v3/proxysink github.com/lestrrat-go/httprc/v3/tracesink -# github.com/lestrrat-go/jwx/v3 v3.0.11 -## explicit; go 1.24.4 +# github.com/lestrrat-go/jwx/v3 v3.0.13 +## explicit; go 1.24.0 github.com/lestrrat-go/jwx/v3 github.com/lestrrat-go/jwx/v3/cert github.com/lestrrat-go/jwx/v3/internal/base64 @@ -635,9 +629,6 @@ github.com/lestrrat-go/jwx/v3/jwt github.com/lestrrat-go/jwx/v3/jwt/internal/errors github.com/lestrrat-go/jwx/v3/jwt/internal/types github.com/lestrrat-go/jwx/v3/transform -# github.com/lestrrat-go/option v1.0.1 -## explicit; go 1.16 -github.com/lestrrat-go/option # github.com/lestrrat-go/option/v2 v2.0.0 ## explicit; go 1.23 github.com/lestrrat-go/option/v2 @@ -849,15 +840,14 @@ github.com/mxk/go-flowrate/flowrate # github.com/oklog/ulid/v2 v2.1.1 ## explicit; go 1.15 github.com/oklog/ulid/v2 -# github.com/open-policy-agent/opa v1.10.1 -## explicit; go 1.24.6 +# github.com/open-policy-agent/opa v1.14.1 +## explicit; go 1.25.0 github.com/open-policy-agent/opa/capabilities 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 github.com/open-policy-agent/opa/internal/compiler/wasm github.com/open-policy-agent/opa/internal/compiler/wasm/opa -github.com/open-policy-agent/opa/internal/config github.com/open-policy-agent/opa/internal/debug github.com/open-policy-agent/opa/internal/deepcopy github.com/open-policy-agent/opa/internal/edittree @@ -876,11 +866,8 @@ github.com/open-policy-agent/opa/internal/providers/aws/crypto github.com/open-policy-agent/opa/internal/providers/aws/v4 github.com/open-policy-agent/opa/internal/ref github.com/open-policy-agent/opa/internal/rego/opa -github.com/open-policy-agent/opa/internal/report -github.com/open-policy-agent/opa/internal/runtime/init github.com/open-policy-agent/opa/internal/semver github.com/open-policy-agent/opa/internal/strings -github.com/open-policy-agent/opa/internal/strvals github.com/open-policy-agent/opa/internal/uuid github.com/open-policy-agent/opa/internal/version github.com/open-policy-agent/opa/internal/wasm/constant @@ -898,9 +885,7 @@ 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 @@ -908,8 +893,6 @@ 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 @@ -968,22 +951,6 @@ github.com/planetscale/vtprotobuf/vtproto # github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 ## explicit github.com/pmezard/go-difflib/difflib -# github.com/prometheus/client_golang v1.23.2 -## explicit; go 1.23.0 -github.com/prometheus/client_golang/prometheus -github.com/prometheus/client_golang/prometheus/internal -# github.com/prometheus/client_model v0.6.2 -## explicit; go 1.22.0 -github.com/prometheus/client_model/go -# github.com/prometheus/common v0.67.5 -## explicit; go 1.24.0 -github.com/prometheus/common/expfmt -github.com/prometheus/common/model -# github.com/prometheus/procfs v0.20.1 -## explicit; go 1.25.0 -github.com/prometheus/procfs -github.com/prometheus/procfs/internal/fs -github.com/prometheus/procfs/internal/util # github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 ## explicit github.com/rcrowley/go-metrics @@ -1000,7 +967,7 @@ github.com/secure-systems-lab/go-securesystemslib/cjson github.com/secure-systems-lab/go-securesystemslib/dsse github.com/secure-systems-lab/go-securesystemslib/encrypted github.com/secure-systems-lab/go-securesystemslib/signerverifier -# github.com/segmentio/asm v1.2.0 +# github.com/segmentio/asm v1.2.1 ## explicit; go 1.18 github.com/segmentio/asm/base64 github.com/segmentio/asm/cpu @@ -1131,11 +1098,11 @@ github.com/transparency-dev/merkle github.com/transparency-dev/merkle/compact github.com/transparency-dev/merkle/proof github.com/transparency-dev/merkle/rfc6962 -# github.com/valyala/fastjson v1.6.4 +# github.com/valyala/fastjson v1.6.7 ## explicit; go 1.12 github.com/valyala/fastjson github.com/valyala/fastjson/fastfloat -# github.com/vektah/gqlparser/v2 v2.5.30 +# github.com/vektah/gqlparser/v2 v2.5.32 ## explicit; go 1.22 github.com/vektah/gqlparser/v2/ast github.com/vektah/gqlparser/v2/gqlerror @@ -1504,7 +1471,6 @@ google.golang.org/grpc/cmd/protoc-gen-go-grpc google.golang.org/protobuf/cmd/protoc-gen-go google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo google.golang.org/protobuf/compiler/protogen -google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/protojson google.golang.org/protobuf/encoding/prototext google.golang.org/protobuf/encoding/protowire From 7cbf3a61936aa096510515723f1be4d042d3edcc Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 16 Jun 2026 14:38:44 +0200 Subject: [PATCH 2/2] policy: remove uses of deprecated WithBuiltins The WithBuiltins method was deprecated in opa v0.23.0 ([opa@afc8c5e]) in favor of WithCapabilities, but the deprecation didn't use the standard format, causing it not being detected as deprecated. OPA v1.1.0 corrected the deprecation in [opa@622434d]. This patch replaces uses of the deprecated functions. [opa@afc8c5e]: https://github.com/open-policy-agent/opa/commit/afc8c5e2a22878086067821f24e15d060594227a [opa@622434d]: https://github.com/open-policy-agent/opa/commit/622434d11386c7b12aee703d7c1eedea34a27c7b Signed-off-by: Sebastiaan van Stijn --- policy/tester.go | 17 +++++++++-------- policy/validate.go | 15 +-------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/policy/tester.go b/policy/tester.go index 4baae4cb2ac3..106dbc9b4cb1 100644 --- a/policy/tester.go +++ b/policy/tester.go @@ -211,21 +211,22 @@ func loadPolicyModules(root fs.StatFS, filename string) (map[string]*ast.Module, return modules, files, nil } -func compilePolicyModules(modules map[string]*ast.Module, p *Policy, fsProvider func() (fs.StatFS, func() error, error)) (*ast.Compiler, func() error, error) { +func policyCapabilities(funcs []fun) *ast.Capabilities { caps := &ast.Capabilities{ Builtins: builtins(), Features: slices.Clone(ast.Features), } - comp := ast.NewCompiler().WithCapabilities(caps).WithKeepModules(true) - - builtinDefs := make(map[string]*ast.Builtin) - for _, f := range p.funcs { - builtinDefs[f.decl.Name] = &ast.Builtin{ + for _, f := range funcs { + caps.Builtins = append(caps.Builtins, &ast.Builtin{ Name: f.decl.Name, Decl: f.decl.Decl, - } + }) } - comp = comp.WithBuiltins(builtinDefs) + return caps +} + +func compilePolicyModules(modules map[string]*ast.Module, p *Policy, fsProvider func() (fs.StatFS, func() error, error)) (*ast.Compiler, func() error, error) { + comp := ast.NewCompiler().WithCapabilities(policyCapabilities(p.funcs)).WithKeepModules(true) loader, closeLoader := newPolicyModuleLoader(fsProvider) comp = comp.WithModuleLoader(loader) diff --git a/policy/validate.go b/policy/validate.go index 0f8a7bfac34c..50f6e6bb8945 100644 --- a/policy/validate.go +++ b/policy/validate.go @@ -131,24 +131,11 @@ func (p *Policy) IsPolicyError(err error) bool { } func (p *Policy) regoBaseOpts() ([]func(*rego.Rego), func(), error) { - caps := &ast.Capabilities{ - Builtins: builtins(), - Features: slices.Clone(ast.Features), - } - comp := ast.NewCompiler().WithCapabilities(caps).WithKeepModules(true) + comp := ast.NewCompiler().WithCapabilities(policyCapabilities(p.funcs)).WithKeepModules(true) if p.opt.Log != nil { comp = comp.WithEnablePrintStatements(true) } - builtins := make(map[string]*ast.Builtin) - for _, f := range p.funcs { - builtins[f.decl.Name] = &ast.Builtin{ - Name: f.decl.Name, - Decl: f.decl.Decl, - } - } - comp = comp.WithBuiltins(builtins) - var root fs.StatFS var closeFS func() error closeRoot := func() {