From d3d45d2ccf85a79d91bef0058beae7cea6a2a556 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Oct 2026 08:38:30 +0000 Subject: [PATCH] chore(deps): bump github.com/tektoncd/pipeline from 1.16.0 to 1.17.0 Bumps [github.com/tektoncd/pipeline](https://github.com/tektoncd/pipeline) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/tektoncd/pipeline/releases) - [Changelog](https://github.com/tektoncd/pipeline/blob/main/releases.md) - [Commits](https://github.com/tektoncd/pipeline/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/tektoncd/pipeline dependency-version: 1.17.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 72 +- go.sum | 155 +- .../google => cel.dev}/cel-go/LICENSE | 0 .../google => cel.dev}/cel-go/cel/BUILD.bazel | 2 +- .../cel-go/cel/async/BUILD.bazel | 2 +- .../cel-go/cel/async/async.go | 10 +- .../google => cel.dev}/cel-go/cel/cel.go | 0 .../google => cel.dev}/cel-go/cel/decls.go | 10 +- .../google => cel.dev}/cel-go/cel/env.go | 26 +- .../cel-go/cel/fieldpaths.go | 4 +- .../google => cel.dev}/cel-go/cel/folding.go | 12 +- .../google => cel.dev}/cel-go/cel/inlining.go | 12 +- .../google => cel.dev}/cel-go/cel/io.go | 12 +- .../google => cel.dev}/cel-go/cel/library.go | 24 +- .../google => cel.dev}/cel-go/cel/macro.go | 8 +- .../cel-go/cel/optimizer.go | 8 +- .../google => cel.dev}/cel-go/cel/options.go | 22 +- .../google => cel.dev}/cel-go/cel/program.go | 14 +- .../google => cel.dev}/cel-go/cel/prompt.go | 8 +- .../cel-go/cel/templates/authoring.tmpl | 0 .../cel-go/cel/validator.go | 8 +- .../cel-go/checker/BUILD.bazel | 3 +- .../cel-go/checker/checker.go | 14 +- .../google => cel.dev}/cel-go/checker/cost.go | 112 +- .../cel-go/checker/decls/BUILD.bazel | 2 +- .../cel-go/checker/decls/decls.go | 0 .../google => cel.dev}/cel-go/checker/env.go | 10 +- .../cel-go/checker/errors.go | 6 +- .../cel-go/checker/format.go | 4 +- .../cel-go/checker/mapping.go | 2 +- .../cel-go/checker/options.go | 0 .../cel-go/checker/printer.go | 4 +- .../cel-go/checker/scopes.go | 2 +- .../cel-go/checker/types.go | 2 +- .../cel-go/common/BUILD.bazel | 2 +- .../cel-go/common/ast/BUILD.bazel | 2 +- .../cel-go/common/ast/ast.go | 6 +- .../cel-go/common/ast/conversion.go | 4 +- .../cel-go/common/ast/expr.go | 2 +- .../cel-go/common/ast/factory.go | 2 +- .../cel-go/common/ast/navigable.go | 4 +- .../cel-go/common/containers/BUILD.bazel | 2 +- .../cel-go/common/containers/container.go | 2 +- .../google => cel.dev}/cel-go/common/cost.go | 0 vendor/cel.dev/cel-go/common/cost/BUILD.bazel | 25 + vendor/cel.dev/cel-go/common/cost/cost.go | 78 + .../cel-go/common/debug/BUILD.bazel | 2 +- .../cel-go/common/debug/debug.go | 6 +- .../cel-go/common/decls/BUILD.bazel | 2 +- .../cel-go/common/decls/decls.go | 12 +- .../google => cel.dev}/cel-go/common/doc.go | 0 .../cel-go/common/env/BUILD.bazel | 2 +- .../cel-go/common/env/env.go | 4 +- .../cel-go/common/env/io.go | 6 +- .../google => cel.dev}/cel-go/common/error.go | 0 .../cel-go/common/errors.go | 0 .../cel-go/common/functions/BUILD.bazel | 2 +- .../cel-go/common/functions/functions.go | 2 +- .../cel-go/common/location.go | 0 .../cel-go/common/operators/BUILD.bazel | 2 +- .../cel-go/common/operators/operators.go | 0 .../cel-go/common/overloads/BUILD.bazel | 2 +- .../cel-go/common/overloads/overloads.go | 0 .../cel-go/common/runes/BUILD.bazel | 2 +- .../cel-go/common/runes/buffer.go | 0 .../cel-go/common/source.go | 2 +- .../cel-go/common/stdlib/BUILD.bazel | 2 +- .../cel-go/common/stdlib/standard.go | 16 +- .../cel-go/common/types/BUILD.bazel | 5 +- .../cel-go/common/types/aggregate_sizer.go | 43 + .../cel-go/common/types/any_value.go | 0 .../cel-go/common/types/bool.go | 2 +- .../cel-go/common/types/bytes.go | 2 +- .../cel-go/common/types/compare.go | 2 +- .../cel-go/common/types/doc.go | 0 .../cel-go/common/types/double.go | 2 +- .../cel-go/common/types/duration.go | 4 +- .../cel-go/common/types/err.go | 2 +- .../cel-go/common/types/format.go | 4 +- .../cel-go/common/types/int.go | 2 +- .../cel-go/common/types/iterator.go | 4 +- .../cel-go/common/types/json_value.go | 0 .../cel-go/common/types/list.go | 42 +- .../cel-go/common/types/map.go | 43 +- .../cel-go/common/types/native.go | 21 +- .../cel-go/common/types/null.go | 2 +- .../cel-go/common/types/object.go | 18 +- .../cel-go/common/types/optional.go | 10 +- .../cel-go/common/types/overflow.go | 21 + .../cel-go/common/types/pb/BUILD.bazel | 2 +- .../cel-go/common/types/pb/checked.go | 0 .../cel-go/common/types/pb/enum.go | 0 .../cel-go/common/types/pb/equal.go | 0 .../cel-go/common/types/pb/file.go | 0 .../cel-go/common/types/pb/pb.go | 0 .../cel-go/common/types/pb/type.go | 0 .../cel-go/common/types/provider.go | 19 +- .../cel-go/common/types/ref/BUILD.bazel | 2 +- .../cel-go/common/types/ref/provider.go | 0 .../cel-go/common/types/ref/reference.go | 0 .../cel-go/common/types/regex.go | 0 .../cel.dev/cel-go/common/types/size_calc.go | 410 + .../cel-go/common/types/string.go | 4 +- .../cel-go/common/types/struct.go | 2 +- .../cel-go/common/types/timestamp.go | 90 +- .../cel-go/common/types/traits/BUILD.bazel | 2 +- .../cel-go/common/types/traits/comparer.go | 2 +- .../cel-go/common/types/traits/container.go | 2 +- .../common/types/traits/field_tester.go | 2 +- .../cel-go/common/types/traits/indexer.go | 2 +- .../cel-go/common/types/traits/iterator.go | 2 +- .../cel-go/common/types/traits/lister.go | 2 +- .../cel-go/common/types/traits/mapper.go | 2 +- .../cel-go/common/types/traits/matcher.go | 2 +- .../cel-go/common/types/traits/math.go | 2 +- .../cel-go/common/types/traits/receiver.go | 2 +- .../cel-go/common/types/traits/sizer.go | 2 +- .../cel-go/common/types/traits/traits.go | 0 .../cel-go/common/types/traits/zeroer.go | 0 .../cel-go/common/types/types.go | 6 +- .../cel-go/common/types/uint.go | 2 +- .../cel-go/common/types/unknown.go | 2 +- .../cel-go/common/types/util.go | 2 +- .../cel-go/interpreter/BUILD.bazel | 3 +- .../cel-go/interpreter/activation.go | 2 +- .../cel-go/interpreter/async.go | 6 +- .../cel-go/interpreter/attribute_patterns.go | 6 +- .../cel-go/interpreter/attributes.go | 8 +- .../cel-go/interpreter/decorators.go | 8 +- .../cel-go/interpreter/dispatcher.go | 2 +- .../cel-go/interpreter/evalstate.go | 2 +- .../cel-go/interpreter/frame.go | 6 +- .../cel-go/interpreter/interpretable.go | 12 +- .../cel-go/interpreter/interpreter.go | 9 +- .../cel-go/interpreter/optimizations.go | 4 +- .../cel-go/interpreter/planner.go | 29 +- .../cel-go/interpreter/prune.go | 12 +- .../cel-go/interpreter/runtimecost.go | 68 +- .../cel-go/parser/BUILD.bazel | 3 +- .../cel-go/parser/errors.go | 2 +- .../cel-go/parser/gen/BUILD.bazel | 2 +- .../cel-go/parser/gen/CEL.g4 | 0 .../cel-go/parser/gen/CEL.interp | 0 .../cel-go/parser/gen/CEL.tokens | 0 .../cel-go/parser/gen/CELLexer.interp | 0 .../cel-go/parser/gen/CELLexer.tokens | 0 .../cel-go/parser/gen/cel_base_listener.go | 0 .../cel-go/parser/gen/cel_base_visitor.go | 0 .../cel-go/parser/gen/cel_lexer.go | 0 .../cel-go/parser/gen/cel_listener.go | 0 .../cel-go/parser/gen/cel_parser.go | 0 .../cel-go/parser/gen/cel_visitor.go | 0 .../cel-go/parser/gen/doc.go | 0 .../cel-go/parser/gen/generate.sh | 0 .../cel-go/parser/helper.go | 8 +- .../google => cel.dev}/cel-go/parser/input.go | 2 +- .../google => cel.dev}/cel-go/parser/macro.go | 10 +- .../cel-go/parser/options.go | 0 .../cel-go/parser/parser.go | 12 +- .../cel-go/parser/unescape.go | 0 .../cel-go/parser/unparser.go | 8 +- .../cli/cli/config/credentials/file_store.go | 43 +- .../emicklei/go-restful/v3/.travis.yml | 13 - .../emicklei/go-restful/v3/CHANGES.md | 4 + .../emicklei/go-restful/v3/README.md | 1 + .../emicklei/go-restful/v3/curly.go | 50 +- .../emicklei/go-restful/v3/custom_verb.go | 34 +- .../github.com/emicklei/go-restful/v3/doc.go | 42 +- .../felixge/httpsnoop/capture_metrics.go | 37 +- .../felixge/httpsnoop/wrap_generated.go | 16179 ++++++++++++++++ .../httpsnoop/wrap_generated_gteq_1.8.go | 436 - .../httpsnoop/wrap_generated_lt_1.8.go | 278 - .../fxamacker/cbor/v2/.golangci.yml | 176 +- vendor/github.com/fxamacker/cbor/v2/README.md | 11 +- vendor/github.com/fxamacker/cbor/v2/cache.go | 257 +- vendor/github.com/fxamacker/cbor/v2/decode.go | 440 +- .../fxamacker/cbor/v2/decode_map_utils.go | 98 + .../github.com/fxamacker/cbor/v2/diagnose.go | 25 +- vendor/github.com/fxamacker/cbor/v2/encode.go | 55 +- .../fxamacker/cbor/v2/simplevalue.go | 2 +- vendor/github.com/fxamacker/cbor/v2/stream.go | 48 +- .../fxamacker/cbor/v2/structfields.go | 65 +- vendor/github.com/fxamacker/cbor/v2/valid.go | 20 +- .../go-openapi/jsonpointer/.gitignore | 6 +- .../go-openapi/jsonpointer/.golangci.yml | 110 +- .../go-openapi/jsonpointer/CODE_OF_CONDUCT.md | 6 +- .../go-openapi/jsonpointer/CONTRIBUTORS.md | 25 + .../github.com/go-openapi/jsonpointer/LICENSE | 1 - .../github.com/go-openapi/jsonpointer/NOTICE | 39 + .../go-openapi/jsonpointer/README.md | 180 +- .../go-openapi/jsonpointer/SECURITY.md | 37 + .../go-openapi/jsonpointer/errors.go | 50 +- .../go-openapi/jsonpointer/ifaces.go | 50 + .../go-openapi/jsonpointer/jsonname/doc.go | 5 + .../jsonpointer/jsonname/go_name_provider.go | 288 + .../go-openapi/jsonpointer/jsonname/ifaces.go | 16 + .../jsonpointer/jsonname/name_provider.go | 140 + .../go-openapi/jsonpointer/options.go | 85 + .../go-openapi/jsonpointer/pointer.go | 839 +- .../go-openapi/jsonreference/.editorconfig | 26 + .../go-openapi/jsonreference/.gitignore | 6 +- .../go-openapi/jsonreference/.golangci.yml | 112 +- .../jsonreference/CODE_OF_CONDUCT.md | 6 +- .../go-openapi/jsonreference/CONTRIBUTORS.md | 21 + .../go-openapi/jsonreference/NOTICE | 39 + .../go-openapi/jsonreference/README.md | 124 +- .../go-openapi/jsonreference/SECURITY.md | 37 + .../jsonreference/internal/normalize_url.go | 11 +- .../go-openapi/jsonreference/reference.go | 112 +- .../github.com/go-openapi/swag/.codecov.yml | 4 + vendor/github.com/go-openapi/swag/.gitignore | 2 + .../github.com/go-openapi/swag/.golangci.yml | 121 +- .../github.com/go-openapi/swag/.mockery.yml | 30 + .../go-openapi/swag/CODE_OF_CONDUCT.md | 6 +- .../go-openapi/swag/CONTRIBUTORS.md | 36 + vendor/github.com/go-openapi/swag/README.md | 230 +- vendor/github.com/go-openapi/swag/SECURITY.md | 37 + .../go-openapi/swag/cmdutils/LICENSE | 202 + .../go-openapi/swag/cmdutils/cmd_utils.go | 13 + .../go-openapi/swag/cmdutils/doc.go | 5 + .../go-openapi/swag/cmdutils_iface.go | 11 + .../github.com/go-openapi/swag/conv/LICENSE | 202 + .../go-openapi/swag/conv/convert.go | 161 + .../go-openapi/swag/conv/convert_types.go | 72 + vendor/github.com/go-openapi/swag/conv/doc.go | 15 + .../github.com/go-openapi/swag/conv/format.go | 28 + .../github.com/go-openapi/swag/conv/sizeof.go | 20 + .../go-openapi/swag/conv/type_constraints.go | 29 + .../github.com/go-openapi/swag/conv_iface.go | 486 + vendor/github.com/go-openapi/swag/convert.go | 208 - .../go-openapi/swag/convert_types.go | 730 - vendor/github.com/go-openapi/swag/doc.go | 70 +- vendor/github.com/go-openapi/swag/errors.go | 15 - vendor/github.com/go-openapi/swag/file.go | 33 - .../go-openapi/swag/fileutils/LICENSE | 202 + .../go-openapi/swag/fileutils/doc.go | 10 + .../go-openapi/swag/fileutils/file.go | 22 + .../go-openapi/swag/{ => fileutils}/path.go | 29 +- .../go-openapi/swag/fileutils_iface.go | 33 + vendor/github.com/go-openapi/swag/go.work | 21 + vendor/github.com/go-openapi/swag/go.work.sum | 7 + .../go-openapi/swag/initialism_index.go | 202 - vendor/github.com/go-openapi/swag/json.go | 313 - .../go-openapi/swag/jsonname_iface.go | 24 + .../go-openapi/swag/jsonutils/LICENSE | 202 + .../go-openapi/swag/jsonutils/README.md | 109 + .../go-openapi/swag/jsonutils/adapters/doc.go | 8 + .../swag/jsonutils/adapters/ifaces/doc.go | 5 + .../swag/jsonutils/adapters/ifaces/ifaces.go | 84 + .../adapters/ifaces/registry_iface.go | 91 + .../swag/jsonutils/adapters/registry.go | 229 + .../jsonutils/adapters/stdlib/json/adapter.go | 133 + .../jsonutils/adapters/stdlib/json/doc.go | 5 + .../jsonutils/adapters/stdlib/json/lexer.go | 356 + .../jsonutils/adapters/stdlib/json/options.go | 52 + .../adapters/stdlib/json/ordered_map.go | 289 + .../jsonutils/adapters/stdlib/json/pool.go | 42 + .../adapters/stdlib/json/register.go | 34 + .../jsonutils/adapters/stdlib/json/writer.go | 88 + .../go-openapi/swag/jsonutils/concat.go | 92 + .../go-openapi/swag/jsonutils/doc.go | 7 + .../go-openapi/swag/jsonutils/json.go | 116 + .../go-openapi/swag/jsonutils/ordered_map.go | 114 + .../go-openapi/swag/jsonutils_iface.go | 65 + .../go-openapi/swag/loading/LICENSE | 202 + .../github.com/go-openapi/swag/loading/doc.go | 29 + .../go-openapi/swag/loading/errors.go | 15 + .../go-openapi/swag/loading/json.go | 25 + .../go-openapi/swag/{ => loading}/loading.go | 118 +- .../go-openapi/swag/loading/options.go | 170 + .../go-openapi/swag/loading/yaml.go | 37 + .../go-openapi/swag/loading_iface.go | 93 + .../swag/{ => mangling}/BENCHMARK.md | 48 +- .../go-openapi/swag/mangling/LICENSE | 202 + .../go-openapi/swag/mangling/doc.go | 25 + .../swag/mangling/initialism_index.go | 270 + .../go-openapi/swag/mangling/name_lexem.go | 186 + .../go-openapi/swag/mangling/name_mangler.go | 370 + .../go-openapi/swag/mangling/options.go | 150 + .../go-openapi/swag/mangling/pools.go | 123 + .../go-openapi/swag/mangling/split.go | 341 + .../swag/{ => mangling}/string_bytes.go | 5 +- .../go-openapi/swag/mangling/util.go | 118 + .../go-openapi/swag/mangling_iface.go | 69 + .../github.com/go-openapi/swag/name_lexem.go | 93 - vendor/github.com/go-openapi/swag/net.go | 38 - .../go-openapi/swag/netutils/LICENSE | 202 + .../go-openapi/swag/netutils/doc.go | 5 + .../go-openapi/swag/netutils/net.go | 31 + .../go-openapi/swag/netutils_iface.go | 13 + .../github.com/go-openapi/swag/pools/LICENSE | 202 + .../go-openapi/swag/pools/README.md | 1 + .../github.com/go-openapi/swag/pools/debug.go | 17 + .../go-openapi/swag/pools/debug_off.go | 51 + .../go-openapi/swag/pools/debug_on.go | 237 + .../github.com/go-openapi/swag/pools/doc.go | 26 + .../github.com/go-openapi/swag/pools/pools.go | 410 + vendor/github.com/go-openapi/swag/split.go | 508 - .../go-openapi/swag/stringutils/LICENSE | 202 + .../swag/stringutils/collection_formats.go | 74 + .../go-openapi/swag/stringutils/doc.go | 5 + .../go-openapi/swag/stringutils/strings.go | 23 + .../go-openapi/swag/stringutils_iface.go | 34 + .../go-openapi/swag/typeutils/LICENSE | 202 + .../go-openapi/swag/typeutils/doc.go | 5 + .../go-openapi/swag/typeutils/types.go | 80 + .../go-openapi/swag/typeutils_iface.go | 12 + vendor/github.com/go-openapi/swag/util.go | 364 - vendor/github.com/go-openapi/swag/yaml.go | 481 - .../go-openapi/swag/yamlutils/LICENSE | 202 + .../go-openapi/swag/yamlutils/doc.go | 13 + .../go-openapi/swag/yamlutils/errors.go | 15 + .../go-openapi/swag/yamlutils/ordered_map.go | 335 + .../go-openapi/swag/yamlutils/yaml.go | 328 + .../go-openapi/swag/yamlutils_iface.go | 20 + .../internal/ipaddr/ipaddr.go | 82 + .../internal/verify/verify.go | 9 +- .../go-containerregistry/pkg/authn/authn.go | 4 +- .../go-containerregistry/pkg/name/digest.go | 11 +- .../go-containerregistry/pkg/name/ref.go | 6 + .../pkg/name/repository.go | 2 +- .../go-containerregistry/pkg/v1/hash.go | 6 + .../pkg/v1/mutate/index.go | 3 + .../pkg/v1/mutate/mutate.go | 87 +- .../pkg/v1/remote/check.go | 6 +- .../pkg/v1/remote/fetcher.go | 35 +- .../pkg/v1/remote/puller.go | 6 +- .../pkg/v1/remote/pusher.go | 6 +- .../pkg/v1/remote/transport/bearer.go | 7 +- .../pkg/v1/remote/write.go | 28 +- .../pkg/v1/types/types.go | 1 + vendor/github.com/josharian/intern/README.md | 5 - vendor/github.com/josharian/intern/intern.go | 44 - vendor/github.com/josharian/intern/license.md | 21 - .../compress/huff0/decompress_amd64.go | 203 +- .../compress/huff0/decompress_amd64.s | 4 +- .../compress/huff0/decompress_arm64.go | 37 + .../compress/huff0/decompress_arm64.s | 851 + .../compress/huff0/decompress_asm.go | 193 + .../compress/huff0/decompress_generic.go | 2 +- .../klauspost/compress/zstd/blockdec.go | 9 +- .../klauspost/compress/zstd/dict.go | 85 +- .../klauspost/compress/zstd/seqdec_amd64.s | 4 +- .../klauspost/compress/zstd/seqdec_arm64.s | 601 +- .../klauspost/compress/zstd/seqdec_asm.go | 33 +- vendor/github.com/mailru/easyjson/LICENSE | 7 - .../github.com/mailru/easyjson/buffer/pool.go | 278 - .../mailru/easyjson/jlexer/bytestostr.go | 21 - .../easyjson/jlexer/bytestostr_nounsafe.go | 13 - .../mailru/easyjson/jlexer/error.go | 15 - .../mailru/easyjson/jlexer/lexer.go | 1257 -- .../mailru/easyjson/jwriter/writer.go | 417 - .../prometheus/common/expfmt/decode.go | 19 +- .../prometheus/common/expfmt/encode.go | 152 +- .../prometheus/common/expfmt/expfmt.go | 11 + .../common/expfmt/openmetrics_2_0_create.go | 425 + .../prometheus/common/model/signature.go | 10 +- .../prometheus/common/model/time.go | 28 + .../github.com/sirupsen/logrus/.golangci.yml | 48 +- vendor/github.com/sirupsen/logrus/.travis.yml | 15 - .../github.com/sirupsen/logrus/CHANGELOG.md | 246 +- vendor/github.com/sirupsen/logrus/README.md | 92 +- vendor/github.com/sirupsen/logrus/alt_exit.go | 4 +- .../github.com/sirupsen/logrus/buffer_pool.go | 22 +- vendor/github.com/sirupsen/logrus/doc.go | 26 +- vendor/github.com/sirupsen/logrus/entry.go | 412 +- vendor/github.com/sirupsen/logrus/exported.go | 169 +- .../github.com/sirupsen/logrus/formatter.go | 47 +- .../sirupsen/logrus/json_formatter.go | 37 +- vendor/github.com/sirupsen/logrus/level.go | 101 + vendor/github.com/sirupsen/logrus/logger.go | 156 +- vendor/github.com/sirupsen/logrus/logrus.go | 211 +- .../logrus/terminal_check_appengine.go | 8 +- .../sirupsen/logrus/terminal_check_bsd.go | 3 +- .../sirupsen/logrus/terminal_check_js.go | 7 - .../logrus/terminal_check_no_terminal.go | 8 +- .../logrus/terminal_check_notappengine.go | 8 +- .../sirupsen/logrus/terminal_check_solaris.go | 2 + .../sirupsen/logrus/terminal_check_unix.go | 5 +- .../sirupsen/logrus/terminal_check_wasi.go | 8 - .../sirupsen/logrus/terminal_check_wasip1.go | 8 - .../sirupsen/logrus/terminal_check_windows.go | 2 +- .../sirupsen/logrus/text_formatter.go | 489 +- vendor/github.com/sirupsen/logrus/writer.go | 6 +- .../pipeline/pkg/apis/config/feature_flags.go | 27 + .../pkg/apis/pipeline/v1/openapi_generated.go | 465 +- .../apis/pipeline/v1/pipeline_validation.go | 45 +- .../pkg/apis/pipeline/v1/result_validation.go | 8 +- .../apis/pipeline/v1/strip_descriptions.go | 70 + .../pkg/apis/pipeline/v1/swagger.json | 198 +- .../pkg/apis/pipeline/v1/when_validation.go | 2 +- .../pipeline/v1alpha1/openapi_generated.go | 77 +- .../pkg/apis/pipeline/v1alpha1/swagger.json | 31 +- .../pipeline/v1beta1/openapi_generated.go | 582 +- .../pipeline/v1beta1/pipeline_validation.go | 45 +- .../pkg/apis/pipeline/v1beta1/swagger.json | 245 +- .../apis/pipeline/v1beta1/when_validation.go | 2 +- vendor/golang.org/x/sys/unix/ifreq_linux.go | 8 +- vendor/golang.org/x/sys/unix/ioctl_linux.go | 7 + vendor/golang.org/x/sys/unix/mkerrors.sh | 9 +- vendor/golang.org/x/sys/unix/syscall.go | 2 +- vendor/golang.org/x/sys/unix/syscall_bsd.go | 2 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 2 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 2 + .../x/sys/unix/zerrors_linux_386.go | 1 - .../x/sys/unix/zerrors_linux_amd64.go | 1 - .../x/sys/unix/zerrors_linux_arm.go | 1 - .../x/sys/unix/zerrors_linux_arm64.go | 1 - .../x/sys/unix/zerrors_linux_loong64.go | 1 - .../x/sys/unix/zerrors_linux_mips.go | 1 - .../x/sys/unix/zerrors_linux_mips64.go | 1 - .../x/sys/unix/zerrors_linux_mips64le.go | 1 - .../x/sys/unix/zerrors_linux_mipsle.go | 1 - .../x/sys/unix/zerrors_linux_ppc.go | 1 - .../x/sys/unix/zerrors_linux_ppc64.go | 1 - .../x/sys/unix/zerrors_linux_ppc64le.go | 1 - .../x/sys/unix/zerrors_linux_riscv64.go | 1 - .../x/sys/unix/zerrors_linux_s390x.go | 1 - .../x/sys/unix/zerrors_linux_sparc64.go | 35 +- vendor/golang.org/x/sys/unix/ztypes_linux.go | 86 +- .../golang.org/x/sys/unix/ztypes_linux_386.go | 32 +- .../x/sys/unix/ztypes_linux_amd64.go | 32 +- .../golang.org/x/sys/unix/ztypes_linux_arm.go | 32 +- .../x/sys/unix/ztypes_linux_arm64.go | 32 +- .../x/sys/unix/ztypes_linux_loong64.go | 32 +- .../x/sys/unix/ztypes_linux_mips.go | 32 +- .../x/sys/unix/ztypes_linux_mips64.go | 32 +- .../x/sys/unix/ztypes_linux_mips64le.go | 32 +- .../x/sys/unix/ztypes_linux_mipsle.go | 32 +- .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 32 +- .../x/sys/unix/ztypes_linux_ppc64.go | 32 +- .../x/sys/unix/ztypes_linux_ppc64le.go | 32 +- .../x/sys/unix/ztypes_linux_riscv64.go | 32 +- .../x/sys/unix/ztypes_linux_s390x.go | 32 +- .../x/sys/unix/ztypes_linux_sparc64.go | 32 +- .../golang.org/x/sys/windows/types_windows.go | 1 + vendor/golang.org/x/term/terminal.go | 24 +- vendor/golang.org/x/text/unicode/bidi/core.go | 5 +- .../x/text/unicode/norm/composition.go | 42 +- .../x/text/unicode/norm/forminfo.go | 24 +- .../x/text/unicode/norm/normalize.go | 5 +- .../x/text/unicode/norm/tables15.0.0.go | 1884 +- .../x/text/unicode/norm/tables17.0.0.go | 1924 +- .../x/text/unicode/norm/transform.go | 5 +- .../x/tools/go/ast/inspector/cursor.go | 41 + .../golang.org/x/tools/go/packages/visit.go | 33 +- .../x/tools/go/types/typeutil/callee.go | 86 - .../x/tools/go/types/typeutil/imports.go | 30 - .../x/tools/go/types/typeutil/map.go | 459 - .../tools/go/types/typeutil/methodsetcache.go | 71 - .../x/tools/go/types/typeutil/ui.go | 53 - .../x/tools/internal/moremaps/maps.go | 116 + .../x/tools/internal/typeparams/common.go | 68 - .../x/tools/internal/typeparams/coretype.go | 157 - .../x/tools/internal/typeparams/free.go | 129 - .../x/tools/internal/typeparams/normalize.go | 216 - .../x/tools/internal/typeparams/termlist.go | 169 - .../x/tools/internal/typeparams/typeterm.go | 172 - .../internal/typesinternal/assignedaddress.go | 128 + .../internal/typesinternal/classify_call.go | 77 +- .../x/tools/internal/typesinternal/element.go | 65 +- .../x/tools/internal/typesinternal/toonew.go | 44 +- .../x/tools/internal/typesinternal/types.go | 8 + .../endpointsharding/endpointsharding.go | 339 +- .../grpc/balancer/pickfirst/pickfirst.go | 50 +- .../grpc_binarylog_v1/binarylog.pb.go | 6 +- vendor/google.golang.org/grpc/call.go | 27 +- vendor/google.golang.org/grpc/clientconn.go | 1 + .../grpc/internal/buffer/unbounded.go | 32 +- .../grpc/internal/envconfig/envconfig.go | 7 + .../grpc/internal/envconfig/xds.go | 5 + .../internal/grpcsync/callback_serializer.go | 6 +- .../grpc/internal/grpcsync/refcounted.go | 109 + .../grpc/internal/internal.go | 4 + .../grpc/internal/resolver/config_selector.go | 15 +- .../grpc/internal/transport/controlbuf.go | 17 + .../grpc/internal/transport/http2_client.go | 57 +- .../grpc/internal/transport/http2_server.go | 1 + .../grpc/internal/transport/http_util.go | 53 +- .../grpc/internal/transport/transport.go | 18 +- .../grpc/metadata/metadata.go | 71 + .../grpc/resolver_wrapper.go | 2 +- vendor/google.golang.org/grpc/server.go | 490 +- vendor/google.golang.org/grpc/stream.go | 194 +- vendor/google.golang.org/grpc/version.go | 2 +- vendor/gopkg.in/yaml.v3/LICENSE | 50 - vendor/gopkg.in/yaml.v3/README.md | 150 - vendor/gopkg.in/yaml.v3/apic.go | 747 - vendor/gopkg.in/yaml.v3/decode.go | 1000 - vendor/gopkg.in/yaml.v3/emitterc.go | 2020 -- vendor/gopkg.in/yaml.v3/encode.go | 577 - vendor/gopkg.in/yaml.v3/parserc.go | 1258 -- vendor/gopkg.in/yaml.v3/readerc.go | 434 - vendor/gopkg.in/yaml.v3/resolve.go | 326 - vendor/gopkg.in/yaml.v3/scannerc.go | 3038 --- vendor/gopkg.in/yaml.v3/sorter.go | 134 - vendor/gopkg.in/yaml.v3/writerc.go | 48 - vendor/gopkg.in/yaml.v3/yaml.go | 698 - vendor/gopkg.in/yaml.v3/yamlh.go | 807 - vendor/gopkg.in/yaml.v3/yamlprivateh.go | 198 - .../apimachinery/pkg/api/meta/interfaces.go | 109 +- .../k8s.io/apimachinery/pkg/api/meta/meta.go | 4 + .../pkg/api/meta/multirestmapper.go | 132 +- .../apimachinery/pkg/api/meta/priority.go | 130 +- .../apimachinery/pkg/api/meta/restmapper.go | 56 +- .../pkg/api/operation/operation.go | 32 +- .../apimachinery/pkg/api/resource/quantity.go | 11 + .../pkg/api/validate/content/kube.go | 16 + .../pkg/api/validate/dependentrequired.go | 83 + .../pkg/api/validate/discriminator.go | 3 + .../apimachinery/pkg/api/validate/each.go | 174 +- .../apimachinery/pkg/api/validate/enum.go | 35 +- .../apimachinery/pkg/api/validate/errors.go | 96 + .../apimachinery/pkg/api/validate/item.go | 87 +- .../apimachinery/pkg/api/validate/limits.go | 20 + .../pkg/api/validate/monotonic.go | 43 + .../apimachinery/pkg/api/validate/options.go | 11 +- .../apimachinery/pkg/api/validate/strfmt.go | 22 + .../apimachinery/pkg/api/validate/subfield.go | 3 + .../apimachinery/pkg/api/validate/update.go | 154 +- .../pkg/api/validation/objectmeta.go | 58 +- .../pkg/apis/meta/v1/generated.proto | 27 + .../apimachinery/pkg/apis/meta/v1/types.go | 63 +- .../pkg/apis/meta/v1/unstructured/helpers.go | 1 + .../pkg/apis/meta/v1/validation/doc.go} | 10 +- .../pkg/apis/meta/v1/validation/validation.go | 74 +- .../v1/validation/zz_generated.validations.go | 638 + .../pkg/apis/meta/v1beta1/types.go | 2 +- .../pkg/conversion/queryparams/convert.go | 4 +- .../apimachinery/pkg/labels/selector.go | 9 +- .../k8s.io/apimachinery/pkg/runtime/codec.go | 2 + .../apimachinery/pkg/runtime/conversion.go | 13 - .../apimachinery/pkg/runtime/converter.go | 34 +- .../apimachinery/pkg/runtime/fieldinfo_126.go | 26 + .../apimachinery/pkg/runtime/fieldinfo_127.go | 33 + .../apimachinery/pkg/runtime/generated.proto | 6 +- .../k8s.io/apimachinery/pkg/runtime/helper.go | 20 +- .../k8s.io/apimachinery/pkg/runtime/scheme.go | 12 +- .../pkg/runtime/serializer/cbor/cbor.go | 31 +- .../runtime/serializer/cbor/collections.go | 328 + .../serializer/cbor/internal/modes/encode.go | 10 +- .../runtime/serializer/json/collections.go | 103 +- .../pkg/runtime/serializer/json/json.go | 1 + .../serializer/protobuf/collections.go | 13 +- .../runtime/serializer/protobuf/protobuf.go | 17 +- .../serializer/versioning/versioning.go | 2 + .../pkg/runtime/swagger_doc_generator.go | 32 +- .../k8s.io/apimachinery/pkg/runtime/types.go | 8 +- .../apimachinery/pkg/util/intstr/intstr.go | 1 + .../managedfields/internal/fieldmanager.go | 32 +- .../managedfields/internal/typeconverter.go | 18 + .../internal/versionconverter.go | 17 +- .../util/validation/field/error_matcher.go | 90 +- .../pkg/util/validation/field/errors.go | 20 + .../apimachinery/pkg/util/validation/ip.go | 2 + .../kube-openapi/pkg/generators/openapi.go | 19 +- .../rules/list_type_streaming_tags.go | 9 +- .../pkg/internal/serialization.go | 2 +- .../go-json-experiment/json/README.md | 246 +- .../go-json-experiment/json/arshal.go | 521 +- .../go-json-experiment/json/arshal_any.go | 281 +- .../go-json-experiment/json/arshal_default.go | 1467 +- .../go-json-experiment/json/arshal_funcs.go | 207 +- .../go-json-experiment/json/arshal_inlined.go | 121 +- .../go-json-experiment/json/arshal_methods.go | 326 +- .../go-json-experiment/json/arshal_time.go | 844 +- .../go-json-experiment/json/decode.go | 1655 -- .../go-json-experiment/json/doc.go | 226 +- .../go-json-experiment/json/encode.go | 1170 -- .../go-json-experiment/json/errors.go | 407 +- .../go-json-experiment/json/fields.go | 501 +- .../go-json-experiment/json/intern.go | 6 +- .../json/internal/internal.go | 40 + .../json/internal/jsonflags/flags.go | 213 + .../json/internal/jsonopts/options.go | 200 + .../json/internal/jsonwire/decode.go | 627 + .../json/internal/jsonwire/encode.go | 288 + .../json/internal/jsonwire/wire.go | 215 + .../json/jsontext/decode.go | 1177 ++ .../go-json-experiment/json/jsontext/doc.go | 109 + .../json/jsontext/encode.go | 975 + .../json/jsontext/errors.go | 180 + .../json/jsontext/export.go | 75 + .../json/jsontext/options.go | 302 + .../json/{ => jsontext}/pools.go | 90 +- .../go-json-experiment/json/jsontext/quote.go | 39 + .../json/{ => jsontext}/state.go | 445 +- .../json/{ => jsontext}/token.go | 85 +- .../go-json-experiment/json/jsontext/value.go | 393 + .../go-json-experiment/json/migrate.sh | 48 + .../go-json-experiment/json/options.go | 287 + .../go-json-experiment/json/value.go | 381 - .../kube-openapi/pkg/schemaconv/openapi.go | 11 +- .../pkg/schemaconv/proto_models.go | 10 +- .../k8s.io/kube-openapi/pkg/spec3/encoding.go | 13 +- .../k8s.io/kube-openapi/pkg/spec3/example.go | 13 +- .../pkg/spec3/external_documentation.go | 13 +- .../k8s.io/kube-openapi/pkg/spec3/header.go | 13 +- .../kube-openapi/pkg/spec3/media_type.go | 13 +- .../kube-openapi/pkg/spec3/operation.go | 13 +- .../kube-openapi/pkg/spec3/parameter.go | 13 +- vendor/k8s.io/kube-openapi/pkg/spec3/path.go | 25 +- .../kube-openapi/pkg/spec3/request_body.go | 13 +- .../k8s.io/kube-openapi/pkg/spec3/response.go | 47 +- .../kube-openapi/pkg/spec3/security_scheme.go | 7 +- .../k8s.io/kube-openapi/pkg/spec3/server.go | 25 +- vendor/k8s.io/kube-openapi/pkg/spec3/spec.go | 5 +- .../pkg/validation/spec/header.go | 13 +- .../kube-openapi/pkg/validation/spec/info.go | 13 +- .../kube-openapi/pkg/validation/spec/items.go | 13 +- .../pkg/validation/spec/operation.go | 13 +- .../pkg/validation/spec/parameter.go | 13 +- .../pkg/validation/spec/path_item.go | 15 +- .../kube-openapi/pkg/validation/spec/paths.go | 11 +- .../pkg/validation/spec/response.go | 15 +- .../pkg/validation/spec/responses.go | 17 +- .../pkg/validation/spec/schema.go | 13 +- .../pkg/validation/spec/security_scheme.go | 13 +- .../pkg/validation/spec/swagger.go | 59 +- .../kube-openapi/pkg/validation/spec/tag.go | 13 +- vendor/k8s.io/utils/ptr/OWNERS | 2 + vendor/k8s.io/utils/ptr/ptr.go | 2 +- vendor/modules.txt | 188 +- .../v6/fieldpath/element.go | 28 +- .../v6/fieldpath/pathelementmap.go | 25 +- .../v6/fieldpath/serialize-pe.go | 18 +- .../v6/fieldpath/serialize.go | 11 + .../structured-merge-diff/v6/fieldpath/set.go | 24 +- .../v6/schema/elements.go | 4 + .../structured-merge-diff/v6/schema/equals.go | 3 + .../v6/schema/schemaschema.go | 3 + .../v6/value/allocator.go | 80 +- .../v6/value/jsontagutil.go | 7 +- .../v6/value/reflectcache.go | 77 +- .../structured-merge-diff/v6/value/value.go | 5 + 635 files changed, 49877 insertions(+), 31906 deletions(-) rename vendor/{github.com/google => cel.dev}/cel-go/LICENSE (100%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/BUILD.bazel (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/async/BUILD.bazel (93%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/async/async.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/cel.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/decls.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/env.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/fieldpaths.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/folding.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/inlining.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/io.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/library.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/macro.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/optimizer.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/options.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/program.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/prompt.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/templates/authoring.tmpl (100%) rename vendor/{github.com/google => cel.dev}/cel-go/cel/validator.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/BUILD.bazel (95%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/checker.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/cost.go (92%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/decls/BUILD.bazel (89%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/decls/decls.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/env.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/errors.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/format.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/mapping.go (96%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/options.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/printer.go (95%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/scopes.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/checker/types.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/BUILD.bazel (93%) rename vendor/{github.com/google => cel.dev}/cel-go/common/ast/BUILD.bazel (96%) rename vendor/{github.com/google => cel.dev}/cel-go/common/ast/ast.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/ast/conversion.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/ast/expr.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/ast/factory.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/ast/navigable.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/containers/BUILD.bazel (89%) rename vendor/{github.com/google => cel.dev}/cel-go/common/containers/container.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/cost.go (100%) create mode 100644 vendor/cel.dev/cel-go/common/cost/BUILD.bazel create mode 100644 vendor/cel.dev/cel-go/common/cost/cost.go rename vendor/{github.com/google => cel.dev}/cel-go/common/debug/BUILD.bazel (88%) rename vendor/{github.com/google => cel.dev}/cel-go/common/debug/debug.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/common/decls/BUILD.bazel (95%) rename vendor/{github.com/google => cel.dev}/cel-go/common/decls/decls.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/doc.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/env/BUILD.bazel (96%) rename vendor/{github.com/google => cel.dev}/cel-go/common/env/env.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/env/io.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/common/error.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/errors.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/functions/BUILD.bazel (83%) rename vendor/{github.com/google => cel.dev}/cel-go/common/functions/functions.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/common/location.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/operators/BUILD.bazel (80%) rename vendor/{github.com/google => cel.dev}/cel-go/common/operators/operators.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/overloads/BUILD.bazel (80%) rename vendor/{github.com/google => cel.dev}/cel-go/common/overloads/overloads.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/runes/BUILD.bazel (87%) rename vendor/{github.com/google => cel.dev}/cel-go/common/runes/buffer.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/source.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/stdlib/BUILD.bazel (91%) rename vendor/{github.com/google => cel.dev}/cel-go/common/stdlib/standard.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/BUILD.bazel (96%) create mode 100644 vendor/cel.dev/cel-go/common/types/aggregate_sizer.go rename vendor/{github.com/google => cel.dev}/cel-go/common/types/any_value.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/bool.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/bytes.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/compare.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/doc.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/double.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/duration.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/err.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/format.go (91%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/int.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/iterator.go (94%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/json_value.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/list.go (93%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/map.go (95%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/native.go (96%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/null.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/object.go (92%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/optional.go (92%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/overflow.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/pb/BUILD.bazel (96%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/pb/checked.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/pb/enum.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/pb/equal.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/pb/file.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/pb/pb.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/pb/type.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/provider.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/ref/BUILD.bazel (89%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/ref/provider.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/ref/reference.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/regex.go (100%) create mode 100644 vendor/cel.dev/cel-go/common/types/size_calc.go rename vendor/{github.com/google => cel.dev}/cel-go/common/types/string.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/struct.go (96%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/timestamp.go (82%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/BUILD.bazel (89%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/comparer.go (95%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/container.go (94%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/field_tester.go (95%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/indexer.go (94%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/iterator.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/lister.go (95%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/mapper.go (96%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/matcher.go (93%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/math.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/receiver.go (94%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/sizer.go (94%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/traits.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/traits/zeroer.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/types.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/uint.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/unknown.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/common/types/util.go (96%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/BUILD.bazel (96%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/activation.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/async.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/attribute_patterns.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/attributes.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/decorators.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/dispatcher.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/evalstate.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/frame.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/interpretable.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/interpreter.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/optimizations.go (94%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/planner.go (96%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/prune.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/interpreter/runtimecost.go (88%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/BUILD.bazel (94%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/errors.go (97%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/BUILD.bazel (90%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/CEL.g4 (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/CEL.interp (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/CEL.tokens (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/CELLexer.interp (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/CELLexer.tokens (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/cel_base_listener.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/cel_base_visitor.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/cel_lexer.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/cel_listener.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/cel_parser.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/cel_visitor.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/doc.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/gen/generate.sh (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/helper.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/input.go (98%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/macro.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/options.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/parser.go (99%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/unescape.go (100%) rename vendor/{github.com/google => cel.dev}/cel-go/parser/unparser.go (99%) delete mode 100644 vendor/github.com/emicklei/go-restful/v3/.travis.yml create mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated.go delete mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go delete mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go create mode 100644 vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md create mode 100644 vendor/github.com/go-openapi/jsonpointer/NOTICE create mode 100644 vendor/github.com/go-openapi/jsonpointer/SECURITY.md create mode 100644 vendor/github.com/go-openapi/jsonpointer/ifaces.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/jsonname/doc.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/jsonname/go_name_provider.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/jsonname/ifaces.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/jsonname/name_provider.go create mode 100644 vendor/github.com/go-openapi/jsonpointer/options.go create mode 100644 vendor/github.com/go-openapi/jsonreference/.editorconfig create mode 100644 vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md create mode 100644 vendor/github.com/go-openapi/jsonreference/NOTICE create mode 100644 vendor/github.com/go-openapi/jsonreference/SECURITY.md create mode 100644 vendor/github.com/go-openapi/swag/.codecov.yml create mode 100644 vendor/github.com/go-openapi/swag/.mockery.yml create mode 100644 vendor/github.com/go-openapi/swag/CONTRIBUTORS.md create mode 100644 vendor/github.com/go-openapi/swag/SECURITY.md create mode 100644 vendor/github.com/go-openapi/swag/cmdutils/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/cmdutils/cmd_utils.go create mode 100644 vendor/github.com/go-openapi/swag/cmdutils/doc.go create mode 100644 vendor/github.com/go-openapi/swag/cmdutils_iface.go create mode 100644 vendor/github.com/go-openapi/swag/conv/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/conv/convert.go create mode 100644 vendor/github.com/go-openapi/swag/conv/convert_types.go create mode 100644 vendor/github.com/go-openapi/swag/conv/doc.go create mode 100644 vendor/github.com/go-openapi/swag/conv/format.go create mode 100644 vendor/github.com/go-openapi/swag/conv/sizeof.go create mode 100644 vendor/github.com/go-openapi/swag/conv/type_constraints.go create mode 100644 vendor/github.com/go-openapi/swag/conv_iface.go delete mode 100644 vendor/github.com/go-openapi/swag/convert.go delete mode 100644 vendor/github.com/go-openapi/swag/convert_types.go delete mode 100644 vendor/github.com/go-openapi/swag/errors.go delete mode 100644 vendor/github.com/go-openapi/swag/file.go create mode 100644 vendor/github.com/go-openapi/swag/fileutils/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/fileutils/doc.go create mode 100644 vendor/github.com/go-openapi/swag/fileutils/file.go rename vendor/github.com/go-openapi/swag/{ => fileutils}/path.go (58%) create mode 100644 vendor/github.com/go-openapi/swag/fileutils_iface.go create mode 100644 vendor/github.com/go-openapi/swag/go.work create mode 100644 vendor/github.com/go-openapi/swag/go.work.sum delete mode 100644 vendor/github.com/go-openapi/swag/initialism_index.go delete mode 100644 vendor/github.com/go-openapi/swag/json.go create mode 100644 vendor/github.com/go-openapi/swag/jsonname_iface.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/README.md create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/doc.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/doc.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/ifaces.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/registry_iface.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/registry.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/doc.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/concat.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/doc.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/json.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/ordered_map.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils_iface.go create mode 100644 vendor/github.com/go-openapi/swag/loading/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/loading/doc.go create mode 100644 vendor/github.com/go-openapi/swag/loading/errors.go create mode 100644 vendor/github.com/go-openapi/swag/loading/json.go rename vendor/github.com/go-openapi/swag/{ => loading}/loading.go (55%) create mode 100644 vendor/github.com/go-openapi/swag/loading/options.go create mode 100644 vendor/github.com/go-openapi/swag/loading/yaml.go create mode 100644 vendor/github.com/go-openapi/swag/loading_iface.go rename vendor/github.com/go-openapi/swag/{ => mangling}/BENCHMARK.md (53%) create mode 100644 vendor/github.com/go-openapi/swag/mangling/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/mangling/doc.go create mode 100644 vendor/github.com/go-openapi/swag/mangling/initialism_index.go create mode 100644 vendor/github.com/go-openapi/swag/mangling/name_lexem.go create mode 100644 vendor/github.com/go-openapi/swag/mangling/name_mangler.go create mode 100644 vendor/github.com/go-openapi/swag/mangling/options.go create mode 100644 vendor/github.com/go-openapi/swag/mangling/pools.go create mode 100644 vendor/github.com/go-openapi/swag/mangling/split.go rename vendor/github.com/go-openapi/swag/{ => mangling}/string_bytes.go (60%) create mode 100644 vendor/github.com/go-openapi/swag/mangling/util.go create mode 100644 vendor/github.com/go-openapi/swag/mangling_iface.go delete mode 100644 vendor/github.com/go-openapi/swag/name_lexem.go delete mode 100644 vendor/github.com/go-openapi/swag/net.go create mode 100644 vendor/github.com/go-openapi/swag/netutils/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/netutils/doc.go create mode 100644 vendor/github.com/go-openapi/swag/netutils/net.go create mode 100644 vendor/github.com/go-openapi/swag/netutils_iface.go create mode 100644 vendor/github.com/go-openapi/swag/pools/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/pools/README.md create mode 100644 vendor/github.com/go-openapi/swag/pools/debug.go create mode 100644 vendor/github.com/go-openapi/swag/pools/debug_off.go create mode 100644 vendor/github.com/go-openapi/swag/pools/debug_on.go create mode 100644 vendor/github.com/go-openapi/swag/pools/doc.go create mode 100644 vendor/github.com/go-openapi/swag/pools/pools.go delete mode 100644 vendor/github.com/go-openapi/swag/split.go create mode 100644 vendor/github.com/go-openapi/swag/stringutils/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/stringutils/collection_formats.go create mode 100644 vendor/github.com/go-openapi/swag/stringutils/doc.go create mode 100644 vendor/github.com/go-openapi/swag/stringutils/strings.go create mode 100644 vendor/github.com/go-openapi/swag/stringutils_iface.go create mode 100644 vendor/github.com/go-openapi/swag/typeutils/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/typeutils/doc.go create mode 100644 vendor/github.com/go-openapi/swag/typeutils/types.go create mode 100644 vendor/github.com/go-openapi/swag/typeutils_iface.go delete mode 100644 vendor/github.com/go-openapi/swag/util.go delete mode 100644 vendor/github.com/go-openapi/swag/yaml.go create mode 100644 vendor/github.com/go-openapi/swag/yamlutils/LICENSE create mode 100644 vendor/github.com/go-openapi/swag/yamlutils/doc.go create mode 100644 vendor/github.com/go-openapi/swag/yamlutils/errors.go create mode 100644 vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go create mode 100644 vendor/github.com/go-openapi/swag/yamlutils/yaml.go create mode 100644 vendor/github.com/go-openapi/swag/yamlutils_iface.go create mode 100644 vendor/github.com/google/go-containerregistry/internal/ipaddr/ipaddr.go delete mode 100644 vendor/github.com/josharian/intern/README.md delete mode 100644 vendor/github.com/josharian/intern/intern.go delete mode 100644 vendor/github.com/josharian/intern/license.md create mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_arm64.go create mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_arm64.s create mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_asm.go delete mode 100644 vendor/github.com/mailru/easyjson/LICENSE delete mode 100644 vendor/github.com/mailru/easyjson/buffer/pool.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/error.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/lexer.go delete mode 100644 vendor/github.com/mailru/easyjson/jwriter/writer.go create mode 100644 vendor/github.com/prometheus/common/expfmt/openmetrics_2_0_create.go delete mode 100644 vendor/github.com/sirupsen/logrus/.travis.yml create mode 100644 vendor/github.com/sirupsen/logrus/level.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_js.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_wasi.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go create mode 100644 vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/strip_descriptions.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/callee.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/imports.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/map.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/ui.go create mode 100644 vendor/golang.org/x/tools/internal/moremaps/maps.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/common.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/coretype.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/free.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/normalize.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/termlist.go delete mode 100644 vendor/golang.org/x/tools/internal/typeparams/typeterm.go create mode 100644 vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/refcounted.go delete mode 100644 vendor/gopkg.in/yaml.v3/LICENSE delete mode 100644 vendor/gopkg.in/yaml.v3/README.md delete mode 100644 vendor/gopkg.in/yaml.v3/apic.go delete mode 100644 vendor/gopkg.in/yaml.v3/decode.go delete mode 100644 vendor/gopkg.in/yaml.v3/emitterc.go delete mode 100644 vendor/gopkg.in/yaml.v3/encode.go delete mode 100644 vendor/gopkg.in/yaml.v3/parserc.go delete mode 100644 vendor/gopkg.in/yaml.v3/readerc.go delete mode 100644 vendor/gopkg.in/yaml.v3/resolve.go delete mode 100644 vendor/gopkg.in/yaml.v3/scannerc.go delete mode 100644 vendor/gopkg.in/yaml.v3/sorter.go delete mode 100644 vendor/gopkg.in/yaml.v3/writerc.go delete mode 100644 vendor/gopkg.in/yaml.v3/yaml.go delete mode 100644 vendor/gopkg.in/yaml.v3/yamlh.go delete mode 100644 vendor/gopkg.in/yaml.v3/yamlprivateh.go create mode 100644 vendor/k8s.io/apimachinery/pkg/api/validate/dependentrequired.go create mode 100644 vendor/k8s.io/apimachinery/pkg/api/validate/errors.go create mode 100644 vendor/k8s.io/apimachinery/pkg/api/validate/monotonic.go rename vendor/{gopkg.in/yaml.v3/NOTICE => k8s.io/apimachinery/pkg/apis/meta/v1/validation/doc.go} (68%) create mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/zz_generated.validations.go create mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_126.go create mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_127.go create mode 100644 vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/collections.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go rename vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/{ => jsontext}/pools.go (64%) create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go rename vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/{ => jsontext}/state.go (63%) rename vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/{ => jsontext}/token.go (87%) create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/migrate.sh create mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go delete mode 100644 vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go diff --git a/go.mod b/go.mod index 64812eab..f5f886df 100644 --- a/go.mod +++ b/go.mod @@ -1,27 +1,28 @@ module github.com/tektoncd/pruner -go 1.26.4 +go 1.27.0 // Retract v0.3.2 as it was an unintended release retract v0.3.2 require ( github.com/stretchr/testify v1.12.1 - github.com/tektoncd/pipeline v1.16.0 + github.com/tektoncd/pipeline v1.17.0 github.com/tektoncd/plumbing v0.0.0-20250805154627-25448098dea2 go.opentelemetry.io/otel v1.46.0 go.opentelemetry.io/otel/metric v1.46.0 go.uber.org/zap v1.28.0 k8s.io/api v0.35.9 - k8s.io/apimachinery v0.36.5 + k8s.io/apimachinery v0.37.1 k8s.io/client-go v0.35.9 k8s.io/code-generator v0.35.9 - k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a - k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 + k8s.io/kube-openapi v0.0.0-20260821135717-be32def86098 + k8s.io/utils v0.0.0-20260626114624-be93311217bd knative.dev/pkg v0.0.0-20260622140654-39ebae2ee2dc ) require ( + cel.dev/cel-go v0.32.0 // indirect cel.dev/expr v0.25.2 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -30,30 +31,38 @@ require ( github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/docker/cli v29.6.2+incompatible // indirect + github.com/docker/cli v29.7.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.5 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/felixge/httpsnoop v1.1.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.1 // indirect github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.1 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/google/cel-go v0.31.0 // indirect + github.com/go-openapi/jsonpointer v1.0.0 // indirect + github.com/go-openapi/jsonreference v1.0.0 // indirect + github.com/go-openapi/swag v0.27.1 // indirect + github.com/go-openapi/swag/cmdutils v0.27.1 // indirect + github.com/go-openapi/swag/conv v0.27.1 // indirect + github.com/go-openapi/swag/fileutils v0.27.1 // indirect + github.com/go-openapi/swag/jsonutils v0.27.1 // indirect + github.com/go-openapi/swag/loading v0.27.1 // indirect + github.com/go-openapi/swag/mangling v0.27.1 // indirect + github.com/go-openapi/swag/netutils v0.27.1 // indirect + github.com/go-openapi/swag/pools v0.27.1 // indirect + github.com/go-openapi/swag/stringutils v0.27.1 // indirect + github.com/go-openapi/swag/typeutils v0.27.1 // indirect + github.com/go-openapi/swag/yamlutils v0.27.1 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/go-containerregistry v0.21.9 // indirect + github.com/google/go-containerregistry v0.22.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.19.1 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/klauspost/compress v1.19.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -61,11 +70,11 @@ require ( github.com/opencontainers/image-spec v1.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.70.1 // indirect + github.com/prometheus/client_model v0.6.3 // indirect + github.com/prometheus/common v0.71.0 // indirect github.com/prometheus/otlptranslator v1.0.0 // indirect github.com/prometheus/procfs v0.21.0 // indirect - github.com/sirupsen/logrus v1.9.4 // indirect + github.com/sirupsen/logrus v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect @@ -87,29 +96,28 @@ require ( go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect golang.org/x/exp v0.0.0-20250808145144-a408d31f581a // indirect - golang.org/x/mod v0.38.0 // indirect + golang.org/x/mod v0.41.0 // indirect golang.org/x/net v0.58.0 // indirect - golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.22.0 // indirect - golang.org/x/sys v0.47.0 // indirect - golang.org/x/term v0.45.0 // indirect - golang.org/x/text v0.41.0 // indirect + golang.org/x/oauth2 v0.37.0 // indirect + golang.org/x/sync v0.23.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/term v0.46.0 // indirect + golang.org/x/text v0.42.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.48.0 // indirect + golang.org/x/tools v0.49.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260727163830-6c54dddc4772 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260720155508-bb71a54f79dc // indirect - google.golang.org/grpc v1.83.2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 // indirect + google.golang.org/grpc v1.84.0 // indirect google.golang.org/protobuf v1.36.12 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.2 // indirect - k8s.io/apiextensions-apiserver v0.35.8 // indirect + k8s.io/apiextensions-apiserver v0.35.9 // indirect k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect k8s.io/klog/v2 v2.140.0 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.3 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/go.sum b/go.sum index 430675e0..d68f1321 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +cel.dev/cel-go v0.32.0 h1:irvpFKr5EuGPyxeME03ERh0rii1TX+BDAnB9eL3IvNk= +cel.dev/cel-go v0.32.0/go.mod h1:DnVip7tpJSsgZymwfT+m1tnEVy3ivAjSMXPx12YrMkU= cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs= cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= github.com/allegro/bigcache/v3 v3.2.0 h1:B45F9x3iaoBlhzIA+0jqxlThTUoyg+mOk7HUKSbJOL8= @@ -20,20 +22,20 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v29.6.2+incompatible h1:/bjePvcbbFTnRrMfWJBY7AjfICdsiLVgHn6LwTVOcqw= -github.com/docker/cli v29.6.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v29.7.2+incompatible h1:dlkwallR8XqfeVnA2ELEhdwvb4lsSwuB4IgsG8Q9cLY= +github.com/docker/cli v29.7.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY= github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -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/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= +github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= +github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= +github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -41,22 +43,48 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= -github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s= +github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= +github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY= +github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0= +github.com/go-openapi/swag v0.27.1 h1:VotvOLWW8q/EAxB0YdsBBGC8XYyeL1YwBj2ungAGPNg= +github.com/go-openapi/swag v0.27.1/go.mod h1:GTkJPwHfhJp6MWr4/rCh64HVI3Ofu+tcsbfjfHmTxpE= +github.com/go-openapi/swag/cmdutils v0.27.1 h1:I7sYqaWVl5mq0NEmNQkAmFDyNin9ufvMX/p2zwtQaOE= +github.com/go-openapi/swag/cmdutils v0.27.1/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= +github.com/go-openapi/swag/conv v0.27.1 h1:8wi9ZG+olmY1wXphl93EWniPtbSPkXM/feH7FgjsvrU= +github.com/go-openapi/swag/conv v0.27.1/go.mod h1:QbqMivkpKhC3g1B1GGGOJ6ANewI3S62dbzYu3Duowqs= +github.com/go-openapi/swag/fileutils v0.27.1 h1:QQqBSoi5mW4XpU85nS0mLcA+zAE6vLzrb0QkmLKf9oM= +github.com/go-openapi/swag/fileutils v0.27.1/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= +github.com/go-openapi/swag/jsonutils v0.27.1 h1:SVgK3i4USzCU5mibOOS/l4ea2h9UQXy7J7RNLTjuXjU= +github.com/go-openapi/swag/jsonutils v0.27.1/go.mod h1:tdlEpZqdcQ17uj6J4YdK9vd8It5qWMwjWXOs0tjpRlk= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1 h1:mJu3COL9WEaZVp/Kf2PRMi7tPszPEJfSr/OO75ynCs8= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= +github.com/go-openapi/swag/loading v0.27.1 h1:/DxUgDXKbBX4bcn7r9uEXfJyzN5XpiJmZplzQTjrRCY= +github.com/go-openapi/swag/loading v0.27.1/go.mod h1:jvGh3iA2+zyUUycB5fgJWzeHnhrpvGnJJM0RVE9ZShE= +github.com/go-openapi/swag/mangling v0.27.1 h1:yC9D0HyUE8gbP+BfmGx9+AA89ikwZTMjESK3OnnoaqA= +github.com/go-openapi/swag/mangling v0.27.1/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= +github.com/go-openapi/swag/netutils v0.27.1 h1:mICMFoS82F5TZ4Zy3cqmcQk+BFeCp3Uyq3Np7GI0/qU= +github.com/go-openapi/swag/netutils v0.27.1/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= +github.com/go-openapi/swag/pools v0.27.1 h1:9LeadcMyb2GJCbXX5hVQDbZ2Lq9TL4dCs/nx1j5DO0E= +github.com/go-openapi/swag/pools v0.27.1/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE= +github.com/go-openapi/swag/stringutils v0.27.1 h1:ZXePZ0r2p1qSjo8tD3Un4vFj8+FqlCkczxDrJIhYUp8= +github.com/go-openapi/swag/stringutils v0.27.1/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= +github.com/go-openapi/swag/typeutils v0.27.1 h1:KSTdFlfnse4r6dP9IrEnwMldjE+zs71UeEB3//PtVXc= +github.com/go-openapi/swag/typeutils v0.27.1/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= +github.com/go-openapi/swag/yamlutils v0.27.1 h1:ftxv6xvXb1E3zohUc+okZ9nSqNb9StQX/FXnKZ98sQA= +github.com/go-openapi/swag/yamlutils v0.27.1/go.mod h1:bnxFIB1qewGRiZHypXGZ3fNgf13/0HfRgnS/iZBDrOo= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= +github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= +github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.31.0 h1:H0bhpFTqOvmHrBGrWKp7ZlhBm5Hh8PYUEXnwxT1LL7A= -github.com/google/cel-go v0.31.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-containerregistry v0.21.9 h1:F+D4uZ3iA3DLMJLfhaqMdHJbzeqm/216WGQq2dokuLs= -github.com/google/go-containerregistry v0.21.9/go.mod h1:dP5XNKcL7kMFF/TB3LfvWmVhAcv7iqkHb3oDK8aauTo= +github.com/google/go-containerregistry v0.22.1 h1:RZuuSYhTvlDvtsK+NkutoCZ//C0X2ebLK8X8l3ULs84= +github.com/google/go-containerregistry v0.22.1/go.mod h1:bJR35SK8XgisYmhg/FMQ/5RK0S/XrOAqLBV5/LR2XE0= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -64,22 +92,14 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF2 github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= -github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= +github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -102,18 +122,16 @@ github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY= -github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc= +github.com/prometheus/client_model v0.6.3 h1:O0jaTVAYNxTHYInEPFJt5I3+sN8zqBtVMPTB1qyxiEo= +github.com/prometheus/client_model v0.6.3/go.mod h1:gpN5P9S7Rr6Yr92PiQ+Ixvhf6JZEkF1dnxsYL2aPBEM= +github.com/prometheus/common v0.71.0 h1:9KDAKb7Mj3HEVKyFCK6Dc/HIwlBzZIN2l7/lrHl3KK8= +github.com/prometheus/common v0.71.0/go.mod h1:CLJ5H8TEsGX8bl31BdMkfhIZ+QmZ9tBPPotUxUbfcmk= github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= github.com/prometheus/procfs v0.21.0 h1:Qh/e6TlBjZf+XLLqNCqFGmCU6Kj/2Bu7kj3oAc0UnXc= github.com/prometheus/procfs v0.21.0/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= -github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/sirupsen/logrus v1.10.2 h1:G2SED73/qrAu6YwbdxOD6peLkCBI3z7L+ykJFTXJBBo= +github.com/sirupsen/logrus v1.10.2/go.mod h1:SLEg8TqYulVKKfIGHldVp2K2aYz2DKSVBq4g/H5bR7Q= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -122,8 +140,8 @@ github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+Q github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= -github.com/tektoncd/pipeline v1.16.0 h1:J5RXmYft5Tljjvn+WV0zdfdh7paNw0eh8y6UCqZRNn0= -github.com/tektoncd/pipeline v1.16.0/go.mod h1:s0AvpOqeqnD8i30nG9H6V4cf01OkG3QBNDzueKpzh+A= +github.com/tektoncd/pipeline v1.17.0 h1:6bD9k0Ww0Smx+Z9ZtNL5rVV63hPDE1VekIqoGuB6EyM= +github.com/tektoncd/pipeline v1.17.0/go.mod h1:lvmLBtFgntABke/RviX6BnFgnC2HeNsGB7DTa8sl5Ok= github.com/tektoncd/plumbing v0.0.0-20250805154627-25448098dea2 h1:v4UPEbe6MEto5i4ELtiXWBxUAUIAWL5U1DznfPhi4WE= github.com/tektoncd/plumbing v0.0.0-20250805154627-25448098dea2/go.mod h1:BC6F3DlZc+wpUT9YcwG9MoSfb4tUiH2olB9xYoIsB4I= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -179,24 +197,24 @@ go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/exp v0.0.0-20250808145144-a408d31f581a h1:Y+7uR/b1Mw2iSXZ3G//1haIiSElDQZ8KWh0h+sZPG90= golang.org/x/exp v0.0.0-20250808145144-a408d31f581a/go.mod h1:rT6SFzZ7oxADUDx58pcaKFTcZ+inxAa9fTrYx/uVYwg= -golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= -golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= +golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c= +golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o= golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= -golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= -golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= -golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= -golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= -golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= -golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= -golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98= +golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= +golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE= +golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= -golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= -golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= +golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= +golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= @@ -207,29 +225,24 @@ gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/genproto/googleapis/api v0.0.0-20260727163830-6c54dddc4772 h1:4namukbyF7JY83aWHQwi9J5ugNTnDReLJ9ZcpqOpRB4= google.golang.org/genproto/googleapis/api v0.0.0-20260727163830-6c54dddc4772/go.mod h1:1brfde68Npq6+WA75c1EHWPijZEG1kMus61ygPZfn4A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260720155508-bb71a54f79dc h1:3TtNq/QbJNrSY1nVdjcikfBw6ujnaNbdrd88wNr1OW4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260720155508-bb71a54f79dc/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= -google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 h1:cYNAzI2sUwhmCcoj9TxvihSrqsxt6uIkj3rDRhSDmW4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA= +google.golang.org/grpc v1.84.0 h1:soMyaPJ8pAak5PIQ0DGBUir0XRo2fRoMqhNWMLlLxO0= +google.golang.org/grpc v1.84.0/go.mod h1:ljCht0DrxQrXBDRTZp52Qxh3Ffk8CdYm2sj4O2QN2C0= google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= k8s.io/api v0.35.9 h1:lF426irCSwVKeukmRgeTMJtHVIETx2+3HLfoslTv9Xg= k8s.io/api v0.35.9/go.mod h1:MNhexKzNrNryBqZMWLx6p6L2rFOAs3PWRdMnKU3Gmjk= -k8s.io/apiextensions-apiserver v0.35.8 h1:2lvyZ28M01/1uOPftaPXIbsOaCslzKHTEcdCjCI0VRE= -k8s.io/apiextensions-apiserver v0.35.8/go.mod h1:/ZbM1upeajFY5yHqGMKEzWTLb5Tx3kU2SkxTCtqB4Uw= -k8s.io/apimachinery v0.36.5 h1:X5Xbg6G4om0ma6LOcGbmUmo+B5Nq7mmIpAWhk+tgCh8= -k8s.io/apimachinery v0.36.5/go.mod h1:oPTSicSaDHDdoGwOs5DFPo6YS2wdTnzFHIYMEglfJ7I= +k8s.io/apiextensions-apiserver v0.35.9 h1:hrM6tdHDLWEeFsUhKPlWTYQKnDBLxuD1Vmz4K6M13Rc= +k8s.io/apiextensions-apiserver v0.35.9/go.mod h1:Rwt6GFUIFCnx9Ps05vQ9rPIj74si/0pW1S4RI2El/PI= +k8s.io/apimachinery v0.37.1 h1:hGCYyvKHCwtwMitj2vU4vYx0Z16N9GyZk9BBnz0wDAE= +k8s.io/apimachinery v0.37.1/go.mod h1:jF84AyUi/IRIXRot5f+lm6MpxoWI+F1XgjaMmwCdTFw= k8s.io/client-go v0.35.9 h1:bOoC16aL38hB6ePadnJCUsQhiySI/trrfOGcusyCiBE= k8s.io/client-go v0.35.9/go.mod h1:pXK/J0aGxq+dUNVNktU39YJOseQ7MprpMma3Gufidxo= k8s.io/code-generator v0.35.9 h1:t3lwkYcG22609Kcr97FSlCEgCK0peYgG/zcQ5JSWHyc= @@ -238,17 +251,17 @@ k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYo k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= -k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +k8s.io/kube-openapi v0.0.0-20260821135717-be32def86098 h1:z5+pcu1jTyKK5mNTe2/+x+U6Uuv9jRVOJQLaBJJMpeI= +k8s.io/kube-openapi v0.0.0-20260821135717-be32def86098/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I= +k8s.io/utils v0.0.0-20260626114624-be93311217bd h1:Ea7fgQ5we8Y9T0OX5o0dAHzQOBRI07D/dEYRaB9ZZEs= +k8s.io/utils v0.0.0-20260626114624-be93311217bd/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= knative.dev/pkg v0.0.0-20260622140654-39ebae2ee2dc h1:i2GrJuRdTFd4sNWocwefVGwuSOkOPjtadEWRTiGsEOY= knative.dev/pkg v0.0.0-20260622140654-39ebae2ee2dc/go.mod h1:Ve19ZYW7DwIfQL4oCT9t9zmPp4egv0KacKVPXUcivDQ= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.3 h1:u08YRbVUi59ri4YD6cg0UqNM4Dimn0sIl+wldcx5PYw= -sigs.k8s.io/structured-merge-diff/v6 v6.3.3/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/vendor/github.com/google/cel-go/LICENSE b/vendor/cel.dev/cel-go/LICENSE similarity index 100% rename from vendor/github.com/google/cel-go/LICENSE rename to vendor/cel.dev/cel-go/LICENSE diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/cel.dev/cel-go/cel/BUILD.bazel similarity index 98% rename from vendor/github.com/google/cel-go/cel/BUILD.bazel rename to vendor/cel.dev/cel-go/cel/BUILD.bazel index 62a56036..c42612e1 100644 --- a/vendor/github.com/google/cel-go/cel/BUILD.bazel +++ b/vendor/cel.dev/cel-go/cel/BUILD.bazel @@ -23,7 +23,7 @@ go_library( "validator.go", ], embedsrcs = ["templates/authoring.tmpl"], - importpath = "github.com/google/cel-go/cel", + importpath = "cel.dev/cel-go/cel", visibility = ["//visibility:public"], deps = [ "//cel/async:go_default_library", diff --git a/vendor/github.com/google/cel-go/cel/async/BUILD.bazel b/vendor/cel.dev/cel-go/cel/async/BUILD.bazel similarity index 93% rename from vendor/github.com/google/cel-go/cel/async/BUILD.bazel rename to vendor/cel.dev/cel-go/cel/async/BUILD.bazel index 85b28bcd..e77dfaec 100644 --- a/vendor/github.com/google/cel-go/cel/async/BUILD.bazel +++ b/vendor/cel.dev/cel-go/cel/async/BUILD.bazel @@ -9,7 +9,7 @@ go_library( srcs = [ "async.go", ], - importpath = "github.com/google/cel-go/cel/async", + importpath = "cel.dev/cel-go/cel/async", visibility = ["//visibility:public"], deps = [ "//common/decls:go_default_library", diff --git a/vendor/github.com/google/cel-go/cel/async/async.go b/vendor/cel.dev/cel-go/cel/async/async.go similarity index 97% rename from vendor/github.com/google/cel-go/cel/async/async.go rename to vendor/cel.dev/cel-go/cel/async/async.go index a011114b..b8621a78 100644 --- a/vendor/github.com/google/cel-go/cel/async/async.go +++ b/vendor/cel.dev/cel-go/cel/async/async.go @@ -21,11 +21,11 @@ import ( "errors" "time" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/interpreter" ) // Call describes a pending or completed asynchronous function call. diff --git a/vendor/github.com/google/cel-go/cel/cel.go b/vendor/cel.dev/cel-go/cel/cel.go similarity index 100% rename from vendor/github.com/google/cel-go/cel/cel.go rename to vendor/cel.dev/cel-go/cel/cel.go diff --git a/vendor/github.com/google/cel-go/cel/decls.go b/vendor/cel.dev/cel-go/cel/decls.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/decls.go rename to vendor/cel.dev/cel-go/cel/decls.go index 53941146..1cc3f7b5 100644 --- a/vendor/github.com/google/cel-go/cel/decls.go +++ b/vendor/cel.dev/cel-go/cel/decls.go @@ -17,11 +17,11 @@ package cel import ( "fmt" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" celpb "cel.dev/expr" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" diff --git a/vendor/github.com/google/cel-go/cel/env.go b/vendor/cel.dev/cel-go/cel/env.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/env.go rename to vendor/cel.dev/cel-go/cel/env.go index 794c62f7..772b0da4 100644 --- a/vendor/github.com/google/cel-go/cel/env.go +++ b/vendor/cel.dev/cel-go/cel/env.go @@ -23,19 +23,19 @@ import ( "strings" "sync" - "github.com/google/cel-go/checker" - chkdecls "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common" - celast "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/env" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/stdlib" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter" - "github.com/google/cel-go/parser" + "cel.dev/cel-go/checker" + chkdecls "cel.dev/cel-go/checker/decls" + "cel.dev/cel-go/common" + celast "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/env" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/stdlib" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/interpreter" + "cel.dev/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" "google.golang.org/protobuf/reflect/protoreflect" diff --git a/vendor/github.com/google/cel-go/cel/fieldpaths.go b/vendor/cel.dev/cel-go/cel/fieldpaths.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/fieldpaths.go rename to vendor/cel.dev/cel-go/cel/fieldpaths.go index 570fce3a..b63c2ba2 100644 --- a/vendor/github.com/google/cel-go/cel/fieldpaths.go +++ b/vendor/cel.dev/cel-go/cel/fieldpaths.go @@ -4,8 +4,8 @@ import ( "slices" "strings" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/types" ) // fieldPath represents a selection path to a field from a variable in a CEL environment. diff --git a/vendor/github.com/google/cel-go/cel/folding.go b/vendor/cel.dev/cel-go/cel/folding.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/folding.go rename to vendor/cel.dev/cel-go/cel/folding.go index e3459034..e45dc609 100644 --- a/vendor/github.com/google/cel-go/cel/folding.go +++ b/vendor/cel.dev/cel-go/cel/folding.go @@ -19,12 +19,12 @@ import ( "errors" "fmt" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) // ConstantFoldingOption defines a functional option for configuring constant folding. diff --git a/vendor/github.com/google/cel-go/cel/inlining.go b/vendor/cel.dev/cel-go/cel/inlining.go similarity index 97% rename from vendor/github.com/google/cel-go/cel/inlining.go rename to vendor/cel.dev/cel-go/cel/inlining.go index d9a5e89a..3ade2204 100644 --- a/vendor/github.com/google/cel-go/cel/inlining.go +++ b/vendor/cel.dev/cel-go/cel/inlining.go @@ -15,12 +15,12 @@ package cel import ( - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/traits" ) // InlineVariable holds a variable name to be matched and an AST representing diff --git a/vendor/github.com/google/cel-go/cel/io.go b/vendor/cel.dev/cel-go/cel/io.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/io.go rename to vendor/cel.dev/cel-go/cel/io.go index c991c95c..31aa304f 100644 --- a/vendor/github.com/google/cel-go/cel/io.go +++ b/vendor/cel.dev/cel-go/cel/io.go @@ -21,12 +21,12 @@ import ( "google.golang.org/protobuf/proto" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" - "github.com/google/cel-go/parser" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" + "cel.dev/cel-go/parser" celpb "cel.dev/expr" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" diff --git a/vendor/github.com/google/cel-go/cel/library.go b/vendor/cel.dev/cel-go/cel/library.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/library.go rename to vendor/cel.dev/cel-go/cel/library.go index 43912eaa..eb0c9562 100644 --- a/vendor/github.com/google/cel-go/cel/library.go +++ b/vendor/cel.dev/cel-go/cel/library.go @@ -18,18 +18,18 @@ import ( "fmt" "math" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/env" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/stdlib" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" - "github.com/google/cel-go/interpreter" - "github.com/google/cel-go/parser" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/env" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/stdlib" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" + "cel.dev/cel-go/interpreter" + "cel.dev/cel-go/parser" ) const ( diff --git a/vendor/github.com/google/cel-go/cel/macro.go b/vendor/cel.dev/cel-go/cel/macro.go similarity index 99% rename from vendor/github.com/google/cel-go/cel/macro.go rename to vendor/cel.dev/cel-go/cel/macro.go index 3d3c5be1..aed4a8da 100644 --- a/vendor/github.com/google/cel-go/cel/macro.go +++ b/vendor/cel.dev/cel-go/cel/macro.go @@ -17,10 +17,10 @@ package cel import ( "fmt" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/parser" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff --git a/vendor/github.com/google/cel-go/cel/optimizer.go b/vendor/cel.dev/cel-go/cel/optimizer.go similarity index 99% rename from vendor/github.com/google/cel-go/cel/optimizer.go rename to vendor/cel.dev/cel-go/cel/optimizer.go index 6e260a93..5c284655 100644 --- a/vendor/github.com/google/cel-go/cel/optimizer.go +++ b/vendor/cel.dev/cel-go/cel/optimizer.go @@ -18,10 +18,10 @@ import ( "fmt" "sort" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // StaticOptimizer contains a sequence of ASTOptimizer instances which will be applied in order. diff --git a/vendor/github.com/google/cel-go/cel/options.go b/vendor/cel.dev/cel-go/cel/options.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/options.go rename to vendor/cel.dev/cel-go/cel/options.go index 709ce007..21cdb361 100644 --- a/vendor/github.com/google/cel-go/cel/options.go +++ b/vendor/cel.dev/cel-go/cel/options.go @@ -24,17 +24,17 @@ import ( "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/dynamicpb" - "github.com/google/cel-go/cel/async" - "github.com/google/cel-go/checker" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/env" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/pb" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter" - "github.com/google/cel-go/parser" + "cel.dev/cel-go/cel/async" + "cel.dev/cel-go/checker" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/env" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/pb" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/interpreter" + "cel.dev/cel-go/parser" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" descpb "google.golang.org/protobuf/types/descriptorpb" diff --git a/vendor/github.com/google/cel-go/cel/program.go b/vendor/cel.dev/cel-go/cel/program.go similarity index 98% rename from vendor/github.com/google/cel-go/cel/program.go rename to vendor/cel.dev/cel-go/cel/program.go index 07849974..b6df752e 100644 --- a/vendor/github.com/google/cel-go/cel/program.go +++ b/vendor/cel.dev/cel-go/cel/program.go @@ -20,13 +20,13 @@ import ( "fmt" "time" - "github.com/google/cel-go/cel/async" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/interpreter" + "cel.dev/cel-go/cel/async" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/interpreter" ) // Program is an evaluable view of an Ast. diff --git a/vendor/github.com/google/cel-go/cel/prompt.go b/vendor/cel.dev/cel-go/cel/prompt.go similarity index 97% rename from vendor/github.com/google/cel-go/cel/prompt.go rename to vendor/cel.dev/cel-go/cel/prompt.go index f5993482..e5e2acde 100644 --- a/vendor/github.com/google/cel-go/cel/prompt.go +++ b/vendor/cel.dev/cel-go/cel/prompt.go @@ -20,10 +20,10 @@ import ( "strings" "text/template" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" ) //go:embed templates/authoring.tmpl diff --git a/vendor/github.com/google/cel-go/cel/templates/authoring.tmpl b/vendor/cel.dev/cel-go/cel/templates/authoring.tmpl similarity index 100% rename from vendor/github.com/google/cel-go/cel/templates/authoring.tmpl rename to vendor/cel.dev/cel-go/cel/templates/authoring.tmpl diff --git a/vendor/github.com/google/cel-go/cel/validator.go b/vendor/cel.dev/cel-go/cel/validator.go similarity index 99% rename from vendor/github.com/google/cel-go/cel/validator.go rename to vendor/cel.dev/cel-go/cel/validator.go index 229defe7..17a999f9 100644 --- a/vendor/github.com/google/cel-go/cel/validator.go +++ b/vendor/cel.dev/cel-go/cel/validator.go @@ -20,10 +20,10 @@ import ( "reflect" "regexp" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/env" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/env" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" ) const ( diff --git a/vendor/github.com/google/cel-go/checker/BUILD.bazel b/vendor/cel.dev/cel-go/checker/BUILD.bazel similarity index 95% rename from vendor/github.com/google/cel-go/checker/BUILD.bazel rename to vendor/cel.dev/cel-go/checker/BUILD.bazel index 678b412a..7c224828 100644 --- a/vendor/github.com/google/cel-go/checker/BUILD.bazel +++ b/vendor/cel.dev/cel-go/checker/BUILD.bazel @@ -18,13 +18,14 @@ go_library( "scopes.go", "types.go", ], - importpath = "github.com/google/cel-go/checker", + importpath = "cel.dev/cel-go/checker", visibility = ["//visibility:public"], deps = [ "//checker/decls:go_default_library", "//common:go_default_library", "//common/ast:go_default_library", "//common/containers:go_default_library", + "//common/cost:go_default_library", "//common/debug:go_default_library", "//common/decls:go_default_library", "//common/operators:go_default_library", diff --git a/vendor/github.com/google/cel-go/checker/checker.go b/vendor/cel.dev/cel-go/checker/checker.go similarity index 98% rename from vendor/github.com/google/cel-go/checker/checker.go rename to vendor/cel.dev/cel-go/checker/checker.go index 42d27a42..1cffd3e5 100644 --- a/vendor/github.com/google/cel-go/checker/checker.go +++ b/vendor/cel.dev/cel-go/checker/checker.go @@ -22,13 +22,13 @@ import ( "slices" "strings" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) type checker struct { diff --git a/vendor/github.com/google/cel-go/checker/cost.go b/vendor/cel.dev/cel-go/checker/cost.go similarity index 92% rename from vendor/github.com/google/cel-go/checker/cost.go rename to vendor/cel.dev/cel-go/checker/cost.go index 3d7dd7ec..33b49805 100644 --- a/vendor/github.com/google/cel-go/checker/cost.go +++ b/vendor/cel.dev/cel-go/checker/cost.go @@ -17,11 +17,12 @@ package checker import ( "math" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/parser" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/cost" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/parser" ) // WARNING: Any changes to cost calculations in this file require a corresponding change in interpreter/runtimecost.go @@ -115,8 +116,8 @@ func FixedSizeEstimate(size uint64) SizeEstimate { // If add would result in an uint64 overflow, the result is math.MaxUint64. func (se SizeEstimate) Add(sizeEstimate SizeEstimate) SizeEstimate { return SizeEstimate{ - addUint64NoOverflow(se.Min, sizeEstimate.Min), - addUint64NoOverflow(se.Max, sizeEstimate.Max), + cost.SafeAdd(se.Min, sizeEstimate.Min), + cost.SafeAdd(se.Max, sizeEstimate.Max), } } @@ -124,8 +125,8 @@ func (se SizeEstimate) Add(sizeEstimate SizeEstimate) SizeEstimate { // If multiply would result in an uint64 overflow, the result is math.MaxUint64. func (se SizeEstimate) Multiply(sizeEstimate SizeEstimate) SizeEstimate { return SizeEstimate{ - multiplyUint64NoOverflow(se.Min, sizeEstimate.Min), - multiplyUint64NoOverflow(se.Max, sizeEstimate.Max), + cost.SafeMultiply(se.Min, sizeEstimate.Min), + cost.SafeMultiply(se.Max, sizeEstimate.Max), } } @@ -133,17 +134,17 @@ func (se SizeEstimate) Multiply(sizeEstimate SizeEstimate) SizeEstimate { // nearest integer of the result, rounded up. func (se SizeEstimate) MultiplyByCostFactor(costPerUnit float64) CostEstimate { return CostEstimate{ - multiplyByCostFactor(se.Min, costPerUnit), - multiplyByCostFactor(se.Max, costPerUnit), + cost.SafeMultiplyByFactor(se.Min, costPerUnit), + cost.SafeMultiplyByFactor(se.Max, costPerUnit), } } // MultiplyByCost multiplies by the cost and returns the product. // If multiply would result in an uint64 overflow, the result is math.MaxUint64. -func (se SizeEstimate) MultiplyByCost(cost CostEstimate) CostEstimate { +func (se SizeEstimate) MultiplyByCost(estimate CostEstimate) CostEstimate { return CostEstimate{ - multiplyUint64NoOverflow(se.Min, cost.Min), - multiplyUint64NoOverflow(se.Max, cost.Max), + cost.SafeMultiply(se.Min, estimate.Min), + cost.SafeMultiply(se.Max, estimate.Max), } } @@ -176,25 +177,25 @@ func UnknownCostEstimate() CostEstimate { } // FixedCostEstimate returns a cost with a fixed min and max range. -func FixedCostEstimate(cost uint64) CostEstimate { - return CostEstimate{Min: cost, Max: cost} +func FixedCostEstimate(fixedCost uint64) CostEstimate { + return CostEstimate{Min: fixedCost, Max: fixedCost} } // Add adds the costs and returns the sum. // If add would result in an uint64 overflow for the min or max, the value is set to math.MaxUint64. -func (ce CostEstimate) Add(cost CostEstimate) CostEstimate { +func (ce CostEstimate) Add(estimate CostEstimate) CostEstimate { return CostEstimate{ - Min: addUint64NoOverflow(ce.Min, cost.Min), - Max: addUint64NoOverflow(ce.Max, cost.Max), + Min: cost.SafeAdd(ce.Min, estimate.Min), + Max: cost.SafeAdd(ce.Max, estimate.Max), } } // Multiply multiplies by the cost and returns the product. // If multiply would result in an uint64 overflow, the result is math.MaxUint64. -func (ce CostEstimate) Multiply(cost CostEstimate) CostEstimate { +func (ce CostEstimate) Multiply(estimate CostEstimate) CostEstimate { return CostEstimate{ - Min: multiplyUint64NoOverflow(ce.Min, cost.Min), - Max: multiplyUint64NoOverflow(ce.Max, cost.Max), + Min: cost.SafeMultiply(ce.Min, estimate.Min), + Max: cost.SafeMultiply(ce.Max, estimate.Max), } } @@ -202,8 +203,8 @@ func (ce CostEstimate) Multiply(cost CostEstimate) CostEstimate { // nearest integer of the result, rounded up. func (ce CostEstimate) MultiplyByCostFactor(costPerUnit float64) CostEstimate { return CostEstimate{ - Min: multiplyByCostFactor(ce.Min, costPerUnit), - Max: multiplyByCostFactor(ce.Max, costPerUnit), + Min: cost.SafeMultiplyByFactor(ce.Min, costPerUnit), + Max: cost.SafeMultiplyByFactor(ce.Max, costPerUnit), } } @@ -219,37 +220,6 @@ func (ce CostEstimate) Union(size CostEstimate) CostEstimate { return result } -// addUint64NoOverflow adds non-negative ints. If the result is exceeds math.MaxUint64, math.MaxUint64 -// is returned. -func addUint64NoOverflow(x, y uint64) uint64 { - if y > 0 && x > math.MaxUint64-y { - return math.MaxUint64 - } - return x + y -} - -// multiplyUint64NoOverflow multiplies non-negative ints. If the result is exceeds math.MaxUint64, math.MaxUint64 -// is returned. -func multiplyUint64NoOverflow(x, y uint64) uint64 { - if y != 0 && x > math.MaxUint64/y { - return math.MaxUint64 - } - return x * y -} - -// multiplyByFactor multiplies an integer by a cost factor float and returns the nearest integer value, rounded up. -func multiplyByCostFactor(x uint64, y float64) uint64 { - xFloat := float64(x) - if xFloat > 0 && y > 0 && xFloat > math.MaxUint64/y { - return math.MaxUint64 - } - ceil := math.Ceil(xFloat * y) - if ceil >= doubleTwoTo64 { - return math.MaxUint64 - } - return uint64(ceil) -} - // CostOption configures flags which affect cost computations. type CostOption func(*coster) error @@ -465,32 +435,32 @@ func (c *coster) cost(e ast.Expr) CostEstimate { if e == nil { return CostEstimate{} } - var cost CostEstimate + var estimate CostEstimate switch e.Kind() { case ast.LiteralKind: - cost = constCost + estimate = constCost case ast.IdentKind: - cost = c.costIdent(e) + estimate = c.costIdent(e) case ast.SelectKind: - cost = c.costSelect(e) + estimate = c.costSelect(e) case ast.CallKind: - cost = c.costCall(e) + estimate = c.costCall(e) case ast.ListKind: - cost = c.costCreateList(e) + estimate = c.costCreateList(e) case ast.MapKind: - cost = c.costCreateMap(e) + estimate = c.costCreateMap(e) case ast.StructKind: - cost = c.costCreateStruct(e) + estimate = c.costCreateStruct(e) case ast.ComprehensionKind: if c.isBind(e) { - cost = c.costBind(e) + estimate = c.costBind(e) } else { - cost = c.costComprehension(e) + estimate = c.costComprehension(e) } default: return CostEstimate{} } - return cost + return estimate } func (c *coster) costIdent(e ast.Expr) CostEstimate { @@ -1013,14 +983,14 @@ func computeExprSize(expr ast.Expr) *SizeEstimate { default: return nil } - cost := FixedSizeEstimate(v) - return &cost + size := FixedSizeEstimate(v) + return &size } func computeTypeSize(t *types.Type) *SizeEstimate { if isScalar(t) { - cost := FixedSizeEstimate(1) - return &cost + size := FixedSizeEstimate(1) + return &size } return nil } @@ -1041,8 +1011,6 @@ func isScalar(t *types.Type) bool { } var ( - doubleTwoTo64 = math.Ldexp(1.0, 64) - unknownSizeEstimate = SizeEstimate{Min: 0, Max: math.MaxUint64} unknownCostEstimate = unknownSizeEstimate.MultiplyByCostFactor(1) diff --git a/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel b/vendor/cel.dev/cel-go/checker/decls/BUILD.bazel similarity index 89% rename from vendor/github.com/google/cel-go/checker/decls/BUILD.bazel rename to vendor/cel.dev/cel-go/checker/decls/BUILD.bazel index a6b0be29..fe538016 100644 --- a/vendor/github.com/google/cel-go/checker/decls/BUILD.bazel +++ b/vendor/cel.dev/cel-go/checker/decls/BUILD.bazel @@ -10,7 +10,7 @@ go_library( srcs = [ "decls.go", ], - importpath = "github.com/google/cel-go/checker/decls", + importpath = "cel.dev/cel-go/checker/decls", deps = [ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//types/known/emptypb:go_default_library", diff --git a/vendor/github.com/google/cel-go/checker/decls/decls.go b/vendor/cel.dev/cel-go/checker/decls/decls.go similarity index 100% rename from vendor/github.com/google/cel-go/checker/decls/decls.go rename to vendor/cel.dev/cel-go/checker/decls/decls.go diff --git a/vendor/github.com/google/cel-go/checker/env.go b/vendor/cel.dev/cel-go/checker/env.go similarity index 98% rename from vendor/github.com/google/cel-go/checker/env.go rename to vendor/cel.dev/cel-go/checker/env.go index 9c3de951..1dd2f0ff 100644 --- a/vendor/github.com/google/cel-go/checker/env.go +++ b/vendor/cel.dev/cel-go/checker/env.go @@ -18,11 +18,11 @@ import ( "fmt" "strings" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/parser" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/parser" ) type aggregateLiteralElementType int diff --git a/vendor/github.com/google/cel-go/checker/errors.go b/vendor/cel.dev/cel-go/checker/errors.go similarity index 97% rename from vendor/github.com/google/cel-go/checker/errors.go rename to vendor/cel.dev/cel-go/checker/errors.go index 3535440b..dce384a8 100644 --- a/vendor/github.com/google/cel-go/checker/errors.go +++ b/vendor/cel.dev/cel-go/checker/errors.go @@ -15,9 +15,9 @@ package checker import ( - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/types" ) // typeErrors is a specialization of Errors. diff --git a/vendor/github.com/google/cel-go/checker/format.go b/vendor/cel.dev/cel-go/checker/format.go similarity index 98% rename from vendor/github.com/google/cel-go/checker/format.go rename to vendor/cel.dev/cel-go/checker/format.go index 95842905..17b1a4d2 100644 --- a/vendor/github.com/google/cel-go/checker/format.go +++ b/vendor/cel.dev/cel-go/checker/format.go @@ -18,8 +18,8 @@ import ( "fmt" "strings" - chkdecls "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types" + chkdecls "cel.dev/cel-go/checker/decls" + "cel.dev/cel-go/common/types" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff --git a/vendor/github.com/google/cel-go/checker/mapping.go b/vendor/cel.dev/cel-go/checker/mapping.go similarity index 96% rename from vendor/github.com/google/cel-go/checker/mapping.go rename to vendor/cel.dev/cel-go/checker/mapping.go index 8163a908..7018d819 100644 --- a/vendor/github.com/google/cel-go/checker/mapping.go +++ b/vendor/cel.dev/cel-go/checker/mapping.go @@ -15,7 +15,7 @@ package checker import ( - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common/types" ) type mapping struct { diff --git a/vendor/github.com/google/cel-go/checker/options.go b/vendor/cel.dev/cel-go/checker/options.go similarity index 100% rename from vendor/github.com/google/cel-go/checker/options.go rename to vendor/cel.dev/cel-go/checker/options.go diff --git a/vendor/github.com/google/cel-go/checker/printer.go b/vendor/cel.dev/cel-go/checker/printer.go similarity index 95% rename from vendor/github.com/google/cel-go/checker/printer.go rename to vendor/cel.dev/cel-go/checker/printer.go index 7a3984f0..c90711e4 100644 --- a/vendor/github.com/google/cel-go/checker/printer.go +++ b/vendor/cel.dev/cel-go/checker/printer.go @@ -17,8 +17,8 @@ package checker import ( "sort" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/debug" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/debug" ) type semanticAdorner struct { diff --git a/vendor/github.com/google/cel-go/checker/scopes.go b/vendor/cel.dev/cel-go/checker/scopes.go similarity index 99% rename from vendor/github.com/google/cel-go/checker/scopes.go rename to vendor/cel.dev/cel-go/checker/scopes.go index 2fcfdf29..88b664af 100644 --- a/vendor/github.com/google/cel-go/checker/scopes.go +++ b/vendor/cel.dev/cel-go/checker/scopes.go @@ -17,7 +17,7 @@ package checker import ( "strings" - "github.com/google/cel-go/common/decls" + "cel.dev/cel-go/common/decls" ) // Scopes represents nested Decl sets where the Scopes value contains a Groups containing all diff --git a/vendor/github.com/google/cel-go/checker/types.go b/vendor/cel.dev/cel-go/checker/types.go similarity index 99% rename from vendor/github.com/google/cel-go/checker/types.go rename to vendor/cel.dev/cel-go/checker/types.go index 4c65b273..b716f4e9 100644 --- a/vendor/github.com/google/cel-go/checker/types.go +++ b/vendor/cel.dev/cel-go/checker/types.go @@ -15,7 +15,7 @@ package checker import ( - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common/types" ) // isDyn returns true if the input t is either type DYN or a well-known ANY message. diff --git a/vendor/github.com/google/cel-go/common/BUILD.bazel b/vendor/cel.dev/cel-go/common/BUILD.bazel similarity index 93% rename from vendor/github.com/google/cel-go/common/BUILD.bazel rename to vendor/cel.dev/cel-go/common/BUILD.bazel index 1b1b7914..40888847 100644 --- a/vendor/github.com/google/cel-go/common/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/BUILD.bazel @@ -15,7 +15,7 @@ go_library( "location.go", "source.go", ], - importpath = "github.com/google/cel-go/common", + importpath = "cel.dev/cel-go/common", deps = [ "//common/runes:go_default_library", "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/ast/BUILD.bazel b/vendor/cel.dev/cel-go/common/ast/BUILD.bazel similarity index 96% rename from vendor/github.com/google/cel-go/common/ast/BUILD.bazel rename to vendor/cel.dev/cel-go/common/ast/BUILD.bazel index 9824f57a..d62a4cb6 100644 --- a/vendor/github.com/google/cel-go/common/ast/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/ast/BUILD.bazel @@ -14,7 +14,7 @@ go_library( "factory.go", "navigable.go", ], - importpath = "github.com/google/cel-go/common/ast", + importpath = "cel.dev/cel-go/common/ast", deps = [ "//common:go_default_library", "//common/types:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/ast/ast.go b/vendor/cel.dev/cel-go/common/ast/ast.go similarity index 99% rename from vendor/github.com/google/cel-go/common/ast/ast.go rename to vendor/cel.dev/cel-go/common/ast/ast.go index c8f8f8a0..d65d10b5 100644 --- a/vendor/github.com/google/cel-go/common/ast/ast.go +++ b/vendor/cel.dev/cel-go/common/ast/ast.go @@ -18,9 +18,9 @@ package ast import ( "slices" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // AST contains a protobuf expression and source info along with CEL-native type and reference information. diff --git a/vendor/github.com/google/cel-go/common/ast/conversion.go b/vendor/cel.dev/cel-go/common/ast/conversion.go similarity index 99% rename from vendor/github.com/google/cel-go/common/ast/conversion.go rename to vendor/cel.dev/cel-go/common/ast/conversion.go index 380f8c11..5d032cc1 100644 --- a/vendor/github.com/google/cel-go/common/ast/conversion.go +++ b/vendor/cel.dev/cel-go/common/ast/conversion.go @@ -19,8 +19,8 @@ import ( "google.golang.org/protobuf/proto" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" celpb "cel.dev/expr" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" diff --git a/vendor/github.com/google/cel-go/common/ast/expr.go b/vendor/cel.dev/cel-go/common/ast/expr.go similarity index 99% rename from vendor/github.com/google/cel-go/common/ast/expr.go rename to vendor/cel.dev/cel-go/common/ast/expr.go index 9f55cb3b..459311f0 100644 --- a/vendor/github.com/google/cel-go/common/ast/expr.go +++ b/vendor/cel.dev/cel-go/common/ast/expr.go @@ -15,7 +15,7 @@ package ast import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // ExprKind represents the expression node kind. diff --git a/vendor/github.com/google/cel-go/common/ast/factory.go b/vendor/cel.dev/cel-go/common/ast/factory.go similarity index 99% rename from vendor/github.com/google/cel-go/common/ast/factory.go rename to vendor/cel.dev/cel-go/common/ast/factory.go index d4dcde4d..b83e5555 100644 --- a/vendor/github.com/google/cel-go/common/ast/factory.go +++ b/vendor/cel.dev/cel-go/common/ast/factory.go @@ -14,7 +14,7 @@ package ast -import "github.com/google/cel-go/common/types/ref" +import "cel.dev/cel-go/common/types/ref" // ExprFactory interfaces defines a set of methods necessary for building native expression values. type ExprFactory interface { diff --git a/vendor/github.com/google/cel-go/common/ast/navigable.go b/vendor/cel.dev/cel-go/common/ast/navigable.go similarity index 99% rename from vendor/github.com/google/cel-go/common/ast/navigable.go rename to vendor/cel.dev/cel-go/common/ast/navigable.go index 364edfa3..3a71f865 100644 --- a/vendor/github.com/google/cel-go/common/ast/navigable.go +++ b/vendor/cel.dev/cel-go/common/ast/navigable.go @@ -15,8 +15,8 @@ package ast import ( - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // NavigableExpr represents the base navigable expression value with methods to inspect the diff --git a/vendor/github.com/google/cel-go/common/containers/BUILD.bazel b/vendor/cel.dev/cel-go/common/containers/BUILD.bazel similarity index 89% rename from vendor/github.com/google/cel-go/common/containers/BUILD.bazel rename to vendor/cel.dev/cel-go/common/containers/BUILD.bazel index 81197f06..7def2f25 100644 --- a/vendor/github.com/google/cel-go/common/containers/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/containers/BUILD.bazel @@ -10,7 +10,7 @@ go_library( srcs = [ "container.go", ], - importpath = "github.com/google/cel-go/common/containers", + importpath = "cel.dev/cel-go/common/containers", deps = [ "//common/ast:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/common/containers/container.go b/vendor/cel.dev/cel-go/common/containers/container.go similarity index 99% rename from vendor/github.com/google/cel-go/common/containers/container.go rename to vendor/cel.dev/cel-go/common/containers/container.go index fcfcdfc3..2330e076 100644 --- a/vendor/github.com/google/cel-go/common/containers/container.go +++ b/vendor/cel.dev/cel-go/common/containers/container.go @@ -21,7 +21,7 @@ import ( "strings" "unicode" - "github.com/google/cel-go/common/ast" + "cel.dev/cel-go/common/ast" ) var ( diff --git a/vendor/github.com/google/cel-go/common/cost.go b/vendor/cel.dev/cel-go/common/cost.go similarity index 100% rename from vendor/github.com/google/cel-go/common/cost.go rename to vendor/cel.dev/cel-go/common/cost.go diff --git a/vendor/cel.dev/cel-go/common/cost/BUILD.bazel b/vendor/cel.dev/cel-go/common/cost/BUILD.bazel new file mode 100644 index 00000000..b7d416b5 --- /dev/null +++ b/vendor/cel.dev/cel-go/common/cost/BUILD.bazel @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], # Apache 2.0 +) + +go_library( + name = "go_default_library", + srcs = [ + "cost.go", + ], + importpath = "cel.dev/cel-go/common/cost", +) + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "cost_test.go", + ], + embed = [ + ":go_default_library", + ], +) diff --git a/vendor/cel.dev/cel-go/common/cost/cost.go b/vendor/cel.dev/cel-go/common/cost/cost.go new file mode 100644 index 00000000..1a81a88e --- /dev/null +++ b/vendor/cel.dev/cel-go/common/cost/cost.go @@ -0,0 +1,78 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package cost provides the saturating arithmetic shared by cost estimation and cost tracking. +// +// Costs and sizes are unsigned 64-bit values where math.MaxUint64 doubles as the representation +// of an unbounded, or unknown, quantity. Every operation in this package saturates at +// math.MaxUint64 rather than wrapping so that an unbounded input remains unbounded through any +// sequence of operations. +package cost + +import "math" + +// maxUint64AsFloat is the smallest float64 value greater than math.MaxUint64. +// +// Conversion of a float64 to a uint64 is undefined when the value is out of range, so float +// results are compared against this bound before conversion. +var maxUint64AsFloat = math.Ldexp(1.0, 64) + +// SafeAdd returns the sum of the input values, saturating at math.MaxUint64. +func SafeAdd(x, y uint64, rest ...uint64) uint64 { + sum := x + if y > 0 && sum > math.MaxUint64-y { + return math.MaxUint64 + } + sum += y + for _, r := range rest { + if r > 0 && sum > math.MaxUint64-r { + return math.MaxUint64 + } + sum += r + } + return sum +} + +// SafeMultiply returns the product of the input values, saturating at math.MaxUint64. +func SafeMultiply(x, y uint64) uint64 { + if y != 0 && x > math.MaxUint64/y { + return math.MaxUint64 + } + return x * y +} + +// SafeMultiplyByFactor multiplies a value by a cost factor and returns the nearest integer +// value, rounded up, saturating at math.MaxUint64. +func SafeMultiplyByFactor(x uint64, factor float64) uint64 { + xFloat := float64(x) + if xFloat > 0 && factor > 0 && xFloat > math.MaxUint64/factor { + return math.MaxUint64 + } + return SafeCeil(xFloat * factor) +} + +// SafeCeil returns the smallest integer value greater than or equal to the input, saturating at +// math.MaxUint64 and flooring at zero. +// +// Negative and NaN inputs return zero. +func SafeCeil(x float64) uint64 { + if math.IsNaN(x) || x <= 0 { + return 0 + } + ceil := math.Ceil(x) + if ceil >= maxUint64AsFloat { + return math.MaxUint64 + } + return uint64(ceil) +} diff --git a/vendor/github.com/google/cel-go/common/debug/BUILD.bazel b/vendor/cel.dev/cel-go/common/debug/BUILD.bazel similarity index 88% rename from vendor/github.com/google/cel-go/common/debug/BUILD.bazel rename to vendor/cel.dev/cel-go/common/debug/BUILD.bazel index 724ed340..07fed427 100644 --- a/vendor/github.com/google/cel-go/common/debug/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/debug/BUILD.bazel @@ -10,7 +10,7 @@ go_library( srcs = [ "debug.go", ], - importpath = "github.com/google/cel-go/common/debug", + importpath = "cel.dev/cel-go/common/debug", deps = [ "//common:go_default_library", "//common/ast:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/debug/debug.go b/vendor/cel.dev/cel-go/common/debug/debug.go similarity index 98% rename from vendor/github.com/google/cel-go/common/debug/debug.go rename to vendor/cel.dev/cel-go/common/debug/debug.go index fbc847f0..67593c99 100644 --- a/vendor/github.com/google/cel-go/common/debug/debug.go +++ b/vendor/cel.dev/cel-go/common/debug/debug.go @@ -22,9 +22,9 @@ import ( "strconv" "strings" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // Adorner returns debug metadata that will be tacked on to the string diff --git a/vendor/github.com/google/cel-go/common/decls/BUILD.bazel b/vendor/cel.dev/cel-go/common/decls/BUILD.bazel similarity index 95% rename from vendor/github.com/google/cel-go/common/decls/BUILD.bazel rename to vendor/cel.dev/cel-go/common/decls/BUILD.bazel index bd3f9ae7..85c7d5c4 100644 --- a/vendor/github.com/google/cel-go/common/decls/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/decls/BUILD.bazel @@ -10,7 +10,7 @@ go_library( srcs = [ "decls.go", ], - importpath = "github.com/google/cel-go/common/decls", + importpath = "cel.dev/cel-go/common/decls", deps = [ "//checker/decls:go_default_library", "//common:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/decls/decls.go b/vendor/cel.dev/cel-go/common/decls/decls.go similarity index 99% rename from vendor/github.com/google/cel-go/common/decls/decls.go rename to vendor/cel.dev/cel-go/common/decls/decls.go index 5c50b8e9..d63a202d 100644 --- a/vendor/github.com/google/cel-go/common/decls/decls.go +++ b/vendor/cel.dev/cel-go/common/decls/decls.go @@ -20,12 +20,12 @@ import ( "fmt" "strings" - chkdecls "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + chkdecls "cel.dev/cel-go/checker/decls" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff --git a/vendor/github.com/google/cel-go/common/doc.go b/vendor/cel.dev/cel-go/common/doc.go similarity index 100% rename from vendor/github.com/google/cel-go/common/doc.go rename to vendor/cel.dev/cel-go/common/doc.go diff --git a/vendor/github.com/google/cel-go/common/env/BUILD.bazel b/vendor/cel.dev/cel-go/common/env/BUILD.bazel similarity index 96% rename from vendor/github.com/google/cel-go/common/env/BUILD.bazel rename to vendor/cel.dev/cel-go/common/env/BUILD.bazel index 261da924..1cd6f9ee 100644 --- a/vendor/github.com/google/cel-go/common/env/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/env/BUILD.bazel @@ -25,7 +25,7 @@ go_library( "env.go", "io.go", ], - importpath = "github.com/google/cel-go/common/env", + importpath = "cel.dev/cel-go/common/env", deps = [ "//common:go_default_library", "//common/decls:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/env/env.go b/vendor/cel.dev/cel-go/common/env/env.go similarity index 99% rename from vendor/github.com/google/cel-go/common/env/env.go rename to vendor/cel.dev/cel-go/common/env/env.go index 936036ed..19e17c5d 100644 --- a/vendor/github.com/google/cel-go/common/env/env.go +++ b/vendor/cel.dev/cel-go/common/env/env.go @@ -22,8 +22,8 @@ import ( "strconv" "strings" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/types" ) // NewConfig creates an instance of a YAML serializable CEL environment configuration. diff --git a/vendor/github.com/google/cel-go/common/env/io.go b/vendor/cel.dev/cel-go/common/env/io.go similarity index 97% rename from vendor/github.com/google/cel-go/common/env/io.go rename to vendor/cel.dev/cel-go/common/env/io.go index ec126f9c..9ef6334d 100644 --- a/vendor/github.com/google/cel-go/common/env/io.go +++ b/vendor/cel.dev/cel-go/common/env/io.go @@ -234,11 +234,15 @@ func (p *typeDescParser) parseTypeParamIdent() (string, error) { } func (p *typeDescParser) skipWhitespace() { - for p.pos < p.length && p.text[p.pos] == ' ' { + for p.pos < p.length && isWhitespace(p.text[p.pos]) { p.pos++ } } +func isWhitespace(c byte) bool { + return c == ' ' || c == '\t' || c == '\n' || c == '\r' +} + func isAlpha(c byte) bool { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') } diff --git a/vendor/github.com/google/cel-go/common/error.go b/vendor/cel.dev/cel-go/common/error.go similarity index 100% rename from vendor/github.com/google/cel-go/common/error.go rename to vendor/cel.dev/cel-go/common/error.go diff --git a/vendor/github.com/google/cel-go/common/errors.go b/vendor/cel.dev/cel-go/common/errors.go similarity index 100% rename from vendor/github.com/google/cel-go/common/errors.go rename to vendor/cel.dev/cel-go/common/errors.go diff --git a/vendor/github.com/google/cel-go/common/functions/BUILD.bazel b/vendor/cel.dev/cel-go/common/functions/BUILD.bazel similarity index 83% rename from vendor/github.com/google/cel-go/common/functions/BUILD.bazel rename to vendor/cel.dev/cel-go/common/functions/BUILD.bazel index 3cc27d60..4511d06f 100644 --- a/vendor/github.com/google/cel-go/common/functions/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/functions/BUILD.bazel @@ -10,7 +10,7 @@ go_library( srcs = [ "functions.go", ], - importpath = "github.com/google/cel-go/common/functions", + importpath = "cel.dev/cel-go/common/functions", deps = [ "//common/types/ref:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/common/functions/functions.go b/vendor/cel.dev/cel-go/common/functions/functions.go similarity index 98% rename from vendor/github.com/google/cel-go/common/functions/functions.go rename to vendor/cel.dev/cel-go/common/functions/functions.go index 0c00781d..c5e68571 100644 --- a/vendor/github.com/google/cel-go/common/functions/functions.go +++ b/vendor/cel.dev/cel-go/common/functions/functions.go @@ -18,7 +18,7 @@ package functions import ( "context" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // Overload defines a named overload of a function, indicating an operand trait diff --git a/vendor/github.com/google/cel-go/common/location.go b/vendor/cel.dev/cel-go/common/location.go similarity index 100% rename from vendor/github.com/google/cel-go/common/location.go rename to vendor/cel.dev/cel-go/common/location.go diff --git a/vendor/github.com/google/cel-go/common/operators/BUILD.bazel b/vendor/cel.dev/cel-go/common/operators/BUILD.bazel similarity index 80% rename from vendor/github.com/google/cel-go/common/operators/BUILD.bazel rename to vendor/cel.dev/cel-go/common/operators/BUILD.bazel index b5b67f06..21776cec 100644 --- a/vendor/github.com/google/cel-go/common/operators/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/operators/BUILD.bazel @@ -10,5 +10,5 @@ go_library( srcs = [ "operators.go", ], - importpath = "github.com/google/cel-go/common/operators", + importpath = "cel.dev/cel-go/common/operators", ) diff --git a/vendor/github.com/google/cel-go/common/operators/operators.go b/vendor/cel.dev/cel-go/common/operators/operators.go similarity index 100% rename from vendor/github.com/google/cel-go/common/operators/operators.go rename to vendor/cel.dev/cel-go/common/operators/operators.go diff --git a/vendor/github.com/google/cel-go/common/overloads/BUILD.bazel b/vendor/cel.dev/cel-go/common/overloads/BUILD.bazel similarity index 80% rename from vendor/github.com/google/cel-go/common/overloads/BUILD.bazel rename to vendor/cel.dev/cel-go/common/overloads/BUILD.bazel index e46e2f48..1f1eaa09 100644 --- a/vendor/github.com/google/cel-go/common/overloads/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/overloads/BUILD.bazel @@ -10,5 +10,5 @@ go_library( srcs = [ "overloads.go", ], - importpath = "github.com/google/cel-go/common/overloads", + importpath = "cel.dev/cel-go/common/overloads", ) diff --git a/vendor/github.com/google/cel-go/common/overloads/overloads.go b/vendor/cel.dev/cel-go/common/overloads/overloads.go similarity index 100% rename from vendor/github.com/google/cel-go/common/overloads/overloads.go rename to vendor/cel.dev/cel-go/common/overloads/overloads.go diff --git a/vendor/github.com/google/cel-go/common/runes/BUILD.bazel b/vendor/cel.dev/cel-go/common/runes/BUILD.bazel similarity index 87% rename from vendor/github.com/google/cel-go/common/runes/BUILD.bazel rename to vendor/cel.dev/cel-go/common/runes/BUILD.bazel index bb30242c..0674eaed 100644 --- a/vendor/github.com/google/cel-go/common/runes/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/runes/BUILD.bazel @@ -10,7 +10,7 @@ go_library( srcs = [ "buffer.go", ], - importpath = "github.com/google/cel-go/common/runes", + importpath = "cel.dev/cel-go/common/runes", ) go_test( diff --git a/vendor/github.com/google/cel-go/common/runes/buffer.go b/vendor/cel.dev/cel-go/common/runes/buffer.go similarity index 100% rename from vendor/github.com/google/cel-go/common/runes/buffer.go rename to vendor/cel.dev/cel-go/common/runes/buffer.go diff --git a/vendor/github.com/google/cel-go/common/source.go b/vendor/cel.dev/cel-go/common/source.go similarity index 99% rename from vendor/github.com/google/cel-go/common/source.go rename to vendor/cel.dev/cel-go/common/source.go index 9187e9b5..73237edf 100644 --- a/vendor/github.com/google/cel-go/common/source.go +++ b/vendor/cel.dev/cel-go/common/source.go @@ -15,7 +15,7 @@ package common import ( - "github.com/google/cel-go/common/runes" + "cel.dev/cel-go/common/runes" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" ) diff --git a/vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel b/vendor/cel.dev/cel-go/common/stdlib/BUILD.bazel similarity index 91% rename from vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel rename to vendor/cel.dev/cel-go/common/stdlib/BUILD.bazel index 124dbea8..dd34ac1e 100644 --- a/vendor/github.com/google/cel-go/common/stdlib/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/stdlib/BUILD.bazel @@ -10,7 +10,7 @@ go_library( srcs = [ "standard.go", ], - importpath = "github.com/google/cel-go/common/stdlib", + importpath = "cel.dev/cel-go/common/stdlib", deps = [ "//common:go_default_library", "//common/decls:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/stdlib/standard.go b/vendor/cel.dev/cel-go/common/stdlib/standard.go similarity index 99% rename from vendor/github.com/google/cel-go/common/stdlib/standard.go rename to vendor/cel.dev/cel-go/common/stdlib/standard.go index 3a151462..1c2a5458 100644 --- a/vendor/github.com/google/cel-go/common/stdlib/standard.go +++ b/vendor/cel.dev/cel-go/common/stdlib/standard.go @@ -22,14 +22,14 @@ import ( "strings" "time" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/decls" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/decls" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) var ( diff --git a/vendor/github.com/google/cel-go/common/types/BUILD.bazel b/vendor/cel.dev/cel-go/common/types/BUILD.bazel similarity index 96% rename from vendor/github.com/google/cel-go/common/types/BUILD.bazel rename to vendor/cel.dev/cel-go/common/types/BUILD.bazel index 4ecc4003..8626df96 100644 --- a/vendor/github.com/google/cel-go/common/types/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/types/BUILD.bazel @@ -8,6 +8,7 @@ package( go_library( name = "go_default_library", srcs = [ + "aggregate_sizer.go", "any_value.go", "bool.go", "bytes.go", @@ -28,6 +29,7 @@ go_library( "overflow.go", "provider.go", "regex.go", + "size_calc.go", "string.go", "struct.go", "timestamp.go", @@ -36,7 +38,7 @@ go_library( "unknown.go", "util.go", ], - importpath = "github.com/google/cel-go/common/types", + importpath = "cel.dev/cel-go/common/types", deps = [ "//checker/decls:go_default_library", "//common/overloads:go_default_library", @@ -76,6 +78,7 @@ go_test( "optional_test.go", "provider_test.go", "regex_test.go", + "size_calc_test.go", "string_test.go", "timestamp_test.go", "types_test.go", diff --git a/vendor/cel.dev/cel-go/common/types/aggregate_sizer.go b/vendor/cel.dev/cel-go/common/types/aggregate_sizer.go new file mode 100644 index 00000000..d56b8bc4 --- /dev/null +++ b/vendor/cel.dev/cel-go/common/types/aggregate_sizer.go @@ -0,0 +1,43 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +// AggregateSizer calculates the recursive element size of values. +type AggregateSizer interface { + // AggregateSize returns the size of the input value, if known. + // Otherwise, a unit size of 1 is returned. + AggregateSize(val any) uint32 +} + +// AggregateSizeVisitor interface for ref.Val implementations capable of returning +// their total recursive element count. +type AggregateSizeVisitor interface { + // AggregateSize returns the total count of nested atomic elements (capped at math.MaxUint32). + AggregateSize(sizer AggregateSizer) uint32 +} + +// Helper for computing aggregate sizes of traits.Foldable types. +type foldableAggregateSizer struct { + sizer AggregateSizer + total uint32 +} + +// FoldEntry implements the traits.FoldEntry interface method and counts the aggregate size +// keys and values. +func (f *foldableAggregateSizer) FoldEntry(k, v any) bool { + f.total = safeAddUint32(f.total, f.sizer.AggregateSize(k)) + f.total = safeAddUint32(f.total, f.sizer.AggregateSize(v)) + return true +} diff --git a/vendor/github.com/google/cel-go/common/types/any_value.go b/vendor/cel.dev/cel-go/common/types/any_value.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/any_value.go rename to vendor/cel.dev/cel-go/common/types/any_value.go diff --git a/vendor/github.com/google/cel-go/common/types/bool.go b/vendor/cel.dev/cel-go/common/types/bool.go similarity index 98% rename from vendor/github.com/google/cel-go/common/types/bool.go rename to vendor/cel.dev/cel-go/common/types/bool.go index 5f1e4573..d16964cd 100644 --- a/vendor/github.com/google/cel-go/common/types/bool.go +++ b/vendor/cel.dev/cel-go/common/types/bool.go @@ -20,7 +20,7 @@ import ( "strconv" "strings" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" diff --git a/vendor/github.com/google/cel-go/common/types/bytes.go b/vendor/cel.dev/cel-go/common/types/bytes.go similarity index 99% rename from vendor/github.com/google/cel-go/common/types/bytes.go rename to vendor/cel.dev/cel-go/common/types/bytes.go index 2eefb5d7..206dd3bc 100644 --- a/vendor/github.com/google/cel-go/common/types/bytes.go +++ b/vendor/cel.dev/cel-go/common/types/bytes.go @@ -22,7 +22,7 @@ import ( "strings" "unicode/utf8" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" diff --git a/vendor/github.com/google/cel-go/common/types/compare.go b/vendor/cel.dev/cel-go/common/types/compare.go similarity index 97% rename from vendor/github.com/google/cel-go/common/types/compare.go rename to vendor/cel.dev/cel-go/common/types/compare.go index e1968261..caad97b9 100644 --- a/vendor/github.com/google/cel-go/common/types/compare.go +++ b/vendor/cel.dev/cel-go/common/types/compare.go @@ -17,7 +17,7 @@ package types import ( "math" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) func compareDoubleInt(d Double, i Int) Int { diff --git a/vendor/github.com/google/cel-go/common/types/doc.go b/vendor/cel.dev/cel-go/common/types/doc.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/doc.go rename to vendor/cel.dev/cel-go/common/types/doc.go diff --git a/vendor/github.com/google/cel-go/common/types/double.go b/vendor/cel.dev/cel-go/common/types/double.go similarity index 99% rename from vendor/github.com/google/cel-go/common/types/double.go rename to vendor/cel.dev/cel-go/common/types/double.go index 02abfee2..729fc1ec 100644 --- a/vendor/github.com/google/cel-go/common/types/double.go +++ b/vendor/cel.dev/cel-go/common/types/double.go @@ -21,7 +21,7 @@ import ( "strconv" "strings" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" diff --git a/vendor/github.com/google/cel-go/common/types/duration.go b/vendor/cel.dev/cel-go/common/types/duration.go similarity index 98% rename from vendor/github.com/google/cel-go/common/types/duration.go rename to vendor/cel.dev/cel-go/common/types/duration.go index 22071477..cd3efa1c 100644 --- a/vendor/github.com/google/cel-go/common/types/duration.go +++ b/vendor/cel.dev/cel-go/common/types/duration.go @@ -21,8 +21,8 @@ import ( "strings" "time" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" dpb "google.golang.org/protobuf/types/known/durationpb" diff --git a/vendor/github.com/google/cel-go/common/types/err.go b/vendor/cel.dev/cel-go/common/types/err.go similarity index 99% rename from vendor/github.com/google/cel-go/common/types/err.go rename to vendor/cel.dev/cel-go/common/types/err.go index 3216ff1c..22749de6 100644 --- a/vendor/github.com/google/cel-go/common/types/err.go +++ b/vendor/cel.dev/cel-go/common/types/err.go @@ -19,7 +19,7 @@ import ( "fmt" "reflect" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // Error interface which allows types types.Err values to be treated as error values. diff --git a/vendor/github.com/google/cel-go/common/types/format.go b/vendor/cel.dev/cel-go/common/types/format.go similarity index 91% rename from vendor/github.com/google/cel-go/common/types/format.go rename to vendor/cel.dev/cel-go/common/types/format.go index 174a2bd0..3b2c06f0 100644 --- a/vendor/github.com/google/cel-go/common/types/format.go +++ b/vendor/cel.dev/cel-go/common/types/format.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) type formattable interface { diff --git a/vendor/github.com/google/cel-go/common/types/int.go b/vendor/cel.dev/cel-go/common/types/int.go similarity index 99% rename from vendor/github.com/google/cel-go/common/types/int.go rename to vendor/cel.dev/cel-go/common/types/int.go index 60d5a716..82dbb173 100644 --- a/vendor/github.com/google/cel-go/common/types/int.go +++ b/vendor/cel.dev/cel-go/common/types/int.go @@ -22,7 +22,7 @@ import ( "strings" "time" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" diff --git a/vendor/github.com/google/cel-go/common/types/iterator.go b/vendor/cel.dev/cel-go/common/types/iterator.go similarity index 94% rename from vendor/github.com/google/cel-go/common/types/iterator.go rename to vendor/cel.dev/cel-go/common/types/iterator.go index 98e9147b..77fc90f4 100644 --- a/vendor/github.com/google/cel-go/common/types/iterator.go +++ b/vendor/cel.dev/cel-go/common/types/iterator.go @@ -18,8 +18,8 @@ import ( "fmt" "reflect" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) var ( diff --git a/vendor/github.com/google/cel-go/common/types/json_value.go b/vendor/cel.dev/cel-go/common/types/json_value.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/json_value.go rename to vendor/cel.dev/cel-go/common/types/json_value.go diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/cel.dev/cel-go/common/types/list.go similarity index 93% rename from vendor/github.com/google/cel-go/common/types/list.go rename to vendor/cel.dev/cel-go/common/types/list.go index 028770ed..bbdd7ada 100644 --- a/vendor/github.com/google/cel-go/common/types/list.go +++ b/vendor/cel.dev/cel-go/common/types/list.go @@ -18,12 +18,13 @@ import ( "fmt" "reflect" "strings" + "sync/atomic" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -110,14 +111,13 @@ func NewMutableList(adapter Adapter) traits.MutableLister { type baseList struct { Adapter value any - - // size indicates the number of elements within the list. - // Since objects are immutable the size of a list is static. - size int - - // get returns a value at the specified integer index. - // The index is guaranteed to be checked against the list index range. - get func(int) any + size int + // aggSize memoizes the aggregate size computed by the first completed sizing of this + // list. Accessed atomically since immutable lists may be shared across concurrent + // evaluations; zero means not yet computed. See the SizeCalculator documentation for + // the memoization contract. + aggSize uint32 + get func(int) any } // Add implements the traits.Adder interface method. @@ -269,6 +269,21 @@ func (l *baseList) Size() ref.Val { return Int(l.size) } +// AggregateSize implements the AggregateSizeVisitor interface method. +func (l *baseList) AggregateSize(sizer AggregateSizer) uint32 { + if sz := atomic.LoadUint32(&l.aggSize); sz != 0 { + return sz + } + total := uint32(1) + for i := range l.size { + total = safeAddUint32(total, sizer.AggregateSize(l.get(i))) + } + if cacheableAggregateSize(sizer) { + atomic.StoreUint32(&l.aggSize, total) + } + return total +} + // Type implements the ref.Val interface method. func (l *baseList) Type() ref.Type { return ListType @@ -322,11 +337,13 @@ func (l *mutableList) Add(other ref.Val) ref.Val { case *mutableList: l.mutableValues = append(l.mutableValues, otherList.mutableValues...) l.size += len(otherList.mutableValues) + atomic.StoreUint32(&l.aggSize, 0) case traits.Lister: for i := IntZero; i < otherList.Size().(Int); i++ { l.size++ l.mutableValues = append(l.mutableValues, otherList.Get(i)) } + atomic.StoreUint32(&l.aggSize, 0) default: return MaybeNoSuchOverloadErr(otherList) } @@ -480,6 +497,11 @@ func (l *concatList) Size() ref.Val { return l.cachedSize } +// AggregateSize implements the AggregateSizeVisitor interface method. +func (l *concatList) AggregateSize(sizer AggregateSizer) uint32 { + return safeAddUint32(sizer.AggregateSize(l.prevList), sizer.AggregateSize(l.nextList)) +} + // String converts the concatenated list to a human-readable string. func (l *concatList) String() string { var sb strings.Builder diff --git a/vendor/github.com/google/cel-go/common/types/map.go b/vendor/cel.dev/cel-go/common/types/map.go similarity index 95% rename from vendor/github.com/google/cel-go/common/types/map.go rename to vendor/cel.dev/cel-go/common/types/map.go index e4d6f765..782003e5 100644 --- a/vendor/github.com/google/cel-go/common/types/map.go +++ b/vendor/cel.dev/cel-go/common/types/map.go @@ -19,14 +19,15 @@ import ( "reflect" "sort" "strings" + "sync/atomic" "unicode" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "github.com/google/cel-go/common/types/pb" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/types/pb" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -142,8 +143,13 @@ type baseMap struct { // value is the native Go value upon which the map type operators. value any - // size is the number of entries in the map. size int + + // aggSize memoizes the aggregate size computed by the first completed sizing of this + // map. Accessed atomically since immutable maps may be shared across concurrent + // evaluations; zero means not yet computed. See the SizeCalculator documentation for + // the memoization contract. + aggSize uint32 } // Contains implements the traits.Container interface method. @@ -303,6 +309,19 @@ func (m *baseMap) Size() ref.Val { return Int(m.size) } +// AggregateSize implements the AggregateSizeVisitor interface method. +func (m *baseMap) AggregateSize(sizer AggregateSizer) uint32 { + if sz := atomic.LoadUint32(&m.aggSize); sz != 0 { + return sz + } + f := foldableAggregateSizer{sizer: sizer, total: 1} + m.Fold(&f) + if cacheableAggregateSize(sizer) { + atomic.StoreUint32(&m.aggSize, f.total) + } + return f.total +} + // String converts the map into a human-readable string. func (m *baseMap) String() string { var sb strings.Builder @@ -380,6 +399,8 @@ func (m *mutableMap) Insert(k, v ref.Val) ref.Val { return NewErr("insert failed: key %v already exists", k) } m.mutableValues[k] = v + m.size++ + atomic.StoreUint32(&m.aggSize, 0) return m } @@ -909,6 +930,20 @@ func (m *protoMap) Size() ref.Val { return Int(m.value.Len()) } +// AggregateSize implements the AggregateSizeVisitor interface method. +func (m *protoMap) AggregateSize(sizer AggregateSizer) uint32 { + if m.value == nil { + return 0 + } + total := uint32(1) + m.value.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { + total = safeAddUint32(total, sizer.AggregateSize(k)) + total = safeAddUint32(total, sizer.AggregateSize(v)) + return true + }) + return total +} + // Type implements the ref.Val interface method. func (m *protoMap) Type() ref.Type { return MapType diff --git a/vendor/github.com/google/cel-go/common/types/native.go b/vendor/cel.dev/cel-go/common/types/native.go similarity index 96% rename from vendor/github.com/google/cel-go/common/types/native.go rename to vendor/cel.dev/cel-go/common/types/native.go index 33c897b4..a3736efb 100644 --- a/vendor/github.com/google/cel-go/common/types/native.go +++ b/vendor/cel.dev/cel-go/common/types/native.go @@ -23,8 +23,8 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" structpb "google.golang.org/protobuf/types/known/structpb" ) @@ -363,6 +363,23 @@ func (o *nativeObj) Value() any { return o.val } +// AggregateSize implements the AggregateSizeVisitor interface method. +func (o *nativeObj) AggregateSize(sizer AggregateSizer) uint32 { + refVal := reflect.Indirect(o.refValue) + if !refVal.IsValid() { + return 0 + } + total := uint32(1) + for _, fieldType := range o.valType.fieldsByName { + fieldValue := safeGetFieldByIndex(refVal, fieldType.Index) + if !fieldValue.IsValid() || fieldValue.IsZero() { + continue + } + total = safeAddUint32(total, sizer.AggregateSize(fieldValue)) + } + return total +} + func newNativeTypes(rawType reflect.Type, fieldNameHandler NativeTypesFieldNameHandler) ([]*NativeType, error) { nt, err := newNativeType(rawType, fieldNameHandler) if err != nil { diff --git a/vendor/github.com/google/cel-go/common/types/null.go b/vendor/cel.dev/cel-go/common/types/null.go similarity index 98% rename from vendor/github.com/google/cel-go/common/types/null.go rename to vendor/cel.dev/cel-go/common/types/null.go index 671e1ee5..990609c6 100644 --- a/vendor/github.com/google/cel-go/common/types/null.go +++ b/vendor/cel.dev/cel-go/common/types/null.go @@ -21,7 +21,7 @@ import ( "google.golang.org/protobuf/proto" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" diff --git a/vendor/github.com/google/cel-go/common/types/object.go b/vendor/cel.dev/cel-go/common/types/object.go similarity index 92% rename from vendor/github.com/google/cel-go/common/types/object.go rename to vendor/cel.dev/cel-go/common/types/object.go index bb2a09e8..3eeb60c0 100644 --- a/vendor/github.com/google/cel-go/common/types/object.go +++ b/vendor/cel.dev/cel-go/common/types/object.go @@ -24,8 +24,8 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "github.com/google/cel-go/common/types/pb" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/pb" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -167,9 +167,17 @@ func (o *protoObj) Value() any { return o.value } -type protoObjField struct { - fd protoreflect.FieldDescriptor - v protoreflect.Value +// AggregateSize implements the AggregateSizeVisitor interface method. +func (o *protoObj) AggregateSize(sizer AggregateSizer) uint32 { + if o.value == nil { + return 0 + } + total := uint32(1) + o.value.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + total = safeAddUint32(total, sizer.AggregateSize(v)) + return true + }) + return total } func (o *protoObj) format(sb *strings.Builder) { diff --git a/vendor/github.com/google/cel-go/common/types/optional.go b/vendor/cel.dev/cel-go/common/types/optional.go similarity index 92% rename from vendor/github.com/google/cel-go/common/types/optional.go rename to vendor/cel.dev/cel-go/common/types/optional.go index 0d861823..b2092f95 100644 --- a/vendor/github.com/google/cel-go/common/types/optional.go +++ b/vendor/cel.dev/cel-go/common/types/optional.go @@ -20,7 +20,7 @@ import ( "reflect" "strings" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) var ( @@ -120,3 +120,11 @@ func (o *Optional) Value() any { } return o.value.Value() } + +// AggregateSize implements the AggregateSizeVisitor interface method. +func (o *Optional) AggregateSize(sizer AggregateSizer) uint32 { + if !o.HasValue() { + return 0 + } + return safeAddUint32(1, sizer.AggregateSize(o.value)) +} diff --git a/vendor/github.com/google/cel-go/common/types/overflow.go b/vendor/cel.dev/cel-go/common/types/overflow.go similarity index 97% rename from vendor/github.com/google/cel-go/common/types/overflow.go rename to vendor/cel.dev/cel-go/common/types/overflow.go index dcb66ef5..49b15377 100644 --- a/vendor/github.com/google/cel-go/common/types/overflow.go +++ b/vendor/cel.dev/cel-go/common/types/overflow.go @@ -427,3 +427,24 @@ func uint64ToInt64Lossless(v uint64) (int64, bool) { i, err := uint64ToInt64Checked(v) return i, err == nil } + +func safeAddUint32(a, b uint32) uint32 { + if math.MaxUint32-a < b { + return math.MaxUint32 + } + return a + b +} + +func safeUint32FromInt(n int) uint32 { + if n < 0 || uint64(n) > math.MaxUint32 { + return math.MaxUint32 + } + return uint32(n) +} + +func safeUint32FromBoxedInt(v Int) uint32 { + if v < 0 || v > math.MaxUint32 { + return math.MaxUint32 + } + return uint32(v) +} diff --git a/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel b/vendor/cel.dev/cel-go/common/types/pb/BUILD.bazel similarity index 96% rename from vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel rename to vendor/cel.dev/cel-go/common/types/pb/BUILD.bazel index e2b9d37b..66d333c3 100644 --- a/vendor/github.com/google/cel-go/common/types/pb/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/types/pb/BUILD.bazel @@ -15,7 +15,7 @@ go_library( "pb.go", "type.go", ], - importpath = "github.com/google/cel-go/common/types/pb", + importpath = "cel.dev/cel-go/common/types/pb", deps = [ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//encoding/protowire:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/types/pb/checked.go b/vendor/cel.dev/cel-go/common/types/pb/checked.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/pb/checked.go rename to vendor/cel.dev/cel-go/common/types/pb/checked.go diff --git a/vendor/github.com/google/cel-go/common/types/pb/enum.go b/vendor/cel.dev/cel-go/common/types/pb/enum.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/pb/enum.go rename to vendor/cel.dev/cel-go/common/types/pb/enum.go diff --git a/vendor/github.com/google/cel-go/common/types/pb/equal.go b/vendor/cel.dev/cel-go/common/types/pb/equal.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/pb/equal.go rename to vendor/cel.dev/cel-go/common/types/pb/equal.go diff --git a/vendor/github.com/google/cel-go/common/types/pb/file.go b/vendor/cel.dev/cel-go/common/types/pb/file.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/pb/file.go rename to vendor/cel.dev/cel-go/common/types/pb/file.go diff --git a/vendor/github.com/google/cel-go/common/types/pb/pb.go b/vendor/cel.dev/cel-go/common/types/pb/pb.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/pb/pb.go rename to vendor/cel.dev/cel-go/common/types/pb/pb.go diff --git a/vendor/github.com/google/cel-go/common/types/pb/type.go b/vendor/cel.dev/cel-go/common/types/pb/type.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/pb/type.go rename to vendor/cel.dev/cel-go/common/types/pb/type.go diff --git a/vendor/github.com/google/cel-go/common/types/provider.go b/vendor/cel.dev/cel-go/common/types/provider.go similarity index 98% rename from vendor/github.com/google/cel-go/common/types/provider.go rename to vendor/cel.dev/cel-go/common/types/provider.go index 2321828d..ba45df76 100644 --- a/vendor/github.com/google/cel-go/common/types/provider.go +++ b/vendor/cel.dev/cel-go/common/types/provider.go @@ -15,6 +15,7 @@ package types import ( + "encoding/json" "fmt" "maps" "reflect" @@ -24,9 +25,9 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "github.com/google/cel-go/common/types/pb" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/types/pb" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" anypb "google.golang.org/protobuf/types/known/anypb" @@ -663,6 +664,18 @@ func (p *Registry) NativeToValue(value any) ref.Val { if v != nil { return Uint(*v) } + case json.Number: + if i, err := v.Int64(); err == nil { + return Int(i) + } + if f, err := v.Float64(); err == nil { + return Double(f) + } + case json.RawMessage: + var rawVal any + if err := json.Unmarshal(v, &rawVal); err == nil { + return p.NativeToValue(rawVal) + } case []byte: return Bytes(v) // specializations for common lists types. diff --git a/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel b/vendor/cel.dev/cel-go/common/types/ref/BUILD.bazel similarity index 89% rename from vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel rename to vendor/cel.dev/cel-go/common/types/ref/BUILD.bazel index 79330c33..9df5779d 100644 --- a/vendor/github.com/google/cel-go/common/types/ref/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/types/ref/BUILD.bazel @@ -11,7 +11,7 @@ go_library( "provider.go", "reference.go", ], - importpath = "github.com/google/cel-go/common/types/ref", + importpath = "cel.dev/cel-go/common/types/ref", deps = [ "@org_golang_google_genproto_googleapis_api//expr/v1alpha1:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", diff --git a/vendor/github.com/google/cel-go/common/types/ref/provider.go b/vendor/cel.dev/cel-go/common/types/ref/provider.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/ref/provider.go rename to vendor/cel.dev/cel-go/common/types/ref/provider.go diff --git a/vendor/github.com/google/cel-go/common/types/ref/reference.go b/vendor/cel.dev/cel-go/common/types/ref/reference.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/ref/reference.go rename to vendor/cel.dev/cel-go/common/types/ref/reference.go diff --git a/vendor/github.com/google/cel-go/common/types/regex.go b/vendor/cel.dev/cel-go/common/types/regex.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/regex.go rename to vendor/cel.dev/cel-go/common/types/regex.go diff --git a/vendor/cel.dev/cel-go/common/types/size_calc.go b/vendor/cel.dev/cel-go/common/types/size_calc.go new file mode 100644 index 00000000..fecb2f30 --- /dev/null +++ b/vendor/cel.dev/cel-go/common/types/size_calc.go @@ -0,0 +1,410 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "math" + "reflect" + "time" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" +) + +const ( + defaultSizeCalculatorMaxDepth = 5 + defaultSizeCalculatorMaxTraversal = 10000 + defaultSizeCalculatorStringUnitLength = 10 +) + +// SizeCalculatorOption configures a SizeCalculator instance. +type SizeCalculatorOption func(*SizeCalculator) + +// SizeCalculatorMaxDepth sets the maximum object depth limit before saturating to math.MaxUint32. +func SizeCalculatorMaxDepth(depth int) SizeCalculatorOption { + return func(s *SizeCalculator) { + s.maxDepth = depth + } +} + +// SizeCalculatorMaxTraversal sets the maximum object traversal limit before saturating to math.MaxUint32. +func SizeCalculatorMaxTraversal(traversal int) SizeCalculatorOption { + return func(s *SizeCalculator) { + s.maxTraversal = traversal + } +} + +// SizeCalculatorStringUnitLength sets the number of string or bytes value bytes which count as +// a single element (default 10). Values less than 1 are treated as 1, meaning each byte counts +// as a whole element. +// +// String sizes are measured in bytes rather than characters so that sizing large values is +// O(1) rather than a full UTF-8 scan per observation; byte length is never smaller than the +// character count, so byte-based sizing is conservative for limit enforcement. +func SizeCalculatorStringUnitLength(length int) SizeCalculatorOption { + return func(s *SizeCalculator) { + if length < 1 { + length = 1 + } + s.stringUnitLength = length + } +} + +// SizeCalculator calculates the recursive element size of values. +// +// Aggregate values may memoize their computed size on first calculation as an optimization +// for repeated sizing of shared structures. The memoized size reflects the configuration of +// the calculator which first sized the value; hosts requiring differently configured +// calculators, e.g. distinct depth or traversal limits, should not share value instances +// across them. Memoized totals are also a snapshot of the value's contents at first sizing: +// hosts which mutate data underlying a sized aggregate, e.g. a proto message held as a list +// element, will observe the total computed before the mutation. Sizes computed from +// calculations aborted at the depth or traversal limits are never memoized. +type SizeCalculator struct { + version int + maxDepth int + maxTraversal int + stringUnitLength int +} + +// NewSizeCalculator returns a new SizeCalculator configured with optional SizeCalculatorOption settings. +func NewSizeCalculator(opts ...SizeCalculatorOption) *SizeCalculator { + s := &SizeCalculator{ + version: 0, + maxDepth: defaultSizeCalculatorMaxDepth, + maxTraversal: defaultSizeCalculatorMaxTraversal, + stringUnitLength: defaultSizeCalculatorStringUnitLength, + } + for _, opt := range opts { + opt(s) + } + return s +} + +// Version returns the calculation version. +func (s *SizeCalculator) Version() int { + return s.version +} + +type sizeContext struct { + calc *SizeCalculator + depth int + traversalCount *int + limitExceeded *bool +} + +func (c sizeContext) childContext() sizeContext { + c.depth++ + return c +} + +func (c sizeContext) visitNode() bool { + *c.traversalCount++ + if *c.traversalCount > c.calc.maxTraversal || c.depth > c.calc.maxDepth { + *c.limitExceeded = true + return false + } + return true +} + +// aggregateSizeStatus exposes whether the in-flight size computation has exceeded the +// calculator's depth or traversal limits. +type aggregateSizeStatus interface { + aggregateSizeLimitExceeded() bool +} + +// aggregateSizeLimitExceeded implements the aggregateSizeStatus interface method. +func (c sizeContext) aggregateSizeLimitExceeded() bool { + return *c.limitExceeded +} + +// cacheableAggregateSize reports whether a size computed with the given sizer is safe to +// memoize on the value. Only totals from computations which verifiably stayed within the +// calculator's depth and traversal limits are stable properties of the value; totals from +// aborted computations depend on where in the traversal the value was encountered and would +// poison the memoized size. +func cacheableAggregateSize(sizer AggregateSizer) bool { + status, ok := sizer.(aggregateSizeStatus) + return ok && !status.aggregateSizeLimitExceeded() +} + +// AggregateSizeEstimate captures the outcome of an aggregate size computation. +// +// The Size saturates at math.MaxUint32 when the accumulated element count overflows uint32. +// LimitExceeded reports the computation was aborted because the value was too expensive to +// traverse (too deep, or too many nodes visited); in that case Size is also math.MaxUint32, +// but the value's true size may be smaller — the two conditions are distinguishable by the flag. +type AggregateSizeEstimate struct { + Size uint32 + LimitExceeded bool +} + +// AggregateSize returns the size of the input value, if known. +// Otherwise, a unit size of 1 is returned. +// +// When the calculator's depth or traversal limits are exceeded, the size saturates to +// math.MaxUint32. Use EstimateAggregateSize to distinguish limit-exceeded results from +// genuine uint32 saturation. +func (s *SizeCalculator) AggregateSize(val any) uint32 { + return s.EstimateAggregateSize(val).Size +} + +// EstimateAggregateSize returns the aggregate size of the input value along with an indication +// of whether the computation was aborted due to the calculator's depth or traversal limits. +func (s *SizeCalculator) EstimateAggregateSize(val any) AggregateSizeEstimate { + traversals := 0 + exceeded := false + ctx := sizeContext{ + calc: s, + depth: 1, + traversalCount: &traversals, + limitExceeded: &exceeded, + } + size := ctx.AggregateSize(val) + return AggregateSizeEstimate{Size: size, LimitExceeded: exceeded} +} + +// stringSize converts a byte length to an element count where stringUnitLength bytes count +// as a single element, rounding up with a minimum size of 1. +func (s *SizeCalculator) stringSize(length int) uint32 { + if length <= 0 { + return 1 + } + return safeUint32FromInt((length + s.stringUnitLength - 1) / s.stringUnitLength) +} + +// AggregateSize implements the ref.Val interface and allows for the generation of nested +// child context values which are necessary for correct traversal count tracking. +func (c sizeContext) AggregateSize(val any) uint32 { + if !c.visitNode() { + return math.MaxUint32 + } + switch v := val.(type) { + case String: + return c.calc.stringSize(len(v)) + case Bytes: + return c.calc.stringSize(len(v)) + case AggregateSizeVisitor: + return v.AggregateSize(c.childContext()) + case traits.Foldable: + f := foldableAggregateSizer{sizer: c.childContext(), total: 1} + v.Fold(&f) + return f.total + case traits.Mapper: + total := uint32(1) + it := v.Iterator() + childCtx := c.childContext() + for it.HasNext() == True { + key := it.Next() + val, _ := v.Find(key) + total = safeAddUint32(total, childCtx.AggregateSize(key)) + total = safeAddUint32(total, childCtx.AggregateSize(val)) + } + return total + case traits.Lister: + total := uint32(1) + it := v.Iterator() + childCtx := c.childContext() + for it.HasNext() == True { + total = safeAddUint32(total, childCtx.AggregateSize(it.Next())) + } + return total + case traits.Sizer: + return safeUint32FromBoxedInt(v.Size().(Int)) + case Bool, Int, Uint, Double, Duration, Timestamp, Null, *Type, *Err, *Unknown: + return 1 + case ref.Val: + return c.AggregateSize(v.Value()) + case protoreflect.Value: + return c.AggregateSize(v.Interface()) + case protoreflect.MapKey: + return c.AggregateSize(v.Value().Interface()) + case protoreflect.Message: + return getProtoMessageAggregateSize(c, v) + case protoreflect.List: + return getProtoListAggregateSize(c, v) + case protoreflect.Map: + return getProtoMapAggregateSize(c, v) + case proto.Message: + if v == nil { + return 0 + } + return getProtoMessageAggregateSize(c, v.ProtoReflect()) + case reflect.Value: + return getReflectValueAggregateSize(c, v) + case string: + return c.calc.stringSize(len(v)) + case []byte: + return c.calc.stringSize(len(v)) + case int, int8, int16, int32, int64, + uint, uint8, uint16, uint32, uint64, + float32, float64, bool, time.Time, time.Duration, nil: + return 1 + default: + return getReflectValueAggregateSize(c, reflect.ValueOf(val)) + } +} + +func getProtoFieldAggregateSize(c sizeContext, fd protoreflect.FieldDescriptor, v protoreflect.Value) uint32 { + if !c.visitNode() { + return math.MaxUint32 + } + childCtx := c.childContext() + if fd.IsMap() { + return getProtoMapAggregateSize(childCtx, v.Map()) + } + if fd.IsList() { + return getProtoListAggregateSize(childCtx, v.List()) + } + return childCtx.AggregateSize(v.Interface()) +} + +func getProtoMessageAggregateSize(c sizeContext, m protoreflect.Message) uint32 { + if !m.IsValid() { + return 0 + } + if !c.visitNode() { + return math.MaxUint32 + } + childCtx := c.childContext() + total := uint32(1) + m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + total = safeAddUint32(total, getProtoFieldAggregateSize(childCtx, fd, v)) + return true + }) + return total +} + +func getProtoListAggregateSize(c sizeContext, l protoreflect.List) uint32 { + if !l.IsValid() { + return 0 + } + if !c.visitNode() { + return math.MaxUint32 + } + childCtx := c.childContext() + total := uint32(1) + for i := range l.Len() { + total = safeAddUint32(total, childCtx.AggregateSize(l.Get(i).Interface())) + } + return total +} + +func getProtoMapAggregateSize(c sizeContext, m protoreflect.Map) uint32 { + if !m.IsValid() { + return 0 + } + if !c.visitNode() { + return math.MaxUint32 + } + childCtx := c.childContext() + total := uint32(1) + m.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { + total = safeAddUint32(total, childCtx.AggregateSize(k.Value().Interface())) + total = safeAddUint32(total, childCtx.AggregateSize(v.Interface())) + return true + }) + return total +} + +func getReflectValueAggregateSize(c sizeContext, fieldVal reflect.Value) uint32 { + if !fieldVal.IsValid() { + return 0 + } + if !c.visitNode() { + return math.MaxUint32 + } + childCtx := c.childContext() + switch fieldVal.Kind() { + case reflect.String: + return c.calc.stringSize(fieldVal.Len()) + case reflect.Slice, reflect.Array: + elemType := fieldVal.Type().Elem() + if elemType.Kind() == reflect.Uint8 { + return c.calc.stringSize(fieldVal.Len()) + } + total := safeAddUint32(1, safeUint32FromInt(fieldVal.Len())) + switch elemType.Kind() { + case reflect.String: + total = 1 + for i := 0; i < fieldVal.Len(); i++ { + total = safeAddUint32(total, childCtx.AggregateSize(fieldVal.Index(i).String())) + } + case reflect.Struct, reflect.Pointer, reflect.Slice, reflect.Array, reflect.Map, reflect.Interface: + total = 1 + for i := 0; i < fieldVal.Len(); i++ { + total = safeAddUint32(total, getReflectValueAggregateSize(childCtx, fieldVal.Index(i))) + } + } + return total + case reflect.Map: + total := uint32(1) + iter := fieldVal.MapRange() + for iter.Next() { + total = safeAddUint32(total, getReflectValueAggregateSize(childCtx, iter.Key())) + total = safeAddUint32(total, getReflectValueAggregateSize(childCtx, iter.Value())) + } + return total + case reflect.Pointer, reflect.Interface: + if fieldVal.IsNil() { + return 0 + } + if sz, ok := checkCustomSizer(childCtx, fieldVal); ok { + return sz + } + return getReflectValueAggregateSize(c, fieldVal.Elem()) + case reflect.Struct: + if fieldVal.Type() == timestampType || fieldVal.Type() == durationType { + return 1 + } + if sz, ok := checkCustomSizer(childCtx, fieldVal); ok { + return sz + } + total := uint32(1) + t := fieldVal.Type() + numFields := fieldVal.NumField() + for i := range numFields { + if !t.Field(i).IsExported() { + continue + } + fVal := fieldVal.Field(i) + if !fVal.IsValid() || fVal.IsZero() { + continue + } + total = safeAddUint32(total, getReflectValueAggregateSize(childCtx, fVal)) + } + return total + default: + return 1 + } +} + +func checkCustomSizer(c sizeContext, fieldVal reflect.Value) (uint32, bool) { + if !fieldVal.CanInterface() { + return 0, false + } + + switch sizer := fieldVal.Interface().(type) { + case AggregateSizeVisitor: + return sizer.AggregateSize(c), true + case traits.Sizer: + return safeUint32FromBoxedInt(sizer.Size().(Int)), true + default: + return 0, false + } +} diff --git a/vendor/github.com/google/cel-go/common/types/string.go b/vendor/cel.dev/cel-go/common/types/string.go similarity index 98% rename from vendor/github.com/google/cel-go/common/types/string.go rename to vendor/cel.dev/cel-go/common/types/string.go index 1335903a..238b8548 100644 --- a/vendor/github.com/google/cel-go/common/types/string.go +++ b/vendor/cel.dev/cel-go/common/types/string.go @@ -22,8 +22,8 @@ import ( "strings" "time" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" diff --git a/vendor/github.com/google/cel-go/common/types/struct.go b/vendor/cel.dev/cel-go/common/types/struct.go similarity index 96% rename from vendor/github.com/google/cel-go/common/types/struct.go rename to vendor/cel.dev/cel-go/common/types/struct.go index 61740a70..0b50895a 100644 --- a/vendor/github.com/google/cel-go/common/types/struct.go +++ b/vendor/cel.dev/cel-go/common/types/struct.go @@ -17,7 +17,7 @@ package types import ( "reflect" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // StructTypeDescriptor describes a CEL struct type, providing field metadata and value instantiation. diff --git a/vendor/github.com/google/cel-go/common/types/timestamp.go b/vendor/cel.dev/cel-go/common/types/timestamp.go similarity index 82% rename from vendor/github.com/google/cel-go/common/types/timestamp.go rename to vendor/cel.dev/cel-go/common/types/timestamp.go index aee47f05..7b316c6d 100644 --- a/vendor/github.com/google/cel-go/common/types/timestamp.go +++ b/vendor/cel.dev/cel-go/common/types/timestamp.go @@ -15,6 +15,8 @@ package types import ( + "encoding/json" + "errors" "fmt" "reflect" "regexp" @@ -23,8 +25,8 @@ import ( "time" "unicode" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" @@ -258,6 +260,90 @@ func (t Timestamp) format(sb *strings.Builder) { fmt.Fprintf(sb, `timestamp("%s")`, t.Time.UTC().Format(time.RFC3339Nano)) } +// ParseTimestamp attempts to parse a timestamp from various supported types and representations: +// - time.Time, Timestamp, *timestamppb.Timestamp +// - RFC 3339 and RFC 3339Nano formatted strings (e.g. "2023-01-01T00:00:00Z") +// - Unix epoch integers (int, int32, int64) +// - Unix epoch floating-point seconds (float32, float64) +// - json.Number +// - String representations of integers or floating-point epoch seconds +// +// If the parsed timestamp falls outside the supported range [minUnixTime, maxUnixTime], an error is returned. +func ParseTimestamp(val any) (time.Time, error) { + if val == nil { + return time.Time{}, errors.New("invalid timestamp: nil value") + } + switch v := val.(type) { + case time.Time: + return validateTimestampRange(v.UTC()) + case Timestamp: + return validateTimestampRange(v.Time.UTC()) + case *tpb.Timestamp: + if v == nil { + return time.Time{}, nil + } + return validateTimestampRange(v.AsTime().UTC()) + case int: + return validateTimestampRange(time.Unix(int64(v), 0).UTC()) + case int32: + return validateTimestampRange(time.Unix(int64(v), 0).UTC()) + case int64: + return validateTimestampRange(time.Unix(v, 0).UTC()) + case float32: + return unixTimeFromFloat(float64(v)) + case float64: + return unixTimeFromFloat(v) + case json.Number: + if i, err := v.Int64(); err == nil { + return validateTimestampRange(time.Unix(i, 0).UTC()) + } + if f, err := v.Float64(); err == nil { + return unixTimeFromFloat(f) + } + return ParseTimestamp(v.String()) + case string: + s := strings.TrimSpace(v) + if s == "" { + return time.Time{}, errors.New("invalid RFC 3339 timestamp: ''") + } + if isStrictRFC3339(s) { + t, err := time.Parse(time.RFC3339, s) + if err != nil { + return time.Time{}, fmt.Errorf("invalid RFC 3339 timestamp %q", s) + } + return validateTimestampRange(t.UTC()) + } + if i, err := strconv.ParseInt(s, 10, 64); err == nil { + return validateTimestampRange(time.Unix(i, 0).UTC()) + } + if f, err := strconv.ParseFloat(s, 64); err == nil { + return unixTimeFromFloat(f) + } + return time.Time{}, fmt.Errorf("unsupported timestamp format: %q", s) + default: + return time.Time{}, fmt.Errorf("unsupported timestamp type: %T", val) + } +} + +func unixTimeFromFloat(f float64) (time.Time, error) { + sec, err := doubleToInt64Checked(f) + if err != nil { + return time.Time{}, err + } + nsec := int64((f - float64(sec)) * 1e9) + return validateTimestampRange(time.Unix(sec, nsec).UTC()) +} + +func validateTimestampRange(t time.Time) (time.Time, error) { + if t.IsZero() { + return t, nil + } + if t.Unix() < minUnixTime || t.Unix() > maxUnixTime { + return time.Time{}, fmt.Errorf("timestamp overflow: %v", t) + } + return t, nil +} + var ( timestampValueType = reflect.TypeOf(&tpb.Timestamp{}) diff --git a/vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel b/vendor/cel.dev/cel-go/common/types/traits/BUILD.bazel similarity index 89% rename from vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel rename to vendor/cel.dev/cel-go/common/types/traits/BUILD.bazel index b19eb830..e2f7d6fd 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/BUILD.bazel +++ b/vendor/cel.dev/cel-go/common/types/traits/BUILD.bazel @@ -22,7 +22,7 @@ go_library( "traits.go", "zeroer.go", ], - importpath = "github.com/google/cel-go/common/types/traits", + importpath = "cel.dev/cel-go/common/types/traits", deps = [ "//common/types/ref:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/common/types/traits/comparer.go b/vendor/cel.dev/cel-go/common/types/traits/comparer.go similarity index 95% rename from vendor/github.com/google/cel-go/common/types/traits/comparer.go rename to vendor/cel.dev/cel-go/common/types/traits/comparer.go index b531d9ae..83b13953 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/comparer.go +++ b/vendor/cel.dev/cel-go/common/types/traits/comparer.go @@ -15,7 +15,7 @@ package traits import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // Comparer interface for ordering comparisons between values in order to diff --git a/vendor/github.com/google/cel-go/common/types/traits/container.go b/vendor/cel.dev/cel-go/common/types/traits/container.go similarity index 94% rename from vendor/github.com/google/cel-go/common/types/traits/container.go rename to vendor/cel.dev/cel-go/common/types/traits/container.go index cf5c621a..357ccd31 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/container.go +++ b/vendor/cel.dev/cel-go/common/types/traits/container.go @@ -14,7 +14,7 @@ package traits -import "github.com/google/cel-go/common/types/ref" +import "cel.dev/cel-go/common/types/ref" // Container interface which permits containment tests such as 'a in b'. type Container interface { diff --git a/vendor/github.com/google/cel-go/common/types/traits/field_tester.go b/vendor/cel.dev/cel-go/common/types/traits/field_tester.go similarity index 95% rename from vendor/github.com/google/cel-go/common/types/traits/field_tester.go rename to vendor/cel.dev/cel-go/common/types/traits/field_tester.go index 816a9565..d80351b4 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/field_tester.go +++ b/vendor/cel.dev/cel-go/common/types/traits/field_tester.go @@ -15,7 +15,7 @@ package traits import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // FieldTester indicates if a defined field on an object type is set to a diff --git a/vendor/github.com/google/cel-go/common/types/traits/indexer.go b/vendor/cel.dev/cel-go/common/types/traits/indexer.go similarity index 94% rename from vendor/github.com/google/cel-go/common/types/traits/indexer.go rename to vendor/cel.dev/cel-go/common/types/traits/indexer.go index 662c6836..2d1f72ae 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/indexer.go +++ b/vendor/cel.dev/cel-go/common/types/traits/indexer.go @@ -15,7 +15,7 @@ package traits import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // Indexer permits random access of elements by index 'a[b()]'. diff --git a/vendor/github.com/google/cel-go/common/types/traits/iterator.go b/vendor/cel.dev/cel-go/common/types/traits/iterator.go similarity index 97% rename from vendor/github.com/google/cel-go/common/types/traits/iterator.go rename to vendor/cel.dev/cel-go/common/types/traits/iterator.go index 91c10f08..f0a0b4cb 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/iterator.go +++ b/vendor/cel.dev/cel-go/common/types/traits/iterator.go @@ -15,7 +15,7 @@ package traits import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // Iterable aggregate types permit traversal over their elements. diff --git a/vendor/github.com/google/cel-go/common/types/traits/lister.go b/vendor/cel.dev/cel-go/common/types/traits/lister.go similarity index 95% rename from vendor/github.com/google/cel-go/common/types/traits/lister.go rename to vendor/cel.dev/cel-go/common/types/traits/lister.go index e54781a6..67f32391 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/lister.go +++ b/vendor/cel.dev/cel-go/common/types/traits/lister.go @@ -14,7 +14,7 @@ package traits -import "github.com/google/cel-go/common/types/ref" +import "cel.dev/cel-go/common/types/ref" // Lister interface which aggregates the traits of a list. type Lister interface { diff --git a/vendor/github.com/google/cel-go/common/types/traits/mapper.go b/vendor/cel.dev/cel-go/common/types/traits/mapper.go similarity index 96% rename from vendor/github.com/google/cel-go/common/types/traits/mapper.go rename to vendor/cel.dev/cel-go/common/types/traits/mapper.go index d13333f3..7a4acedc 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/mapper.go +++ b/vendor/cel.dev/cel-go/common/types/traits/mapper.go @@ -14,7 +14,7 @@ package traits -import "github.com/google/cel-go/common/types/ref" +import "cel.dev/cel-go/common/types/ref" // Mapper interface which aggregates the traits of a maps. type Mapper interface { diff --git a/vendor/github.com/google/cel-go/common/types/traits/matcher.go b/vendor/cel.dev/cel-go/common/types/traits/matcher.go similarity index 93% rename from vendor/github.com/google/cel-go/common/types/traits/matcher.go rename to vendor/cel.dev/cel-go/common/types/traits/matcher.go index 085dc94f..4ea283e9 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/matcher.go +++ b/vendor/cel.dev/cel-go/common/types/traits/matcher.go @@ -14,7 +14,7 @@ package traits -import "github.com/google/cel-go/common/types/ref" +import "cel.dev/cel-go/common/types/ref" // Matcher interface for supporting 'matches()' overloads. type Matcher interface { diff --git a/vendor/github.com/google/cel-go/common/types/traits/math.go b/vendor/cel.dev/cel-go/common/types/traits/math.go similarity index 97% rename from vendor/github.com/google/cel-go/common/types/traits/math.go rename to vendor/cel.dev/cel-go/common/types/traits/math.go index 86d5b913..cb6354f7 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/math.go +++ b/vendor/cel.dev/cel-go/common/types/traits/math.go @@ -14,7 +14,7 @@ package traits -import "github.com/google/cel-go/common/types/ref" +import "cel.dev/cel-go/common/types/ref" // Adder interface to support '+' operator overloads. type Adder interface { diff --git a/vendor/github.com/google/cel-go/common/types/traits/receiver.go b/vendor/cel.dev/cel-go/common/types/traits/receiver.go similarity index 94% rename from vendor/github.com/google/cel-go/common/types/traits/receiver.go rename to vendor/cel.dev/cel-go/common/types/traits/receiver.go index 8f41db45..4760192c 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/receiver.go +++ b/vendor/cel.dev/cel-go/common/types/traits/receiver.go @@ -14,7 +14,7 @@ package traits -import "github.com/google/cel-go/common/types/ref" +import "cel.dev/cel-go/common/types/ref" // Receiver interface for routing instance method calls within a value. type Receiver interface { diff --git a/vendor/github.com/google/cel-go/common/types/traits/sizer.go b/vendor/cel.dev/cel-go/common/types/traits/sizer.go similarity index 94% rename from vendor/github.com/google/cel-go/common/types/traits/sizer.go rename to vendor/cel.dev/cel-go/common/types/traits/sizer.go index b80d2513..8e2e3cf9 100644 --- a/vendor/github.com/google/cel-go/common/types/traits/sizer.go +++ b/vendor/cel.dev/cel-go/common/types/traits/sizer.go @@ -15,7 +15,7 @@ package traits import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // Sizer interface for supporting 'size()' overloads. diff --git a/vendor/github.com/google/cel-go/common/types/traits/traits.go b/vendor/cel.dev/cel-go/common/types/traits/traits.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/traits/traits.go rename to vendor/cel.dev/cel-go/common/types/traits/traits.go diff --git a/vendor/github.com/google/cel-go/common/types/traits/zeroer.go b/vendor/cel.dev/cel-go/common/types/traits/zeroer.go similarity index 100% rename from vendor/github.com/google/cel-go/common/types/traits/zeroer.go rename to vendor/cel.dev/cel-go/common/types/traits/zeroer.go diff --git a/vendor/github.com/google/cel-go/common/types/types.go b/vendor/cel.dev/cel-go/common/types/types.go similarity index 99% rename from vendor/github.com/google/cel-go/common/types/types.go rename to vendor/cel.dev/cel-go/common/types/types.go index 78c77a9b..fc35bddb 100644 --- a/vendor/github.com/google/cel-go/common/types/types.go +++ b/vendor/cel.dev/cel-go/common/types/types.go @@ -21,9 +21,9 @@ import ( "google.golang.org/protobuf/proto" - chkdecls "github.com/google/cel-go/checker/decls" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + chkdecls "cel.dev/cel-go/checker/decls" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" celpb "cel.dev/expr" exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" diff --git a/vendor/github.com/google/cel-go/common/types/uint.go b/vendor/cel.dev/cel-go/common/types/uint.go similarity index 99% rename from vendor/github.com/google/cel-go/common/types/uint.go rename to vendor/cel.dev/cel-go/common/types/uint.go index 91d5369d..6c2bef72 100644 --- a/vendor/github.com/google/cel-go/common/types/uint.go +++ b/vendor/cel.dev/cel-go/common/types/uint.go @@ -21,7 +21,7 @@ import ( "strconv" "strings" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" anypb "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" diff --git a/vendor/github.com/google/cel-go/common/types/unknown.go b/vendor/cel.dev/cel-go/common/types/unknown.go similarity index 99% rename from vendor/github.com/google/cel-go/common/types/unknown.go rename to vendor/cel.dev/cel-go/common/types/unknown.go index f43aff18..96150fc3 100644 --- a/vendor/github.com/google/cel-go/common/types/unknown.go +++ b/vendor/cel.dev/cel-go/common/types/unknown.go @@ -23,7 +23,7 @@ import ( "strings" "unicode" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) var ( diff --git a/vendor/github.com/google/cel-go/common/types/util.go b/vendor/cel.dev/cel-go/common/types/util.go similarity index 96% rename from vendor/github.com/google/cel-go/common/types/util.go rename to vendor/cel.dev/cel-go/common/types/util.go index 71662eee..cb37389f 100644 --- a/vendor/github.com/google/cel-go/common/types/util.go +++ b/vendor/cel.dev/cel-go/common/types/util.go @@ -15,7 +15,7 @@ package types import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // IsUnknownOrError returns whether the input element ref.Val is an ErrType or UnknownType. diff --git a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel b/vendor/cel.dev/cel-go/interpreter/BUILD.bazel similarity index 96% rename from vendor/github.com/google/cel-go/interpreter/BUILD.bazel rename to vendor/cel.dev/cel-go/interpreter/BUILD.bazel index 40ac2ba6..ee1f2ebd 100644 --- a/vendor/github.com/google/cel-go/interpreter/BUILD.bazel +++ b/vendor/cel.dev/cel-go/interpreter/BUILD.bazel @@ -23,11 +23,12 @@ go_library( "prune.go", "runtimecost.go", ], - importpath = "github.com/google/cel-go/interpreter", + importpath = "cel.dev/cel-go/interpreter", deps = [ "//common:go_default_library", "//common/ast:go_default_library", "//common/containers:go_default_library", + "//common/cost:go_default_library", "//common/functions:go_default_library", "//common/operators:go_default_library", "//common/overloads:go_default_library", diff --git a/vendor/github.com/google/cel-go/interpreter/activation.go b/vendor/cel.dev/cel-go/interpreter/activation.go similarity index 99% rename from vendor/github.com/google/cel-go/interpreter/activation.go rename to vendor/cel.dev/cel-go/interpreter/activation.go index bc9296ed..15cbd300 100644 --- a/vendor/github.com/google/cel-go/interpreter/activation.go +++ b/vendor/cel.dev/cel-go/interpreter/activation.go @@ -18,7 +18,7 @@ import ( "errors" "fmt" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // Activation used to resolve identifiers by name and references by id. diff --git a/vendor/github.com/google/cel-go/interpreter/async.go b/vendor/cel.dev/cel-go/interpreter/async.go similarity index 99% rename from vendor/github.com/google/cel-go/interpreter/async.go rename to vendor/cel.dev/cel-go/interpreter/async.go index 4e391196..a678705a 100644 --- a/vendor/github.com/google/cel-go/interpreter/async.go +++ b/vendor/cel.dev/cel-go/interpreter/async.go @@ -23,9 +23,9 @@ import ( "sync" "sync/atomic" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // Async extension function support. diff --git a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go b/vendor/cel.dev/cel-go/interpreter/attribute_patterns.go similarity index 99% rename from vendor/github.com/google/cel-go/interpreter/attribute_patterns.go rename to vendor/cel.dev/cel-go/interpreter/attribute_patterns.go index bbaca522..8e33ddd2 100644 --- a/vendor/github.com/google/cel-go/interpreter/attribute_patterns.go +++ b/vendor/cel.dev/cel-go/interpreter/attribute_patterns.go @@ -18,9 +18,9 @@ import ( "fmt" "strings" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // AttributePattern represents a top-level variable with an optional set of qualifier patterns. diff --git a/vendor/github.com/google/cel-go/interpreter/attributes.go b/vendor/cel.dev/cel-go/interpreter/attributes.go similarity index 99% rename from vendor/github.com/google/cel-go/interpreter/attributes.go rename to vendor/cel.dev/cel-go/interpreter/attributes.go index 26d8eb0f..ce344eb6 100644 --- a/vendor/github.com/google/cel-go/interpreter/attributes.go +++ b/vendor/cel.dev/cel-go/interpreter/attributes.go @@ -18,10 +18,10 @@ import ( "fmt" "strings" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) // AttributeFactory provides methods creating Attribute and Qualifier values. diff --git a/vendor/github.com/google/cel-go/interpreter/decorators.go b/vendor/cel.dev/cel-go/interpreter/decorators.go similarity index 98% rename from vendor/github.com/google/cel-go/interpreter/decorators.go rename to vendor/cel.dev/cel-go/interpreter/decorators.go index 6c48e5c1..7402d18f 100644 --- a/vendor/github.com/google/cel-go/interpreter/decorators.go +++ b/vendor/cel.dev/cel-go/interpreter/decorators.go @@ -17,10 +17,10 @@ package interpreter import ( "fmt" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) // InterpretableDecorator is a functional interface for decorating or replacing diff --git a/vendor/github.com/google/cel-go/interpreter/dispatcher.go b/vendor/cel.dev/cel-go/interpreter/dispatcher.go similarity index 98% rename from vendor/github.com/google/cel-go/interpreter/dispatcher.go rename to vendor/cel.dev/cel-go/interpreter/dispatcher.go index 8f0bdb7b..40efe300 100644 --- a/vendor/github.com/google/cel-go/interpreter/dispatcher.go +++ b/vendor/cel.dev/cel-go/interpreter/dispatcher.go @@ -17,7 +17,7 @@ package interpreter import ( "fmt" - "github.com/google/cel-go/common/functions" + "cel.dev/cel-go/common/functions" ) // Dispatcher resolves function calls to their appropriate overload. diff --git a/vendor/github.com/google/cel-go/interpreter/evalstate.go b/vendor/cel.dev/cel-go/interpreter/evalstate.go similarity index 97% rename from vendor/github.com/google/cel-go/interpreter/evalstate.go rename to vendor/cel.dev/cel-go/interpreter/evalstate.go index 4bdd1fdc..c1ee6ea1 100644 --- a/vendor/github.com/google/cel-go/interpreter/evalstate.go +++ b/vendor/cel.dev/cel-go/interpreter/evalstate.go @@ -15,7 +15,7 @@ package interpreter import ( - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/ref" ) // EvalState tracks the values associated with expression ids during execution. diff --git a/vendor/github.com/google/cel-go/interpreter/frame.go b/vendor/cel.dev/cel-go/interpreter/frame.go similarity index 98% rename from vendor/github.com/google/cel-go/interpreter/frame.go rename to vendor/cel.dev/cel-go/interpreter/frame.go index 20ab313c..2fd93052 100644 --- a/vendor/github.com/google/cel-go/interpreter/frame.go +++ b/vendor/cel.dev/cel-go/interpreter/frame.go @@ -21,9 +21,9 @@ import ( "sync" "sync/atomic" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // evalContext contains the stateful information needed for a single evaluation. diff --git a/vendor/github.com/google/cel-go/interpreter/interpretable.go b/vendor/cel.dev/cel-go/interpreter/interpretable.go similarity index 99% rename from vendor/github.com/google/cel-go/interpreter/interpretable.go rename to vendor/cel.dev/cel-go/interpreter/interpretable.go index 906c4f80..d17e51d1 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpretable.go +++ b/vendor/cel.dev/cel-go/interpreter/interpretable.go @@ -18,12 +18,12 @@ import ( "fmt" "sync" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) // Interpretable evaluates an Activation and produces a value. diff --git a/vendor/github.com/google/cel-go/interpreter/interpreter.go b/vendor/cel.dev/cel-go/interpreter/interpreter.go similarity index 97% rename from vendor/github.com/google/cel-go/interpreter/interpreter.go rename to vendor/cel.dev/cel-go/interpreter/interpreter.go index 29df9d41..e5a583f6 100644 --- a/vendor/github.com/google/cel-go/interpreter/interpreter.go +++ b/vendor/cel.dev/cel-go/interpreter/interpreter.go @@ -20,10 +20,10 @@ package interpreter import ( "errors" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // PlannerOption configures the program plan options during interpretable setup. @@ -101,7 +101,6 @@ func EvalStateObserver(opts ...evalStateOption) PlannerOption { return nil, errors.New("eval state factory not configured") } p.observers = append(p.observers, et) - p.decorators = append(p.decorators, decObserveEval(et.Observe)) return p, nil } } diff --git a/vendor/github.com/google/cel-go/interpreter/optimizations.go b/vendor/cel.dev/cel-go/interpreter/optimizations.go similarity index 94% rename from vendor/github.com/google/cel-go/interpreter/optimizations.go rename to vendor/cel.dev/cel-go/interpreter/optimizations.go index 2fc87e69..c6478fa7 100644 --- a/vendor/github.com/google/cel-go/interpreter/optimizations.go +++ b/vendor/cel.dev/cel-go/interpreter/optimizations.go @@ -17,8 +17,8 @@ package interpreter import ( "regexp" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // MatchesRegexOptimization optimizes the 'matches' standard library function by compiling the regex pattern and diff --git a/vendor/github.com/google/cel-go/interpreter/planner.go b/vendor/cel.dev/cel-go/interpreter/planner.go similarity index 96% rename from vendor/github.com/google/cel-go/interpreter/planner.go rename to vendor/cel.dev/cel-go/interpreter/planner.go index 396a9803..bdf183be 100644 --- a/vendor/github.com/google/cel-go/interpreter/planner.go +++ b/vendor/cel.dev/cel-go/interpreter/planner.go @@ -18,11 +18,12 @@ import ( "fmt" "strings" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/containers" - "github.com/google/cel-go/common/functions" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/types" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/containers" + "cel.dev/cel-go/common/functions" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // newPlanner creates an interpretablePlanner which references a Dispatcher, TypeProvider, @@ -73,6 +74,12 @@ type planBuilder struct { // such as state-tracking, expression re-write, and possibly efficient thread-safe memoization of // repeated expressions. func (p *planner) Plan(expr ast.Expr) (InterpretableV2, error) { + if len(p.observers) != 0 { + // A single decorator reports to every observer. One decorator per observer would not + // work, since the second decorator would find the node already wrapped by the first and + // leave it alone, silently dropping the second observer's observations. + p.decorators = append(p.decorators, decObserveEval(observeAll(p.observers))) + } pb := &planBuilder{planner: p, localVars: make(map[string]int)} i, err := pb.plan(expr) if err != nil { @@ -84,6 +91,18 @@ func (p *planner) Plan(expr ast.Expr) (InterpretableV2, error) { return &ObservableInterpretable{InterpretableV2: i, observers: p.observers}, nil } +// observeAll returns an EvalObserver which reports each observation to all of the observers. +func observeAll(observers []StatefulObserver) EvalObserver { + if len(observers) == 1 { + return observers[0].Observe + } + return func(vars Activation, id int64, programStep any, value ref.Val) { + for _, o := range observers { + o.Observe(vars, id, programStep, value) + } + } +} + func (p *planBuilder) plan(expr ast.Expr) (InterpretableV2, error) { switch expr.Kind() { case ast.CallKind: diff --git a/vendor/github.com/google/cel-go/interpreter/prune.go b/vendor/cel.dev/cel-go/interpreter/prune.go similarity index 98% rename from vendor/github.com/google/cel-go/interpreter/prune.go rename to vendor/cel.dev/cel-go/interpreter/prune.go index 1662c1c1..9f55f1a8 100644 --- a/vendor/github.com/google/cel-go/interpreter/prune.go +++ b/vendor/cel.dev/cel-go/interpreter/prune.go @@ -15,12 +15,12 @@ package interpreter import ( - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) type astPruner struct { diff --git a/vendor/github.com/google/cel-go/interpreter/runtimecost.go b/vendor/cel.dev/cel-go/interpreter/runtimecost.go similarity index 88% rename from vendor/github.com/google/cel-go/interpreter/runtimecost.go rename to vendor/cel.dev/cel-go/interpreter/runtimecost.go index 81e4ef63..5558cf6f 100644 --- a/vendor/github.com/google/cel-go/interpreter/runtimecost.go +++ b/vendor/cel.dev/cel-go/interpreter/runtimecost.go @@ -16,13 +16,13 @@ package interpreter import ( "errors" - "math" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/overloads" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" - "github.com/google/cel-go/common/types/traits" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/cost" + "cel.dev/cel-go/common/overloads" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" + "cel.dev/cel-go/common/types/traits" ) // WARNING: Any changes to cost calculations in this file require a corresponding change in checker/cost.go @@ -57,7 +57,6 @@ func CostObserver(opts ...costTrackPlanOption) PlannerOption { return nil, errors.New("cost tracker factory not configured") } p.observers = append(p.observers, ct) - p.decorators = append(p.decorators, decObserveEval(ct.Observe)) return p, nil } } @@ -255,21 +254,21 @@ func (c *CostTracker) ActualCost() uint64 { } func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result ref.Val) uint64 { - var cost uint64 + var total uint64 if len(c.overloadTrackers) != 0 { if tracker, found := c.overloadTrackers[call.OverloadID()]; found { callCost := tracker(args, result) if callCost != nil { - cost = safeAdd(cost, *callCost) - return cost + total = cost.SafeAdd(total, *callCost) + return total } } } if c.Estimator != nil { callCost := c.Estimator.CallCost(call.Function(), call.OverloadID(), args, result) if callCost != nil { - cost = safeAdd(cost, *callCost) - return cost + total = cost.SafeAdd(total, *callCost) + return total } } // if user didn't specify, the default way of calculating runtime cost would be used. @@ -277,13 +276,13 @@ func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result re switch call.OverloadID() { // O(n) functions case overloads.StartsWithString, overloads.EndsWithString: - cost = safeAdd(cost, uint64(math.Ceil(float64(actualSize(args[1]))*common.StringTraversalCostFactor))) + total = cost.SafeAdd(total, cost.SafeMultiplyByFactor(actualSize(args[1]), common.StringTraversalCostFactor)) case overloads.StringToBytes, overloads.BytesToString, overloads.ExtQuoteString, overloads.ExtFormatString: - cost = safeAdd(cost, uint64(math.Ceil(float64(actualSize(args[0]))*common.StringTraversalCostFactor))) + total = cost.SafeAdd(total, cost.SafeMultiplyByFactor(actualSize(args[0]), common.StringTraversalCostFactor)) case overloads.InList: // If a list is composed entirely of constant values this is O(1), but we don't account for that here. // We just assume all list containment checks are O(n). - cost = safeAdd(cost, actualSize(args[1])) + total = cost.SafeAdd(total, actualSize(args[1])) // O(min(m, n)) functions case overloads.LessString, overloads.GreaterString, overloads.LessEqualsString, overloads.GreaterEqualsString, overloads.LessBytes, overloads.GreaterBytes, overloads.LessEqualsBytes, overloads.GreaterEqualsBytes, @@ -294,28 +293,29 @@ func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result re lhsSize := actualSize(args[0]) rhsSize := actualSize(args[1]) minSize := min(rhsSize, lhsSize) - cost = safeAdd(cost, uint64(math.Ceil(float64(minSize)*common.StringTraversalCostFactor))) + total = cost.SafeAdd(total, cost.SafeMultiplyByFactor(minSize, common.StringTraversalCostFactor)) // O(m+n) functions case overloads.AddString, overloads.AddBytes: // In the worst case scenario, we would need to reallocate a new backing store and copy both operands over. - cost = safeAdd(cost, uint64(math.Ceil(float64(actualSize(args[0])+actualSize(args[1]))*common.StringTraversalCostFactor))) + argSize := cost.SafeAdd(actualSize(args[0]), actualSize(args[1])) + total = cost.SafeAdd(total, cost.SafeMultiplyByFactor(argSize, common.StringTraversalCostFactor)) // O(nm) functions case overloads.Matches, overloads.MatchesString: // https://swtch.com/~rsc/regexp/regexp1.html applies to RE2 implementation supported by CEL // Add one to string length for purposes of cost calculation to prevent product of string and regex to be 0 // in case where string is empty but regex is still expensive. - strCost := uint64(math.Ceil((1.0 + float64(actualSize(args[0]))) * common.StringTraversalCostFactor)) + strCost := cost.SafeMultiplyByFactor(cost.SafeAdd(1, actualSize(args[0])), common.StringTraversalCostFactor) // We don't know how many expressions are in the regex, just the string length (a huge // improvement here would be to somehow get a count the number of expressions in the regex or // how many states are in the regex state machine and use that to measure regex cost). // For now, we're making a guess that each expression in a regex is typically at least 4 chars // in length. - regexCost := uint64(math.Ceil(float64(actualSize(args[1])) * common.RegexStringLengthCostFactor)) - cost = safeAdd(cost, strCost*regexCost) + regexCost := cost.SafeMultiplyByFactor(actualSize(args[1]), common.RegexStringLengthCostFactor) + total = cost.SafeAdd(total, cost.SafeMultiply(strCost, regexCost)) case overloads.ContainsString: - strCost := uint64(math.Ceil(float64(actualSize(args[0])) * common.StringTraversalCostFactor)) - substrCost := uint64(math.Ceil(float64(actualSize(args[1])) * common.StringTraversalCostFactor)) - cost = safeAdd(cost, strCost*substrCost) + strCost := cost.SafeMultiplyByFactor(actualSize(args[0]), common.StringTraversalCostFactor) + substrCost := cost.SafeMultiplyByFactor(actualSize(args[1]), common.StringTraversalCostFactor) + total = cost.SafeAdd(total, cost.SafeMultiply(strCost, substrCost)) default: // The following operations are assumed to have O(1) complexity. @@ -325,10 +325,10 @@ func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result re // - Computing the size of strings, byte sequences, lists and maps. // - Logical operations and all operators on fixed width scalars (comparisons, equality) // - Any functions that don't have a declared cost either here or in provided ActualCostEstimator. - cost = safeAdd(cost, 1) + total = cost.SafeAdd(total, 1) } - return cost + return total } // actualSize returns the size of the value for all traits.Sizer values, a fixed size for all proto-based @@ -396,21 +396,3 @@ argloop: } return result, true } - -func safeAdd(x, y uint64, rest ...uint64) uint64 { - if y > 0 && x > math.MaxUint64-y { - return math.MaxUint64 - } - next := x + y - if len(rest) == 0 { - return next - } - return safeAdd(next, rest[0], rest[1:]...) -} - -func safeMul(x, y uint64) uint64 { - if y != 0 && x > math.MaxUint64/y { - return math.MaxUint64 - } - return x * y -} diff --git a/vendor/github.com/google/cel-go/parser/BUILD.bazel b/vendor/cel.dev/cel-go/parser/BUILD.bazel similarity index 94% rename from vendor/github.com/google/cel-go/parser/BUILD.bazel rename to vendor/cel.dev/cel-go/parser/BUILD.bazel index 97bc9bd4..c6666163 100644 --- a/vendor/github.com/google/cel-go/parser/BUILD.bazel +++ b/vendor/cel.dev/cel-go/parser/BUILD.bazel @@ -16,7 +16,7 @@ go_library( "unescape.go", "unparser.go", ], - importpath = "github.com/google/cel-go/parser", + importpath = "cel.dev/cel-go/parser", visibility = ["//visibility:public"], deps = [ "//common:go_default_library", @@ -48,6 +48,7 @@ go_test( deps = [ "//common/ast:go_default_library", "//common/debug:go_default_library", + "//common/operators:go_default_library", "//common/types:go_default_library", "//parser/gen:go_default_library", "//test:go_default_library", diff --git a/vendor/github.com/google/cel-go/parser/errors.go b/vendor/cel.dev/cel-go/parser/errors.go similarity index 97% rename from vendor/github.com/google/cel-go/parser/errors.go rename to vendor/cel.dev/cel-go/parser/errors.go index c3cec01a..968dbe82 100644 --- a/vendor/github.com/google/cel-go/parser/errors.go +++ b/vendor/cel.dev/cel-go/parser/errors.go @@ -15,7 +15,7 @@ package parser import ( - "github.com/google/cel-go/common" + "cel.dev/cel-go/common" ) // parseErrors is a specialization of Errors. diff --git a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel b/vendor/cel.dev/cel-go/parser/gen/BUILD.bazel similarity index 90% rename from vendor/github.com/google/cel-go/parser/gen/BUILD.bazel rename to vendor/cel.dev/cel-go/parser/gen/BUILD.bazel index 3efed87b..6c0187d5 100644 --- a/vendor/github.com/google/cel-go/parser/gen/BUILD.bazel +++ b/vendor/cel.dev/cel-go/parser/gen/BUILD.bazel @@ -19,7 +19,7 @@ go_library( "CEL.tokens", "CELLexer.tokens", ], - importpath = "github.com/google/cel-go/parser/gen", + importpath = "cel.dev/cel-go/parser/gen", deps = [ "@com_github_antlr4_go_antlr_v4//:go_default_library", ], diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.g4 b/vendor/cel.dev/cel-go/parser/gen/CEL.g4 similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/CEL.g4 rename to vendor/cel.dev/cel-go/parser/gen/CEL.g4 diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.interp b/vendor/cel.dev/cel-go/parser/gen/CEL.interp similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/CEL.interp rename to vendor/cel.dev/cel-go/parser/gen/CEL.interp diff --git a/vendor/github.com/google/cel-go/parser/gen/CEL.tokens b/vendor/cel.dev/cel-go/parser/gen/CEL.tokens similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/CEL.tokens rename to vendor/cel.dev/cel-go/parser/gen/CEL.tokens diff --git a/vendor/github.com/google/cel-go/parser/gen/CELLexer.interp b/vendor/cel.dev/cel-go/parser/gen/CELLexer.interp similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/CELLexer.interp rename to vendor/cel.dev/cel-go/parser/gen/CELLexer.interp diff --git a/vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens b/vendor/cel.dev/cel-go/parser/gen/CELLexer.tokens similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/CELLexer.tokens rename to vendor/cel.dev/cel-go/parser/gen/CELLexer.tokens diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go b/vendor/cel.dev/cel-go/parser/gen/cel_base_listener.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/cel_base_listener.go rename to vendor/cel.dev/cel-go/parser/gen/cel_base_listener.go diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go b/vendor/cel.dev/cel-go/parser/gen/cel_base_visitor.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/cel_base_visitor.go rename to vendor/cel.dev/cel-go/parser/gen/cel_base_visitor.go diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_lexer.go b/vendor/cel.dev/cel-go/parser/gen/cel_lexer.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/cel_lexer.go rename to vendor/cel.dev/cel-go/parser/gen/cel_lexer.go diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_listener.go b/vendor/cel.dev/cel-go/parser/gen/cel_listener.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/cel_listener.go rename to vendor/cel.dev/cel-go/parser/gen/cel_listener.go diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_parser.go b/vendor/cel.dev/cel-go/parser/gen/cel_parser.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/cel_parser.go rename to vendor/cel.dev/cel-go/parser/gen/cel_parser.go diff --git a/vendor/github.com/google/cel-go/parser/gen/cel_visitor.go b/vendor/cel.dev/cel-go/parser/gen/cel_visitor.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/cel_visitor.go rename to vendor/cel.dev/cel-go/parser/gen/cel_visitor.go diff --git a/vendor/github.com/google/cel-go/parser/gen/doc.go b/vendor/cel.dev/cel-go/parser/gen/doc.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/doc.go rename to vendor/cel.dev/cel-go/parser/gen/doc.go diff --git a/vendor/github.com/google/cel-go/parser/gen/generate.sh b/vendor/cel.dev/cel-go/parser/gen/generate.sh similarity index 100% rename from vendor/github.com/google/cel-go/parser/gen/generate.sh rename to vendor/cel.dev/cel-go/parser/gen/generate.sh diff --git a/vendor/github.com/google/cel-go/parser/helper.go b/vendor/cel.dev/cel-go/parser/helper.go similarity index 99% rename from vendor/github.com/google/cel-go/parser/helper.go rename to vendor/cel.dev/cel-go/parser/helper.go index 84bef80d..b043ef54 100644 --- a/vendor/github.com/google/cel-go/parser/helper.go +++ b/vendor/cel.dev/cel-go/parser/helper.go @@ -19,10 +19,10 @@ import ( antlr "github.com/antlr4-go/antlr/v4" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) type parserHelper struct { diff --git a/vendor/github.com/google/cel-go/parser/input.go b/vendor/cel.dev/cel-go/parser/input.go similarity index 98% rename from vendor/github.com/google/cel-go/parser/input.go rename to vendor/cel.dev/cel-go/parser/input.go index 44792455..9ccccd0f 100644 --- a/vendor/github.com/google/cel-go/parser/input.go +++ b/vendor/cel.dev/cel-go/parser/input.go @@ -17,7 +17,7 @@ package parser import ( antlr "github.com/antlr4-go/antlr/v4" - "github.com/google/cel-go/common/runes" + "cel.dev/cel-go/common/runes" ) type charStream struct { diff --git a/vendor/github.com/google/cel-go/parser/macro.go b/vendor/cel.dev/cel-go/parser/macro.go similarity index 99% rename from vendor/github.com/google/cel-go/parser/macro.go rename to vendor/cel.dev/cel-go/parser/macro.go index 1ef43c4b..b9f53d7b 100644 --- a/vendor/github.com/google/cel-go/parser/macro.go +++ b/vendor/cel.dev/cel-go/parser/macro.go @@ -17,11 +17,11 @@ package parser import ( "fmt" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // MacroOpt defines a functional option for configuring macro behavior. diff --git a/vendor/github.com/google/cel-go/parser/options.go b/vendor/cel.dev/cel-go/parser/options.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/options.go rename to vendor/cel.dev/cel-go/parser/options.go diff --git a/vendor/github.com/google/cel-go/parser/parser.go b/vendor/cel.dev/cel-go/parser/parser.go similarity index 99% rename from vendor/github.com/google/cel-go/parser/parser.go rename to vendor/cel.dev/cel-go/parser/parser.go index 33823354..2df20a70 100644 --- a/vendor/github.com/google/cel-go/parser/parser.go +++ b/vendor/cel.dev/cel-go/parser/parser.go @@ -25,12 +25,12 @@ import ( antlr "github.com/antlr4-go/antlr/v4" - "github.com/google/cel-go/common" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/runes" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/parser/gen" + "cel.dev/cel-go/common" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/runes" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/parser/gen" ) // Parser encapsulates the context necessary to perform parsing for different expressions. diff --git a/vendor/github.com/google/cel-go/parser/unescape.go b/vendor/cel.dev/cel-go/parser/unescape.go similarity index 100% rename from vendor/github.com/google/cel-go/parser/unescape.go rename to vendor/cel.dev/cel-go/parser/unescape.go diff --git a/vendor/github.com/google/cel-go/parser/unparser.go b/vendor/cel.dev/cel-go/parser/unparser.go similarity index 99% rename from vendor/github.com/google/cel-go/parser/unparser.go rename to vendor/cel.dev/cel-go/parser/unparser.go index d503a450..8b5fdbdc 100644 --- a/vendor/github.com/google/cel-go/parser/unparser.go +++ b/vendor/cel.dev/cel-go/parser/unparser.go @@ -21,10 +21,10 @@ import ( "strconv" "strings" - "github.com/google/cel-go/common/ast" - "github.com/google/cel-go/common/operators" - "github.com/google/cel-go/common/types" - "github.com/google/cel-go/common/types/ref" + "cel.dev/cel-go/common/ast" + "cel.dev/cel-go/common/operators" + "cel.dev/cel-go/common/types" + "cel.dev/cel-go/common/types/ref" ) // Unparse takes an input expression and source position information and generates a human-readable diff --git a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go index e3ef8e25..d4037b7a 100644 --- a/vendor/github.com/docker/cli/cli/config/credentials/file_store.go +++ b/vendor/github.com/docker/cli/cli/config/credentials/file_store.go @@ -104,7 +104,7 @@ func (c *fileStore) Store(authConfig types.AuthConfig) error { // stored as hostname or as hostname including scheme (in legacy configuration // files). // -// It's the equivalent to [registry.ConvertToHostname] in the daemon. +// It's based on [registry.ConvertToHostname] from Moby daemon. // // [registry.ConvertToHostname]: https://pkg.go.dev/github.com/moby/moby/v2@v2.0.0-beta.7/daemon/pkg/registry#ConvertToHostname func ConvertToHostname(maybeURL string) string { @@ -117,7 +117,48 @@ func ConvertToHostname(maybeURL string) string { } return net.JoinHostPort(u.Hostname(), u.Port()) } + + if hostName := hostFromURLFallback(stripped); hostName != "" { + return hostName + } } hostName, _, _ := strings.Cut(stripped, "/") return hostName } + +// hostFromURLFallback extracts a host from scheme URLs that net/url rejects. +// Go rejects unbracketed IPv6 literals in URL hosts since +// https://github.com/golang/go/commit/0c28789bd7dfc55099cac86a3212dda0d6c091f6 +func hostFromURLFallback(maybeURL string) string { + _, rest, ok := strings.Cut(maybeURL, "://") + if !ok { + return "" + } + + hostName, _, _ := strings.Cut(rest, "/") + if hostName == "" { + return "" + } + + if strings.Count(hostName, ":") > 1 && !strings.HasPrefix(hostName, "[") { + portStart := strings.LastIndex(hostName, ":") + addr, port := hostName[:portStart], hostName[portStart+1:] + if addr != "" && isPort(port) { + return net.JoinHostPort(addr, port) + } + } + + return hostName +} + +func isPort(port string) bool { + if port == "" { + return false + } + for _, r := range port { + if r < '0' || r > '9' { + return false + } + } + return true +} diff --git a/vendor/github.com/emicklei/go-restful/v3/.travis.yml b/vendor/github.com/emicklei/go-restful/v3/.travis.yml deleted file mode 100644 index 3a0bf5ff..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go - -go: - - 1.x - -before_install: - - go test -v - -script: - - go test -race -coverprofile=coverage.txt -covermode=atomic - -after_success: - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md index 6f24dfff..4fcd920a 100644 --- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md @@ -1,5 +1,9 @@ # Change history of go-restful +## [v3.13.0] - 2025-08-14 + +- optimize performance of path matching in CurlyRouter ( thanks @wenhuang, Wen Huang) + ## [v3.12.2] - 2025-02-21 - allow empty payloads in post,put,patch, issue #580 ( thanks @liggitt, Jordan Liggitt) diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md index 3fb40d19..50a79ab6 100644 --- a/vendor/github.com/emicklei/go-restful/v3/README.md +++ b/vendor/github.com/emicklei/go-restful/v3/README.md @@ -84,6 +84,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo - Configurable (trace) logging - Customizable gzip/deflate readers and writers using CompressorProvider registration - Inject your own http.Handler using the `HttpMiddlewareHandlerToFilter` function +- Added `SetPathTokenCacheEnabled` and `SetCustomVerbCacheEnabled` to disable regexp caching (default=true) ## How to customize There are several hooks to customize the behavior of the go-restful package. diff --git a/vendor/github.com/emicklei/go-restful/v3/curly.go b/vendor/github.com/emicklei/go-restful/v3/curly.go index 6fd2bcd5..eec43bfd 100644 --- a/vendor/github.com/emicklei/go-restful/v3/curly.go +++ b/vendor/github.com/emicklei/go-restful/v3/curly.go @@ -9,11 +9,35 @@ import ( "regexp" "sort" "strings" + "sync" ) // CurlyRouter expects Routes with paths that contain zero or more parameters in curly brackets. type CurlyRouter struct{} +var ( + regexCache sync.Map // Cache for compiled regex patterns + pathTokenCacheEnabled = true // Enable/disable path token regex caching +) + +// SetPathTokenCacheEnabled enables or disables path token regex caching for CurlyRouter. +// When disabled, regex patterns will be compiled on every request. +// When enabled (default), compiled regex patterns are cached for better performance. +func SetPathTokenCacheEnabled(enabled bool) { + pathTokenCacheEnabled = enabled +} + +// getCachedRegexp retrieves a compiled regex from the cache if found and valid. +// Returns the regex and true if found and valid, nil and false otherwise. +func getCachedRegexp(cache *sync.Map, pattern string) (*regexp.Regexp, bool) { + if cached, found := cache.Load(pattern); found { + if regex, ok := cached.(*regexp.Regexp); ok { + return regex, true + } + } + return nil, false +} + // SelectRoute is part of the Router interface and returns the best match // for the WebService and its Route for the given Request. func (c CurlyRouter) SelectRoute( @@ -113,8 +137,28 @@ func (c CurlyRouter) regularMatchesPathToken(routeToken string, colon int, reque } return true, true } - matched, err := regexp.MatchString(regPart, requestToken) - return (matched && err == nil), false + + // Check cache first (if enabled) + if pathTokenCacheEnabled { + if regex, found := getCachedRegexp(®exCache, regPart); found { + matched := regex.MatchString(requestToken) + return matched, false + } + } + + // Compile the regex + regex, err := regexp.Compile(regPart) + if err != nil { + return false, false + } + + // Cache the regex (if enabled) + if pathTokenCacheEnabled { + regexCache.Store(regPart, regex) + } + + matched := regex.MatchString(requestToken) + return matched, false } var jsr311Router = RouterJSR311{} @@ -168,7 +212,7 @@ func (c CurlyRouter) computeWebserviceScore(requestTokens []string, routeTokens if matchesToken { score++ // extra score for regex match } - } + } } else { // not a parameter if eachRequestToken != eachRouteToken { diff --git a/vendor/github.com/emicklei/go-restful/v3/custom_verb.go b/vendor/github.com/emicklei/go-restful/v3/custom_verb.go index bfc17efd..0b98eeb0 100644 --- a/vendor/github.com/emicklei/go-restful/v3/custom_verb.go +++ b/vendor/github.com/emicklei/go-restful/v3/custom_verb.go @@ -1,14 +1,28 @@ package restful +// Copyright 2025 Ernest Micklei. All rights reserved. +// Use of this source code is governed by a license +// that can be found in the LICENSE file. + import ( "fmt" "regexp" + "sync" ) var ( - customVerbReg = regexp.MustCompile(":([A-Za-z]+)$") + customVerbReg = regexp.MustCompile(":([A-Za-z]+)$") + customVerbCache sync.Map // Cache for compiled custom verb regexes + customVerbCacheEnabled = true // Enable/disable custom verb regex caching ) +// SetCustomVerbCacheEnabled enables or disables custom verb regex caching. +// When disabled, custom verb regex patterns will be compiled on every request. +// When enabled (default), compiled custom verb regex patterns are cached for better performance. +func SetCustomVerbCacheEnabled(enabled bool) { + customVerbCacheEnabled = enabled +} + func hasCustomVerb(routeToken string) bool { return customVerbReg.MatchString(routeToken) } @@ -20,7 +34,23 @@ func isMatchCustomVerb(routeToken string, pathToken string) bool { } customVerb := rs[1] - specificVerbReg := regexp.MustCompile(fmt.Sprintf(":%s$", customVerb)) + regexPattern := fmt.Sprintf(":%s$", customVerb) + + // Check cache first (if enabled) + if customVerbCacheEnabled { + if specificVerbReg, found := getCachedRegexp(&customVerbCache, regexPattern); found { + return specificVerbReg.MatchString(pathToken) + } + } + + // Compile the regex + specificVerbReg := regexp.MustCompile(regexPattern) + + // Cache the regex (if enabled) + if customVerbCacheEnabled { + customVerbCache.Store(regexPattern, specificVerbReg) + } + return specificVerbReg.MatchString(pathToken) } diff --git a/vendor/github.com/emicklei/go-restful/v3/doc.go b/vendor/github.com/emicklei/go-restful/v3/doc.go index 69b13057..80809225 100644 --- a/vendor/github.com/emicklei/go-restful/v3/doc.go +++ b/vendor/github.com/emicklei/go-restful/v3/doc.go @@ -1,7 +1,7 @@ /* Package restful , a lean package for creating REST-style WebServices without magic. -WebServices and Routes +### WebServices and Routes A WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls. Typically, a WebService has a root path (e.g. /users) and defines common MIME types for its routes. @@ -30,14 +30,14 @@ The (*Request, *Response) arguments provide functions for reading information fr See the example https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go with a full implementation. -Regular expression matching Routes +### Regular expression matching Routes A Route parameter can be specified using the format "uri/{var[:regexp]}" or the special version "uri/{var:*}" for matching the tail of the path. For example, /persons/{name:[A-Z][A-Z]} can be used to restrict values for the parameter "name" to only contain capital alphabetic characters. Regular expressions must use the standard Go syntax as described in the regexp package. (https://code.google.com/p/re2/wiki/Syntax) This feature requires the use of a CurlyRouter. -Containers +### Containers A Container holds a collection of WebServices, Filters and a http.ServeMux for multiplexing http requests. Using the statements "restful.Add(...) and restful.Filter(...)" will register WebServices and Filters to the Default Container. @@ -47,7 +47,7 @@ You can create your own Container and create a new http.Server for that particul container := restful.NewContainer() server := &http.Server{Addr: ":8081", Handler: container} -Filters +### Filters A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. You can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc. @@ -60,22 +60,21 @@ Use the following statement to pass the request,response pair to the next filter chain.ProcessFilter(req, resp) -Container Filters +### Container Filters These are processed before any registered WebService. // install a (global) filter for the default container (processed before any webservice) restful.Filter(globalLogging) -WebService Filters +### WebService Filters These are processed before any Route of a WebService. // install a webservice filter (processed before any route) ws.Filter(webserviceLogging).Filter(measureTime) - -Route Filters +### Route Filters These are processed before calling the function associated with the Route. @@ -84,7 +83,7 @@ These are processed before calling the function associated with the Route. See the example https://github.com/emicklei/go-restful/blob/v3/examples/filters/restful-filters.go with full implementations. -Response Encoding +### Response Encoding Two encodings are supported: gzip and deflate. To enable this for all responses: @@ -95,20 +94,20 @@ Alternatively, you can create a Filter that performs the encoding and install it See the example https://github.com/emicklei/go-restful/blob/v3/examples/encoding/restful-encoding-filter.go -OPTIONS support +### OPTIONS support By installing a pre-defined container filter, your Webservice(s) can respond to the OPTIONS Http request. Filter(OPTIONSFilter()) -CORS +### CORS By installing the filter of a CrossOriginResourceSharing (CORS), your WebService(s) can handle CORS requests. cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer} Filter(cors.Filter) -Error Handling +### Error Handling Unexpected things happen. If a request cannot be processed because of a failure, your service needs to tell via the response what happened and why. For this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation. @@ -137,11 +136,11 @@ The request does not have or has an unknown Accept Header set for this operation The request does not have or has an unknown Content-Type Header set for this operation. -ServiceError +### ServiceError In addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response. -Performance options +### Performance options This package has several options that affect the performance of your service. It is important to understand them and how you can change it. @@ -156,30 +155,27 @@ Default value is true If content encoding is enabled then the default strategy for getting new gzip/zlib writers and readers is to use a sync.Pool. Because writers are expensive structures, performance is even more improved when using a preloaded cache. You can also inject your own implementation. -Trouble shooting +### Trouble shooting This package has the means to produce detail logging of the complete Http request matching process and filter invocation. Enabling this feature requires you to set an implementation of restful.StdLogger (e.g. log.Logger) instance such as: restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile)) -Logging +### Logging The restful.SetLogger() method allows you to override the logger used by the package. By default restful uses the standard library `log` package and logs to stdout. Different logging packages are supported as long as they conform to `StdLogger` interface defined in the `log` sub-package, writing an adapter for your preferred package is simple. -Resources +### Resources -[project]: https://github.com/emicklei/go-restful +(c) 2012-2025, http://ernestmicklei.com. MIT License +[project]: https://github.com/emicklei/go-restful [examples]: https://github.com/emicklei/go-restful/blob/master/examples - -[design]: http://ernestmicklei.com/2012/11/11/go-restful-api-design/ - +[design]: http://ernestmicklei.com/2012/11/11/go-restful-api-design/ [showcases]: https://github.com/emicklei/mora, https://github.com/emicklei/landskape - -(c) 2012-2015, http://ernestmicklei.com. MIT License */ package restful diff --git a/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/vendor/github.com/felixge/httpsnoop/capture_metrics.go index bec7b71b..97f0a51d 100644 --- a/vendor/github.com/felixge/httpsnoop/capture_metrics.go +++ b/vendor/github.com/felixge/httpsnoop/capture_metrics.go @@ -69,6 +69,16 @@ func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWri } }, + WriteString: func(next WriteStringFunc) WriteStringFunc { + return func(s string) (int, error) { + n, err := next(s) + + m.Written += int64(n) + headerWritten = true + return n, err + } + }, + ReadFrom: func(next ReadFromFunc) ReadFromFunc { return func(src io.Reader) (int64, error) { n, err := next(src) @@ -81,6 +91,31 @@ func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWri } ) + // defer to ensure duration is updated even if the handler panics + defer func() { + m.Duration += time.Since(start) + }() fn(Wrap(w, hooks)) - m.Duration += time.Since(start) +} + +// deadliner defines two methods introduced in go 1.20. The standard library +// seems not to provide an interface we can import, hence its definition here. +type deadliner interface { + SetReadDeadline(deadline time.Time) error + SetWriteDeadline(deadline time.Time) error +} + +// fullDuplexEnabler defines a method introduced in go 1.21. The standard +// library seems not to provide an interface we can import, hence its definition +// here. +type fullDuplexEnabler interface { + EnableFullDuplex() error +} + +// httpFlushError defines a method introduced in go 1.20. The standard +// library seems not to provide an interface we can import, hence its definition +// here. +// See https://github.com/golang/go/blob/go1.20/src/net/http/responsecontroller.go#L50 +type httpFlushError interface { + FlushError() error } diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated.go b/vendor/github.com/felixge/httpsnoop/wrap_generated.go new file mode 100644 index 00000000..b6549ba9 --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/wrap_generated.go @@ -0,0 +1,16179 @@ +// Code generated by "httpsnoop/codegen"; DO NOT EDIT. + +package httpsnoop + +import ( + "bufio" + "io" + "net" + "net/http" + "time" +) + +// HeaderFunc is part of the http.ResponseWriter interface. +type HeaderFunc func() http.Header + +// WriteHeaderFunc is part of the http.ResponseWriter interface. +type WriteHeaderFunc func(code int) + +// WriteFunc is part of the http.ResponseWriter interface. +type WriteFunc func(b []byte) (int, error) + +// FlushFunc is part of the http.Flusher interface. +type FlushFunc func() + +// FlushErrorFunc is part of the httpFlushError interface. +type FlushErrorFunc func() error + +// CloseNotifyFunc is part of the http.CloseNotifier interface. +type CloseNotifyFunc func() <-chan bool + +// HijackFunc is part of the http.Hijacker interface. +type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) + +// ReadFromFunc is part of the io.ReaderFrom interface. +type ReadFromFunc func(src io.Reader) (int64, error) + +// SetReadDeadlineFunc is part of the deadliner interface. +type SetReadDeadlineFunc func(deadline time.Time) error + +// SetWriteDeadlineFunc is part of the deadliner interface. +type SetWriteDeadlineFunc func(deadline time.Time) error + +// EnableFullDuplexFunc is part of the fullDuplexEnabler interface. +type EnableFullDuplexFunc func() error + +// PushFunc is part of the http.Pusher interface. +type PushFunc func(target string, opts *http.PushOptions) error + +// WriteStringFunc is part of the io.StringWriter interface. +type WriteStringFunc func(s string) (int, error) + +// Hooks defines a set of method interceptors for methods included in +// http.ResponseWriter as well as some others. You can think of them as +// middleware for the function calls they target. See Wrap for more details. +// +// For each method, the exact matching hook takes precedence. For example, +// WriteString calls the WriteString hook when it is configured, even if a +// Write hook is also configured. If the exact hook is not configured, most +// methods call through to the underlying ResponseWriter directly. +// +// Two compatibility fallbacks preserve the behavior users had before Wrap +// learned about newer optional interfaces: +// - If the underlying ResponseWriter implements io.StringWriter and +// WriteString is called, but only the Write hook is configured, WriteString +// is routed through the Write hook with []byte(s). If neither hook is +// configured, WriteString calls the underlying WriteString method directly. +// - If the underlying ResponseWriter implements both http.Flusher and +// FlushError, and FlushError is called, but only the Flush hook is +// configured, FlushError is routed through the Flush hook while preserving +// the error returned by the underlying FlushError method. If neither hook is +// configured, FlushError calls the underlying FlushError method directly. +type Hooks struct { + Header func(HeaderFunc) HeaderFunc + WriteHeader func(WriteHeaderFunc) WriteHeaderFunc + Write func(WriteFunc) WriteFunc + Flush func(FlushFunc) FlushFunc + FlushError func(FlushErrorFunc) FlushErrorFunc + CloseNotify func(CloseNotifyFunc) CloseNotifyFunc + Hijack func(HijackFunc) HijackFunc + ReadFrom func(ReadFromFunc) ReadFromFunc + SetReadDeadline func(SetReadDeadlineFunc) SetReadDeadlineFunc + SetWriteDeadline func(SetWriteDeadlineFunc) SetWriteDeadlineFunc + EnableFullDuplex func(EnableFullDuplexFunc) EnableFullDuplexFunc + Push func(PushFunc) PushFunc + WriteString func(WriteStringFunc) WriteStringFunc +} + +// Wrap returns a wrapped version of w that provides the exact same interface +// as w. Specifically if w implements any combination of: +// +// - http.Flusher +// - httpFlushError +// - http.CloseNotifier +// - http.Hijacker +// - io.ReaderFrom +// - deadliner +// - fullDuplexEnabler +// - http.Pusher +// - io.StringWriter +// +// The wrapped version will implement the exact same combination. If no hooks +// are set, the wrapped version also behaves exactly as w. Hooks targeting +// methods not supported by w are ignored. Any other hooks will intercept the +// method they target and may modify the call's arguments and/or return values. +// The CaptureMetrics implementation serves as a working example for how the +// hooks can be used. +func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { + state := &rwState{w: w} + var combo uint16 + if hooks.Header != nil { + state.header = hooks.Header(w.Header) + } + if hooks.WriteHeader != nil { + state.writeHeader = hooks.WriteHeader(w.WriteHeader) + } + if hooks.Write != nil { + state.write = hooks.Write(w.Write) + } + if t0, i0 := w.(http.Flusher); i0 { + combo |= 1 << 8 + if hooks.Flush != nil { + state.flush = hooks.Flush(t0.Flush) + } + } + if t1, i1 := w.(httpFlushError); i1 { + combo |= 1 << 7 + if hooks.FlushError != nil { + state.flushError = hooks.FlushError(t1.FlushError) + } else if state.flush != nil { + state.flushError = func() (err error) { hooks.Flush(func() { err = t1.FlushError() })(); return err } + } + } + if t2, i2 := w.(http.CloseNotifier); i2 { + combo |= 1 << 6 + if hooks.CloseNotify != nil { + state.closeNotify = hooks.CloseNotify(t2.CloseNotify) + } + } + if t3, i3 := w.(http.Hijacker); i3 { + combo |= 1 << 5 + if hooks.Hijack != nil { + state.hijack = hooks.Hijack(t3.Hijack) + } + } + if t4, i4 := w.(io.ReaderFrom); i4 { + combo |= 1 << 4 + if hooks.ReadFrom != nil { + state.readFrom = hooks.ReadFrom(t4.ReadFrom) + } + } + if t5, i5 := w.(deadliner); i5 { + combo |= 1 << 3 + if hooks.SetReadDeadline != nil { + state.setReadDeadline = hooks.SetReadDeadline(t5.SetReadDeadline) + } + if hooks.SetWriteDeadline != nil { + state.setWriteDeadline = hooks.SetWriteDeadline(t5.SetWriteDeadline) + } + } + if t6, i6 := w.(fullDuplexEnabler); i6 { + combo |= 1 << 2 + if hooks.EnableFullDuplex != nil { + state.enableFullDuplex = hooks.EnableFullDuplex(t6.EnableFullDuplex) + } + } + if t7, i7 := w.(http.Pusher); i7 { + combo |= 1 << 1 + if hooks.Push != nil { + state.push = hooks.Push(t7.Push) + } + } + if t8, i8 := w.(io.StringWriter); i8 { + combo |= 1 << 0 + if hooks.WriteString != nil { + state.writeString = hooks.WriteString(t8.WriteString) + } else if state.write != nil { + state.writeString = func(s string) (int, error) { return state.write([]byte(s)) } + } + } + switch combo { + case 0: + return (*rw0)(state) + case 1: + return (*rw1)(state) + case 2: + return (*rw2)(state) + case 3: + return (*rw3)(state) + case 4: + return (*rw4)(state) + case 5: + return (*rw5)(state) + case 6: + return (*rw6)(state) + case 7: + return (*rw7)(state) + case 8: + return (*rw8)(state) + case 9: + return (*rw9)(state) + case 10: + return (*rw10)(state) + case 11: + return (*rw11)(state) + case 12: + return (*rw12)(state) + case 13: + return (*rw13)(state) + case 14: + return (*rw14)(state) + case 15: + return (*rw15)(state) + case 16: + return (*rw16)(state) + case 17: + return (*rw17)(state) + case 18: + return (*rw18)(state) + case 19: + return (*rw19)(state) + case 20: + return (*rw20)(state) + case 21: + return (*rw21)(state) + case 22: + return (*rw22)(state) + case 23: + return (*rw23)(state) + case 24: + return (*rw24)(state) + case 25: + return (*rw25)(state) + case 26: + return (*rw26)(state) + case 27: + return (*rw27)(state) + case 28: + return (*rw28)(state) + case 29: + return (*rw29)(state) + case 30: + return (*rw30)(state) + case 31: + return (*rw31)(state) + case 32: + return (*rw32)(state) + case 33: + return (*rw33)(state) + case 34: + return (*rw34)(state) + case 35: + return (*rw35)(state) + case 36: + return (*rw36)(state) + case 37: + return (*rw37)(state) + case 38: + return (*rw38)(state) + case 39: + return (*rw39)(state) + case 40: + return (*rw40)(state) + case 41: + return (*rw41)(state) + case 42: + return (*rw42)(state) + case 43: + return (*rw43)(state) + case 44: + return (*rw44)(state) + case 45: + return (*rw45)(state) + case 46: + return (*rw46)(state) + case 47: + return (*rw47)(state) + case 48: + return (*rw48)(state) + case 49: + return (*rw49)(state) + case 50: + return (*rw50)(state) + case 51: + return (*rw51)(state) + case 52: + return (*rw52)(state) + case 53: + return (*rw53)(state) + case 54: + return (*rw54)(state) + case 55: + return (*rw55)(state) + case 56: + return (*rw56)(state) + case 57: + return (*rw57)(state) + case 58: + return (*rw58)(state) + case 59: + return (*rw59)(state) + case 60: + return (*rw60)(state) + case 61: + return (*rw61)(state) + case 62: + return (*rw62)(state) + case 63: + return (*rw63)(state) + case 64: + return (*rw64)(state) + case 65: + return (*rw65)(state) + case 66: + return (*rw66)(state) + case 67: + return (*rw67)(state) + case 68: + return (*rw68)(state) + case 69: + return (*rw69)(state) + case 70: + return (*rw70)(state) + case 71: + return (*rw71)(state) + case 72: + return (*rw72)(state) + case 73: + return (*rw73)(state) + case 74: + return (*rw74)(state) + case 75: + return (*rw75)(state) + case 76: + return (*rw76)(state) + case 77: + return (*rw77)(state) + case 78: + return (*rw78)(state) + case 79: + return (*rw79)(state) + case 80: + return (*rw80)(state) + case 81: + return (*rw81)(state) + case 82: + return (*rw82)(state) + case 83: + return (*rw83)(state) + case 84: + return (*rw84)(state) + case 85: + return (*rw85)(state) + case 86: + return (*rw86)(state) + case 87: + return (*rw87)(state) + case 88: + return (*rw88)(state) + case 89: + return (*rw89)(state) + case 90: + return (*rw90)(state) + case 91: + return (*rw91)(state) + case 92: + return (*rw92)(state) + case 93: + return (*rw93)(state) + case 94: + return (*rw94)(state) + case 95: + return (*rw95)(state) + case 96: + return (*rw96)(state) + case 97: + return (*rw97)(state) + case 98: + return (*rw98)(state) + case 99: + return (*rw99)(state) + case 100: + return (*rw100)(state) + case 101: + return (*rw101)(state) + case 102: + return (*rw102)(state) + case 103: + return (*rw103)(state) + case 104: + return (*rw104)(state) + case 105: + return (*rw105)(state) + case 106: + return (*rw106)(state) + case 107: + return (*rw107)(state) + case 108: + return (*rw108)(state) + case 109: + return (*rw109)(state) + case 110: + return (*rw110)(state) + case 111: + return (*rw111)(state) + case 112: + return (*rw112)(state) + case 113: + return (*rw113)(state) + case 114: + return (*rw114)(state) + case 115: + return (*rw115)(state) + case 116: + return (*rw116)(state) + case 117: + return (*rw117)(state) + case 118: + return (*rw118)(state) + case 119: + return (*rw119)(state) + case 120: + return (*rw120)(state) + case 121: + return (*rw121)(state) + case 122: + return (*rw122)(state) + case 123: + return (*rw123)(state) + case 124: + return (*rw124)(state) + case 125: + return (*rw125)(state) + case 126: + return (*rw126)(state) + case 127: + return (*rw127)(state) + case 128: + return (*rw128)(state) + case 129: + return (*rw129)(state) + case 130: + return (*rw130)(state) + case 131: + return (*rw131)(state) + case 132: + return (*rw132)(state) + case 133: + return (*rw133)(state) + case 134: + return (*rw134)(state) + case 135: + return (*rw135)(state) + case 136: + return (*rw136)(state) + case 137: + return (*rw137)(state) + case 138: + return (*rw138)(state) + case 139: + return (*rw139)(state) + case 140: + return (*rw140)(state) + case 141: + return (*rw141)(state) + case 142: + return (*rw142)(state) + case 143: + return (*rw143)(state) + case 144: + return (*rw144)(state) + case 145: + return (*rw145)(state) + case 146: + return (*rw146)(state) + case 147: + return (*rw147)(state) + case 148: + return (*rw148)(state) + case 149: + return (*rw149)(state) + case 150: + return (*rw150)(state) + case 151: + return (*rw151)(state) + case 152: + return (*rw152)(state) + case 153: + return (*rw153)(state) + case 154: + return (*rw154)(state) + case 155: + return (*rw155)(state) + case 156: + return (*rw156)(state) + case 157: + return (*rw157)(state) + case 158: + return (*rw158)(state) + case 159: + return (*rw159)(state) + case 160: + return (*rw160)(state) + case 161: + return (*rw161)(state) + case 162: + return (*rw162)(state) + case 163: + return (*rw163)(state) + case 164: + return (*rw164)(state) + case 165: + return (*rw165)(state) + case 166: + return (*rw166)(state) + case 167: + return (*rw167)(state) + case 168: + return (*rw168)(state) + case 169: + return (*rw169)(state) + case 170: + return (*rw170)(state) + case 171: + return (*rw171)(state) + case 172: + return (*rw172)(state) + case 173: + return (*rw173)(state) + case 174: + return (*rw174)(state) + case 175: + return (*rw175)(state) + case 176: + return (*rw176)(state) + case 177: + return (*rw177)(state) + case 178: + return (*rw178)(state) + case 179: + return (*rw179)(state) + case 180: + return (*rw180)(state) + case 181: + return (*rw181)(state) + case 182: + return (*rw182)(state) + case 183: + return (*rw183)(state) + case 184: + return (*rw184)(state) + case 185: + return (*rw185)(state) + case 186: + return (*rw186)(state) + case 187: + return (*rw187)(state) + case 188: + return (*rw188)(state) + case 189: + return (*rw189)(state) + case 190: + return (*rw190)(state) + case 191: + return (*rw191)(state) + case 192: + return (*rw192)(state) + case 193: + return (*rw193)(state) + case 194: + return (*rw194)(state) + case 195: + return (*rw195)(state) + case 196: + return (*rw196)(state) + case 197: + return (*rw197)(state) + case 198: + return (*rw198)(state) + case 199: + return (*rw199)(state) + case 200: + return (*rw200)(state) + case 201: + return (*rw201)(state) + case 202: + return (*rw202)(state) + case 203: + return (*rw203)(state) + case 204: + return (*rw204)(state) + case 205: + return (*rw205)(state) + case 206: + return (*rw206)(state) + case 207: + return (*rw207)(state) + case 208: + return (*rw208)(state) + case 209: + return (*rw209)(state) + case 210: + return (*rw210)(state) + case 211: + return (*rw211)(state) + case 212: + return (*rw212)(state) + case 213: + return (*rw213)(state) + case 214: + return (*rw214)(state) + case 215: + return (*rw215)(state) + case 216: + return (*rw216)(state) + case 217: + return (*rw217)(state) + case 218: + return (*rw218)(state) + case 219: + return (*rw219)(state) + case 220: + return (*rw220)(state) + case 221: + return (*rw221)(state) + case 222: + return (*rw222)(state) + case 223: + return (*rw223)(state) + case 224: + return (*rw224)(state) + case 225: + return (*rw225)(state) + case 226: + return (*rw226)(state) + case 227: + return (*rw227)(state) + case 228: + return (*rw228)(state) + case 229: + return (*rw229)(state) + case 230: + return (*rw230)(state) + case 231: + return (*rw231)(state) + case 232: + return (*rw232)(state) + case 233: + return (*rw233)(state) + case 234: + return (*rw234)(state) + case 235: + return (*rw235)(state) + case 236: + return (*rw236)(state) + case 237: + return (*rw237)(state) + case 238: + return (*rw238)(state) + case 239: + return (*rw239)(state) + case 240: + return (*rw240)(state) + case 241: + return (*rw241)(state) + case 242: + return (*rw242)(state) + case 243: + return (*rw243)(state) + case 244: + return (*rw244)(state) + case 245: + return (*rw245)(state) + case 246: + return (*rw246)(state) + case 247: + return (*rw247)(state) + case 248: + return (*rw248)(state) + case 249: + return (*rw249)(state) + case 250: + return (*rw250)(state) + case 251: + return (*rw251)(state) + case 252: + return (*rw252)(state) + case 253: + return (*rw253)(state) + case 254: + return (*rw254)(state) + case 255: + return (*rw255)(state) + case 256: + return (*rw256)(state) + case 257: + return (*rw257)(state) + case 258: + return (*rw258)(state) + case 259: + return (*rw259)(state) + case 260: + return (*rw260)(state) + case 261: + return (*rw261)(state) + case 262: + return (*rw262)(state) + case 263: + return (*rw263)(state) + case 264: + return (*rw264)(state) + case 265: + return (*rw265)(state) + case 266: + return (*rw266)(state) + case 267: + return (*rw267)(state) + case 268: + return (*rw268)(state) + case 269: + return (*rw269)(state) + case 270: + return (*rw270)(state) + case 271: + return (*rw271)(state) + case 272: + return (*rw272)(state) + case 273: + return (*rw273)(state) + case 274: + return (*rw274)(state) + case 275: + return (*rw275)(state) + case 276: + return (*rw276)(state) + case 277: + return (*rw277)(state) + case 278: + return (*rw278)(state) + case 279: + return (*rw279)(state) + case 280: + return (*rw280)(state) + case 281: + return (*rw281)(state) + case 282: + return (*rw282)(state) + case 283: + return (*rw283)(state) + case 284: + return (*rw284)(state) + case 285: + return (*rw285)(state) + case 286: + return (*rw286)(state) + case 287: + return (*rw287)(state) + case 288: + return (*rw288)(state) + case 289: + return (*rw289)(state) + case 290: + return (*rw290)(state) + case 291: + return (*rw291)(state) + case 292: + return (*rw292)(state) + case 293: + return (*rw293)(state) + case 294: + return (*rw294)(state) + case 295: + return (*rw295)(state) + case 296: + return (*rw296)(state) + case 297: + return (*rw297)(state) + case 298: + return (*rw298)(state) + case 299: + return (*rw299)(state) + case 300: + return (*rw300)(state) + case 301: + return (*rw301)(state) + case 302: + return (*rw302)(state) + case 303: + return (*rw303)(state) + case 304: + return (*rw304)(state) + case 305: + return (*rw305)(state) + case 306: + return (*rw306)(state) + case 307: + return (*rw307)(state) + case 308: + return (*rw308)(state) + case 309: + return (*rw309)(state) + case 310: + return (*rw310)(state) + case 311: + return (*rw311)(state) + case 312: + return (*rw312)(state) + case 313: + return (*rw313)(state) + case 314: + return (*rw314)(state) + case 315: + return (*rw315)(state) + case 316: + return (*rw316)(state) + case 317: + return (*rw317)(state) + case 318: + return (*rw318)(state) + case 319: + return (*rw319)(state) + case 320: + return (*rw320)(state) + case 321: + return (*rw321)(state) + case 322: + return (*rw322)(state) + case 323: + return (*rw323)(state) + case 324: + return (*rw324)(state) + case 325: + return (*rw325)(state) + case 326: + return (*rw326)(state) + case 327: + return (*rw327)(state) + case 328: + return (*rw328)(state) + case 329: + return (*rw329)(state) + case 330: + return (*rw330)(state) + case 331: + return (*rw331)(state) + case 332: + return (*rw332)(state) + case 333: + return (*rw333)(state) + case 334: + return (*rw334)(state) + case 335: + return (*rw335)(state) + case 336: + return (*rw336)(state) + case 337: + return (*rw337)(state) + case 338: + return (*rw338)(state) + case 339: + return (*rw339)(state) + case 340: + return (*rw340)(state) + case 341: + return (*rw341)(state) + case 342: + return (*rw342)(state) + case 343: + return (*rw343)(state) + case 344: + return (*rw344)(state) + case 345: + return (*rw345)(state) + case 346: + return (*rw346)(state) + case 347: + return (*rw347)(state) + case 348: + return (*rw348)(state) + case 349: + return (*rw349)(state) + case 350: + return (*rw350)(state) + case 351: + return (*rw351)(state) + case 352: + return (*rw352)(state) + case 353: + return (*rw353)(state) + case 354: + return (*rw354)(state) + case 355: + return (*rw355)(state) + case 356: + return (*rw356)(state) + case 357: + return (*rw357)(state) + case 358: + return (*rw358)(state) + case 359: + return (*rw359)(state) + case 360: + return (*rw360)(state) + case 361: + return (*rw361)(state) + case 362: + return (*rw362)(state) + case 363: + return (*rw363)(state) + case 364: + return (*rw364)(state) + case 365: + return (*rw365)(state) + case 366: + return (*rw366)(state) + case 367: + return (*rw367)(state) + case 368: + return (*rw368)(state) + case 369: + return (*rw369)(state) + case 370: + return (*rw370)(state) + case 371: + return (*rw371)(state) + case 372: + return (*rw372)(state) + case 373: + return (*rw373)(state) + case 374: + return (*rw374)(state) + case 375: + return (*rw375)(state) + case 376: + return (*rw376)(state) + case 377: + return (*rw377)(state) + case 378: + return (*rw378)(state) + case 379: + return (*rw379)(state) + case 380: + return (*rw380)(state) + case 381: + return (*rw381)(state) + case 382: + return (*rw382)(state) + case 383: + return (*rw383)(state) + case 384: + return (*rw384)(state) + case 385: + return (*rw385)(state) + case 386: + return (*rw386)(state) + case 387: + return (*rw387)(state) + case 388: + return (*rw388)(state) + case 389: + return (*rw389)(state) + case 390: + return (*rw390)(state) + case 391: + return (*rw391)(state) + case 392: + return (*rw392)(state) + case 393: + return (*rw393)(state) + case 394: + return (*rw394)(state) + case 395: + return (*rw395)(state) + case 396: + return (*rw396)(state) + case 397: + return (*rw397)(state) + case 398: + return (*rw398)(state) + case 399: + return (*rw399)(state) + case 400: + return (*rw400)(state) + case 401: + return (*rw401)(state) + case 402: + return (*rw402)(state) + case 403: + return (*rw403)(state) + case 404: + return (*rw404)(state) + case 405: + return (*rw405)(state) + case 406: + return (*rw406)(state) + case 407: + return (*rw407)(state) + case 408: + return (*rw408)(state) + case 409: + return (*rw409)(state) + case 410: + return (*rw410)(state) + case 411: + return (*rw411)(state) + case 412: + return (*rw412)(state) + case 413: + return (*rw413)(state) + case 414: + return (*rw414)(state) + case 415: + return (*rw415)(state) + case 416: + return (*rw416)(state) + case 417: + return (*rw417)(state) + case 418: + return (*rw418)(state) + case 419: + return (*rw419)(state) + case 420: + return (*rw420)(state) + case 421: + return (*rw421)(state) + case 422: + return (*rw422)(state) + case 423: + return (*rw423)(state) + case 424: + return (*rw424)(state) + case 425: + return (*rw425)(state) + case 426: + return (*rw426)(state) + case 427: + return (*rw427)(state) + case 428: + return (*rw428)(state) + case 429: + return (*rw429)(state) + case 430: + return (*rw430)(state) + case 431: + return (*rw431)(state) + case 432: + return (*rw432)(state) + case 433: + return (*rw433)(state) + case 434: + return (*rw434)(state) + case 435: + return (*rw435)(state) + case 436: + return (*rw436)(state) + case 437: + return (*rw437)(state) + case 438: + return (*rw438)(state) + case 439: + return (*rw439)(state) + case 440: + return (*rw440)(state) + case 441: + return (*rw441)(state) + case 442: + return (*rw442)(state) + case 443: + return (*rw443)(state) + case 444: + return (*rw444)(state) + case 445: + return (*rw445)(state) + case 446: + return (*rw446)(state) + case 447: + return (*rw447)(state) + case 448: + return (*rw448)(state) + case 449: + return (*rw449)(state) + case 450: + return (*rw450)(state) + case 451: + return (*rw451)(state) + case 452: + return (*rw452)(state) + case 453: + return (*rw453)(state) + case 454: + return (*rw454)(state) + case 455: + return (*rw455)(state) + case 456: + return (*rw456)(state) + case 457: + return (*rw457)(state) + case 458: + return (*rw458)(state) + case 459: + return (*rw459)(state) + case 460: + return (*rw460)(state) + case 461: + return (*rw461)(state) + case 462: + return (*rw462)(state) + case 463: + return (*rw463)(state) + case 464: + return (*rw464)(state) + case 465: + return (*rw465)(state) + case 466: + return (*rw466)(state) + case 467: + return (*rw467)(state) + case 468: + return (*rw468)(state) + case 469: + return (*rw469)(state) + case 470: + return (*rw470)(state) + case 471: + return (*rw471)(state) + case 472: + return (*rw472)(state) + case 473: + return (*rw473)(state) + case 474: + return (*rw474)(state) + case 475: + return (*rw475)(state) + case 476: + return (*rw476)(state) + case 477: + return (*rw477)(state) + case 478: + return (*rw478)(state) + case 479: + return (*rw479)(state) + case 480: + return (*rw480)(state) + case 481: + return (*rw481)(state) + case 482: + return (*rw482)(state) + case 483: + return (*rw483)(state) + case 484: + return (*rw484)(state) + case 485: + return (*rw485)(state) + case 486: + return (*rw486)(state) + case 487: + return (*rw487)(state) + case 488: + return (*rw488)(state) + case 489: + return (*rw489)(state) + case 490: + return (*rw490)(state) + case 491: + return (*rw491)(state) + case 492: + return (*rw492)(state) + case 493: + return (*rw493)(state) + case 494: + return (*rw494)(state) + case 495: + return (*rw495)(state) + case 496: + return (*rw496)(state) + case 497: + return (*rw497)(state) + case 498: + return (*rw498)(state) + case 499: + return (*rw499)(state) + case 500: + return (*rw500)(state) + case 501: + return (*rw501)(state) + case 502: + return (*rw502)(state) + case 503: + return (*rw503)(state) + case 504: + return (*rw504)(state) + case 505: + return (*rw505)(state) + case 506: + return (*rw506)(state) + case 507: + return (*rw507)(state) + case 508: + return (*rw508)(state) + case 509: + return (*rw509)(state) + case 510: + return (*rw510)(state) + case 511: + return (*rw511)(state) + } + panic("unreachable") +} + +type rwState struct { + w http.ResponseWriter + header HeaderFunc + writeHeader WriteHeaderFunc + write WriteFunc + flush FlushFunc + flushError FlushErrorFunc + closeNotify CloseNotifyFunc + hijack HijackFunc + readFrom ReadFromFunc + setReadDeadline SetReadDeadlineFunc + setWriteDeadline SetWriteDeadlineFunc + enableFullDuplex EnableFullDuplexFunc + push PushFunc + writeString WriteStringFunc +} + +func (r *rwState) doHeader() http.Header { + if r.header != nil { + return r.header() + } + return r.w.Header() +} + +func (r *rwState) doWriteHeader(code int) { + if r.writeHeader != nil { + r.writeHeader(code) + return + } + r.w.WriteHeader(code) +} + +func (r *rwState) doWrite(b []byte) (int, error) { + if r.write != nil { + return r.write(b) + } + return r.w.Write(b) +} + +func (r *rwState) doFlush() { + if r.flush != nil { + r.flush() + return + } + r.w.(http.Flusher).Flush() +} + +func (r *rwState) doFlushError() error { + if r.flushError != nil { + return r.flushError() + } + return r.w.(httpFlushError).FlushError() +} + +func (r *rwState) doCloseNotify() <-chan bool { + if r.closeNotify != nil { + return r.closeNotify() + } + return r.w.(http.CloseNotifier).CloseNotify() +} + +func (r *rwState) doHijack() (net.Conn, *bufio.ReadWriter, error) { + if r.hijack != nil { + return r.hijack() + } + return r.w.(http.Hijacker).Hijack() +} + +func (r *rwState) doReadFrom(src io.Reader) (int64, error) { + if r.readFrom != nil { + return r.readFrom(src) + } + return r.w.(io.ReaderFrom).ReadFrom(src) +} + +func (r *rwState) doSetReadDeadline(deadline time.Time) error { + if r.setReadDeadline != nil { + return r.setReadDeadline(deadline) + } + return r.w.(deadliner).SetReadDeadline(deadline) +} + +func (r *rwState) doSetWriteDeadline(deadline time.Time) error { + if r.setWriteDeadline != nil { + return r.setWriteDeadline(deadline) + } + return r.w.(deadliner).SetWriteDeadline(deadline) +} + +func (r *rwState) doEnableFullDuplex() error { + if r.enableFullDuplex != nil { + return r.enableFullDuplex() + } + return r.w.(fullDuplexEnabler).EnableFullDuplex() +} + +func (r *rwState) doPush(target string, opts *http.PushOptions) error { + if r.push != nil { + return r.push(target, opts) + } + return r.w.(http.Pusher).Push(target, opts) +} + +func (r *rwState) doWriteString(s string) (int, error) { + if r.writeString != nil { + return r.writeString(s) + } + return r.w.(io.StringWriter).WriteString(s) +} + +// combination 1/512: http.ResponseWriter +type rw0 rwState + +func (w *rw0) Unwrap() http.ResponseWriter { return w.w } +func (w *rw0) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw0) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw0) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} + +// combination 2/512: http.ResponseWriter, io.StringWriter +type rw1 rwState + +func (w *rw1) Unwrap() http.ResponseWriter { return w.w } +func (w *rw1) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw1) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw1) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw1) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 3/512: http.ResponseWriter, http.Pusher +type rw2 rwState + +func (w *rw2) Unwrap() http.ResponseWriter { return w.w } +func (w *rw2) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw2) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw2) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw2) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 4/512: http.ResponseWriter, http.Pusher, io.StringWriter +type rw3 rwState + +func (w *rw3) Unwrap() http.ResponseWriter { return w.w } +func (w *rw3) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw3) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw3) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw3) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw3) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 5/512: http.ResponseWriter, fullDuplexEnabler +type rw4 rwState + +func (w *rw4) Unwrap() http.ResponseWriter { return w.w } +func (w *rw4) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw4) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw4) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw4) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 6/512: http.ResponseWriter, fullDuplexEnabler, io.StringWriter +type rw5 rwState + +func (w *rw5) Unwrap() http.ResponseWriter { return w.w } +func (w *rw5) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw5) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw5) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw5) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw5) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 7/512: http.ResponseWriter, fullDuplexEnabler, http.Pusher +type rw6 rwState + +func (w *rw6) Unwrap() http.ResponseWriter { return w.w } +func (w *rw6) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw6) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw6) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw6) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw6) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 8/512: http.ResponseWriter, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw7 rwState + +func (w *rw7) Unwrap() http.ResponseWriter { return w.w } +func (w *rw7) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw7) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw7) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw7) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw7) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw7) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 9/512: http.ResponseWriter, deadliner +type rw8 rwState + +func (w *rw8) Unwrap() http.ResponseWriter { return w.w } +func (w *rw8) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw8) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw8) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw8) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw8) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 10/512: http.ResponseWriter, deadliner, io.StringWriter +type rw9 rwState + +func (w *rw9) Unwrap() http.ResponseWriter { return w.w } +func (w *rw9) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw9) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw9) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw9) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw9) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw9) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 11/512: http.ResponseWriter, deadliner, http.Pusher +type rw10 rwState + +func (w *rw10) Unwrap() http.ResponseWriter { return w.w } +func (w *rw10) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw10) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw10) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw10) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw10) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw10) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 12/512: http.ResponseWriter, deadliner, http.Pusher, io.StringWriter +type rw11 rwState + +func (w *rw11) Unwrap() http.ResponseWriter { return w.w } +func (w *rw11) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw11) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw11) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw11) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw11) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw11) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw11) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 13/512: http.ResponseWriter, deadliner, fullDuplexEnabler +type rw12 rwState + +func (w *rw12) Unwrap() http.ResponseWriter { return w.w } +func (w *rw12) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw12) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw12) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw12) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw12) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw12) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 14/512: http.ResponseWriter, deadliner, fullDuplexEnabler, io.StringWriter +type rw13 rwState + +func (w *rw13) Unwrap() http.ResponseWriter { return w.w } +func (w *rw13) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw13) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw13) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw13) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw13) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw13) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw13) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 15/512: http.ResponseWriter, deadliner, fullDuplexEnabler, http.Pusher +type rw14 rwState + +func (w *rw14) Unwrap() http.ResponseWriter { return w.w } +func (w *rw14) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw14) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw14) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw14) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw14) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw14) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw14) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 16/512: http.ResponseWriter, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw15 rwState + +func (w *rw15) Unwrap() http.ResponseWriter { return w.w } +func (w *rw15) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw15) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw15) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw15) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw15) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw15) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw15) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw15) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 17/512: http.ResponseWriter, io.ReaderFrom +type rw16 rwState + +func (w *rw16) Unwrap() http.ResponseWriter { return w.w } +func (w *rw16) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw16) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw16) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw16) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 18/512: http.ResponseWriter, io.ReaderFrom, io.StringWriter +type rw17 rwState + +func (w *rw17) Unwrap() http.ResponseWriter { return w.w } +func (w *rw17) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw17) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw17) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw17) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw17) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 19/512: http.ResponseWriter, io.ReaderFrom, http.Pusher +type rw18 rwState + +func (w *rw18) Unwrap() http.ResponseWriter { return w.w } +func (w *rw18) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw18) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw18) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw18) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw18) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 20/512: http.ResponseWriter, io.ReaderFrom, http.Pusher, io.StringWriter +type rw19 rwState + +func (w *rw19) Unwrap() http.ResponseWriter { return w.w } +func (w *rw19) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw19) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw19) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw19) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw19) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw19) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 21/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler +type rw20 rwState + +func (w *rw20) Unwrap() http.ResponseWriter { return w.w } +func (w *rw20) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw20) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw20) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw20) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw20) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 22/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw21 rwState + +func (w *rw21) Unwrap() http.ResponseWriter { return w.w } +func (w *rw21) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw21) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw21) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw21) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw21) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw21) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 23/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw22 rwState + +func (w *rw22) Unwrap() http.ResponseWriter { return w.w } +func (w *rw22) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw22) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw22) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw22) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw22) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw22) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 24/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw23 rwState + +func (w *rw23) Unwrap() http.ResponseWriter { return w.w } +func (w *rw23) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw23) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw23) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw23) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw23) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw23) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw23) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 25/512: http.ResponseWriter, io.ReaderFrom, deadliner +type rw24 rwState + +func (w *rw24) Unwrap() http.ResponseWriter { return w.w } +func (w *rw24) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw24) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw24) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw24) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw24) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw24) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 26/512: http.ResponseWriter, io.ReaderFrom, deadliner, io.StringWriter +type rw25 rwState + +func (w *rw25) Unwrap() http.ResponseWriter { return w.w } +func (w *rw25) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw25) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw25) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw25) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw25) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw25) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw25) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 27/512: http.ResponseWriter, io.ReaderFrom, deadliner, http.Pusher +type rw26 rwState + +func (w *rw26) Unwrap() http.ResponseWriter { return w.w } +func (w *rw26) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw26) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw26) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw26) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw26) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw26) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw26) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 28/512: http.ResponseWriter, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw27 rwState + +func (w *rw27) Unwrap() http.ResponseWriter { return w.w } +func (w *rw27) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw27) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw27) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw27) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw27) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw27) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw27) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw27) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 29/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw28 rwState + +func (w *rw28) Unwrap() http.ResponseWriter { return w.w } +func (w *rw28) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw28) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw28) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw28) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw28) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw28) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw28) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 30/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw29 rwState + +func (w *rw29) Unwrap() http.ResponseWriter { return w.w } +func (w *rw29) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw29) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw29) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw29) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw29) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw29) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw29) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw29) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 31/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw30 rwState + +func (w *rw30) Unwrap() http.ResponseWriter { return w.w } +func (w *rw30) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw30) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw30) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw30) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw30) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw30) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw30) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw30) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 32/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw31 rwState + +func (w *rw31) Unwrap() http.ResponseWriter { return w.w } +func (w *rw31) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw31) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw31) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw31) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw31) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw31) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw31) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw31) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw31) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 33/512: http.ResponseWriter, http.Hijacker +type rw32 rwState + +func (w *rw32) Unwrap() http.ResponseWriter { return w.w } +func (w *rw32) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw32) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw32) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw32) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 34/512: http.ResponseWriter, http.Hijacker, io.StringWriter +type rw33 rwState + +func (w *rw33) Unwrap() http.ResponseWriter { return w.w } +func (w *rw33) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw33) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw33) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw33) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw33) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 35/512: http.ResponseWriter, http.Hijacker, http.Pusher +type rw34 rwState + +func (w *rw34) Unwrap() http.ResponseWriter { return w.w } +func (w *rw34) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw34) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw34) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw34) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw34) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 36/512: http.ResponseWriter, http.Hijacker, http.Pusher, io.StringWriter +type rw35 rwState + +func (w *rw35) Unwrap() http.ResponseWriter { return w.w } +func (w *rw35) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw35) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw35) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw35) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw35) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw35) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 37/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler +type rw36 rwState + +func (w *rw36) Unwrap() http.ResponseWriter { return w.w } +func (w *rw36) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw36) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw36) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw36) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw36) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 38/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw37 rwState + +func (w *rw37) Unwrap() http.ResponseWriter { return w.w } +func (w *rw37) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw37) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw37) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw37) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw37) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw37) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 39/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw38 rwState + +func (w *rw38) Unwrap() http.ResponseWriter { return w.w } +func (w *rw38) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw38) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw38) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw38) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw38) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw38) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 40/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw39 rwState + +func (w *rw39) Unwrap() http.ResponseWriter { return w.w } +func (w *rw39) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw39) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw39) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw39) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw39) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw39) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw39) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 41/512: http.ResponseWriter, http.Hijacker, deadliner +type rw40 rwState + +func (w *rw40) Unwrap() http.ResponseWriter { return w.w } +func (w *rw40) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw40) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw40) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw40) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw40) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw40) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 42/512: http.ResponseWriter, http.Hijacker, deadliner, io.StringWriter +type rw41 rwState + +func (w *rw41) Unwrap() http.ResponseWriter { return w.w } +func (w *rw41) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw41) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw41) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw41) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw41) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw41) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw41) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 43/512: http.ResponseWriter, http.Hijacker, deadliner, http.Pusher +type rw42 rwState + +func (w *rw42) Unwrap() http.ResponseWriter { return w.w } +func (w *rw42) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw42) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw42) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw42) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw42) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw42) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw42) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 44/512: http.ResponseWriter, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw43 rwState + +func (w *rw43) Unwrap() http.ResponseWriter { return w.w } +func (w *rw43) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw43) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw43) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw43) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw43) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw43) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw43) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw43) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 45/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler +type rw44 rwState + +func (w *rw44) Unwrap() http.ResponseWriter { return w.w } +func (w *rw44) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw44) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw44) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw44) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw44) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw44) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw44) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 46/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw45 rwState + +func (w *rw45) Unwrap() http.ResponseWriter { return w.w } +func (w *rw45) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw45) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw45) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw45) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw45) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw45) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw45) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw45) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 47/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw46 rwState + +func (w *rw46) Unwrap() http.ResponseWriter { return w.w } +func (w *rw46) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw46) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw46) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw46) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw46) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw46) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw46) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw46) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 48/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw47 rwState + +func (w *rw47) Unwrap() http.ResponseWriter { return w.w } +func (w *rw47) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw47) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw47) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw47) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw47) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw47) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw47) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw47) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw47) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 49/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom +type rw48 rwState + +func (w *rw48) Unwrap() http.ResponseWriter { return w.w } +func (w *rw48) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw48) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw48) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw48) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw48) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 50/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw49 rwState + +func (w *rw49) Unwrap() http.ResponseWriter { return w.w } +func (w *rw49) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw49) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw49) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw49) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw49) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw49) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 51/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, http.Pusher +type rw50 rwState + +func (w *rw50) Unwrap() http.ResponseWriter { return w.w } +func (w *rw50) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw50) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw50) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw50) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw50) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw50) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 52/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw51 rwState + +func (w *rw51) Unwrap() http.ResponseWriter { return w.w } +func (w *rw51) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw51) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw51) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw51) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw51) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw51) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw51) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 53/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw52 rwState + +func (w *rw52) Unwrap() http.ResponseWriter { return w.w } +func (w *rw52) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw52) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw52) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw52) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw52) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw52) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 54/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw53 rwState + +func (w *rw53) Unwrap() http.ResponseWriter { return w.w } +func (w *rw53) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw53) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw53) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw53) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw53) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw53) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw53) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 55/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw54 rwState + +func (w *rw54) Unwrap() http.ResponseWriter { return w.w } +func (w *rw54) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw54) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw54) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw54) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw54) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw54) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw54) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 56/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw55 rwState + +func (w *rw55) Unwrap() http.ResponseWriter { return w.w } +func (w *rw55) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw55) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw55) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw55) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw55) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw55) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw55) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw55) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 57/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner +type rw56 rwState + +func (w *rw56) Unwrap() http.ResponseWriter { return w.w } +func (w *rw56) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw56) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw56) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw56) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw56) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw56) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw56) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 58/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw57 rwState + +func (w *rw57) Unwrap() http.ResponseWriter { return w.w } +func (w *rw57) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw57) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw57) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw57) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw57) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw57) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw57) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw57) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 59/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw58 rwState + +func (w *rw58) Unwrap() http.ResponseWriter { return w.w } +func (w *rw58) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw58) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw58) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw58) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw58) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw58) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw58) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw58) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 60/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw59 rwState + +func (w *rw59) Unwrap() http.ResponseWriter { return w.w } +func (w *rw59) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw59) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw59) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw59) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw59) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw59) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw59) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw59) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw59) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 61/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw60 rwState + +func (w *rw60) Unwrap() http.ResponseWriter { return w.w } +func (w *rw60) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw60) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw60) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw60) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw60) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw60) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw60) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw60) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 62/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw61 rwState + +func (w *rw61) Unwrap() http.ResponseWriter { return w.w } +func (w *rw61) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw61) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw61) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw61) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw61) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw61) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw61) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw61) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw61) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 63/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw62 rwState + +func (w *rw62) Unwrap() http.ResponseWriter { return w.w } +func (w *rw62) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw62) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw62) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw62) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw62) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw62) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw62) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw62) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw62) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 64/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw63 rwState + +func (w *rw63) Unwrap() http.ResponseWriter { return w.w } +func (w *rw63) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw63) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw63) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw63) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw63) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw63) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw63) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw63) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw63) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw63) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 65/512: http.ResponseWriter, http.CloseNotifier +type rw64 rwState + +func (w *rw64) Unwrap() http.ResponseWriter { return w.w } +func (w *rw64) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw64) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw64) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw64) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 66/512: http.ResponseWriter, http.CloseNotifier, io.StringWriter +type rw65 rwState + +func (w *rw65) Unwrap() http.ResponseWriter { return w.w } +func (w *rw65) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw65) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw65) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw65) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw65) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 67/512: http.ResponseWriter, http.CloseNotifier, http.Pusher +type rw66 rwState + +func (w *rw66) Unwrap() http.ResponseWriter { return w.w } +func (w *rw66) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw66) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw66) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw66) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw66) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 68/512: http.ResponseWriter, http.CloseNotifier, http.Pusher, io.StringWriter +type rw67 rwState + +func (w *rw67) Unwrap() http.ResponseWriter { return w.w } +func (w *rw67) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw67) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw67) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw67) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw67) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw67) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 69/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler +type rw68 rwState + +func (w *rw68) Unwrap() http.ResponseWriter { return w.w } +func (w *rw68) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw68) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw68) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw68) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw68) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 70/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw69 rwState + +func (w *rw69) Unwrap() http.ResponseWriter { return w.w } +func (w *rw69) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw69) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw69) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw69) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw69) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw69) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 71/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw70 rwState + +func (w *rw70) Unwrap() http.ResponseWriter { return w.w } +func (w *rw70) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw70) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw70) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw70) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw70) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw70) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 72/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw71 rwState + +func (w *rw71) Unwrap() http.ResponseWriter { return w.w } +func (w *rw71) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw71) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw71) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw71) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw71) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw71) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw71) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 73/512: http.ResponseWriter, http.CloseNotifier, deadliner +type rw72 rwState + +func (w *rw72) Unwrap() http.ResponseWriter { return w.w } +func (w *rw72) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw72) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw72) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw72) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw72) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw72) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 74/512: http.ResponseWriter, http.CloseNotifier, deadliner, io.StringWriter +type rw73 rwState + +func (w *rw73) Unwrap() http.ResponseWriter { return w.w } +func (w *rw73) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw73) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw73) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw73) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw73) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw73) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw73) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 75/512: http.ResponseWriter, http.CloseNotifier, deadliner, http.Pusher +type rw74 rwState + +func (w *rw74) Unwrap() http.ResponseWriter { return w.w } +func (w *rw74) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw74) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw74) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw74) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw74) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw74) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw74) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 76/512: http.ResponseWriter, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw75 rwState + +func (w *rw75) Unwrap() http.ResponseWriter { return w.w } +func (w *rw75) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw75) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw75) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw75) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw75) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw75) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw75) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw75) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 77/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw76 rwState + +func (w *rw76) Unwrap() http.ResponseWriter { return w.w } +func (w *rw76) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw76) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw76) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw76) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw76) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw76) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw76) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 78/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw77 rwState + +func (w *rw77) Unwrap() http.ResponseWriter { return w.w } +func (w *rw77) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw77) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw77) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw77) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw77) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw77) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw77) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw77) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 79/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw78 rwState + +func (w *rw78) Unwrap() http.ResponseWriter { return w.w } +func (w *rw78) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw78) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw78) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw78) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw78) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw78) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw78) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw78) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 80/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw79 rwState + +func (w *rw79) Unwrap() http.ResponseWriter { return w.w } +func (w *rw79) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw79) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw79) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw79) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw79) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw79) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw79) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw79) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw79) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 81/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom +type rw80 rwState + +func (w *rw80) Unwrap() http.ResponseWriter { return w.w } +func (w *rw80) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw80) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw80) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw80) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw80) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 82/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw81 rwState + +func (w *rw81) Unwrap() http.ResponseWriter { return w.w } +func (w *rw81) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw81) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw81) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw81) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw81) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw81) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 83/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw82 rwState + +func (w *rw82) Unwrap() http.ResponseWriter { return w.w } +func (w *rw82) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw82) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw82) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw82) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw82) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw82) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 84/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw83 rwState + +func (w *rw83) Unwrap() http.ResponseWriter { return w.w } +func (w *rw83) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw83) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw83) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw83) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw83) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw83) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw83) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 85/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw84 rwState + +func (w *rw84) Unwrap() http.ResponseWriter { return w.w } +func (w *rw84) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw84) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw84) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw84) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw84) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw84) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 86/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw85 rwState + +func (w *rw85) Unwrap() http.ResponseWriter { return w.w } +func (w *rw85) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw85) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw85) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw85) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw85) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw85) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw85) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 87/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw86 rwState + +func (w *rw86) Unwrap() http.ResponseWriter { return w.w } +func (w *rw86) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw86) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw86) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw86) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw86) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw86) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw86) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 88/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw87 rwState + +func (w *rw87) Unwrap() http.ResponseWriter { return w.w } +func (w *rw87) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw87) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw87) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw87) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw87) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw87) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw87) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw87) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 89/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner +type rw88 rwState + +func (w *rw88) Unwrap() http.ResponseWriter { return w.w } +func (w *rw88) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw88) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw88) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw88) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw88) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw88) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw88) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 90/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw89 rwState + +func (w *rw89) Unwrap() http.ResponseWriter { return w.w } +func (w *rw89) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw89) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw89) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw89) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw89) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw89) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw89) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw89) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 91/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw90 rwState + +func (w *rw90) Unwrap() http.ResponseWriter { return w.w } +func (w *rw90) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw90) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw90) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw90) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw90) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw90) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw90) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw90) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 92/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw91 rwState + +func (w *rw91) Unwrap() http.ResponseWriter { return w.w } +func (w *rw91) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw91) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw91) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw91) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw91) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw91) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw91) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw91) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw91) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 93/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw92 rwState + +func (w *rw92) Unwrap() http.ResponseWriter { return w.w } +func (w *rw92) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw92) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw92) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw92) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw92) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw92) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw92) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw92) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 94/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw93 rwState + +func (w *rw93) Unwrap() http.ResponseWriter { return w.w } +func (w *rw93) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw93) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw93) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw93) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw93) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw93) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw93) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw93) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw93) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 95/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw94 rwState + +func (w *rw94) Unwrap() http.ResponseWriter { return w.w } +func (w *rw94) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw94) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw94) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw94) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw94) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw94) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw94) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw94) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw94) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 96/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw95 rwState + +func (w *rw95) Unwrap() http.ResponseWriter { return w.w } +func (w *rw95) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw95) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw95) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw95) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw95) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw95) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw95) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw95) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw95) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw95) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 97/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker +type rw96 rwState + +func (w *rw96) Unwrap() http.ResponseWriter { return w.w } +func (w *rw96) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw96) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw96) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw96) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw96) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 98/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw97 rwState + +func (w *rw97) Unwrap() http.ResponseWriter { return w.w } +func (w *rw97) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw97) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw97) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw97) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw97) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw97) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 99/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, http.Pusher +type rw98 rwState + +func (w *rw98) Unwrap() http.ResponseWriter { return w.w } +func (w *rw98) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw98) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw98) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw98) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw98) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw98) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 100/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw99 rwState + +func (w *rw99) Unwrap() http.ResponseWriter { return w.w } +func (w *rw99) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw99) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw99) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw99) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw99) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw99) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw99) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 101/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw100 rwState + +func (w *rw100) Unwrap() http.ResponseWriter { return w.w } +func (w *rw100) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw100) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw100) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw100) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw100) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw100) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 102/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw101 rwState + +func (w *rw101) Unwrap() http.ResponseWriter { return w.w } +func (w *rw101) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw101) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw101) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw101) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw101) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw101) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw101) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 103/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw102 rwState + +func (w *rw102) Unwrap() http.ResponseWriter { return w.w } +func (w *rw102) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw102) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw102) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw102) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw102) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw102) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw102) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 104/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw103 rwState + +func (w *rw103) Unwrap() http.ResponseWriter { return w.w } +func (w *rw103) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw103) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw103) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw103) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw103) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw103) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw103) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw103) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 105/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner +type rw104 rwState + +func (w *rw104) Unwrap() http.ResponseWriter { return w.w } +func (w *rw104) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw104) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw104) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw104) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw104) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw104) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw104) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 106/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw105 rwState + +func (w *rw105) Unwrap() http.ResponseWriter { return w.w } +func (w *rw105) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw105) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw105) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw105) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw105) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw105) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw105) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw105) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 107/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw106 rwState + +func (w *rw106) Unwrap() http.ResponseWriter { return w.w } +func (w *rw106) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw106) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw106) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw106) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw106) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw106) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw106) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw106) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 108/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw107 rwState + +func (w *rw107) Unwrap() http.ResponseWriter { return w.w } +func (w *rw107) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw107) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw107) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw107) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw107) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw107) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw107) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw107) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw107) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 109/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw108 rwState + +func (w *rw108) Unwrap() http.ResponseWriter { return w.w } +func (w *rw108) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw108) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw108) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw108) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw108) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw108) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw108) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw108) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 110/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw109 rwState + +func (w *rw109) Unwrap() http.ResponseWriter { return w.w } +func (w *rw109) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw109) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw109) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw109) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw109) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw109) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw109) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw109) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw109) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 111/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw110 rwState + +func (w *rw110) Unwrap() http.ResponseWriter { return w.w } +func (w *rw110) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw110) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw110) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw110) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw110) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw110) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw110) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw110) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw110) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 112/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw111 rwState + +func (w *rw111) Unwrap() http.ResponseWriter { return w.w } +func (w *rw111) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw111) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw111) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw111) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw111) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw111) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw111) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw111) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw111) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw111) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 113/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw112 rwState + +func (w *rw112) Unwrap() http.ResponseWriter { return w.w } +func (w *rw112) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw112) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw112) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw112) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw112) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw112) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 114/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw113 rwState + +func (w *rw113) Unwrap() http.ResponseWriter { return w.w } +func (w *rw113) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw113) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw113) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw113) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw113) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw113) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw113) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 115/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw114 rwState + +func (w *rw114) Unwrap() http.ResponseWriter { return w.w } +func (w *rw114) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw114) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw114) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw114) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw114) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw114) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw114) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 116/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw115 rwState + +func (w *rw115) Unwrap() http.ResponseWriter { return w.w } +func (w *rw115) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw115) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw115) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw115) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw115) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw115) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw115) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw115) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 117/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw116 rwState + +func (w *rw116) Unwrap() http.ResponseWriter { return w.w } +func (w *rw116) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw116) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw116) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw116) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw116) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw116) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw116) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 118/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw117 rwState + +func (w *rw117) Unwrap() http.ResponseWriter { return w.w } +func (w *rw117) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw117) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw117) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw117) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw117) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw117) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw117) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw117) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 119/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw118 rwState + +func (w *rw118) Unwrap() http.ResponseWriter { return w.w } +func (w *rw118) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw118) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw118) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw118) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw118) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw118) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw118) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw118) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 120/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw119 rwState + +func (w *rw119) Unwrap() http.ResponseWriter { return w.w } +func (w *rw119) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw119) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw119) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw119) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw119) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw119) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw119) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw119) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw119) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 121/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw120 rwState + +func (w *rw120) Unwrap() http.ResponseWriter { return w.w } +func (w *rw120) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw120) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw120) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw120) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw120) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw120) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw120) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw120) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 122/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw121 rwState + +func (w *rw121) Unwrap() http.ResponseWriter { return w.w } +func (w *rw121) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw121) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw121) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw121) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw121) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw121) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw121) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw121) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw121) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 123/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw122 rwState + +func (w *rw122) Unwrap() http.ResponseWriter { return w.w } +func (w *rw122) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw122) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw122) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw122) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw122) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw122) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw122) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw122) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw122) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 124/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw123 rwState + +func (w *rw123) Unwrap() http.ResponseWriter { return w.w } +func (w *rw123) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw123) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw123) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw123) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw123) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw123) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw123) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw123) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw123) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw123) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 125/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw124 rwState + +func (w *rw124) Unwrap() http.ResponseWriter { return w.w } +func (w *rw124) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw124) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw124) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw124) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw124) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw124) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw124) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw124) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw124) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 126/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw125 rwState + +func (w *rw125) Unwrap() http.ResponseWriter { return w.w } +func (w *rw125) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw125) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw125) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw125) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw125) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw125) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw125) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw125) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw125) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw125) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 127/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw126 rwState + +func (w *rw126) Unwrap() http.ResponseWriter { return w.w } +func (w *rw126) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw126) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw126) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw126) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw126) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw126) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw126) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw126) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw126) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw126) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 128/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw127 rwState + +func (w *rw127) Unwrap() http.ResponseWriter { return w.w } +func (w *rw127) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw127) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw127) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw127) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw127) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw127) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw127) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw127) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw127) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw127) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw127) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 129/512: http.ResponseWriter, httpFlushError +type rw128 rwState + +func (w *rw128) Unwrap() http.ResponseWriter { return w.w } +func (w *rw128) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw128) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw128) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw128) FlushError() error { + return (*rwState)(w).doFlushError() +} + +// combination 130/512: http.ResponseWriter, httpFlushError, io.StringWriter +type rw129 rwState + +func (w *rw129) Unwrap() http.ResponseWriter { return w.w } +func (w *rw129) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw129) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw129) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw129) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw129) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 131/512: http.ResponseWriter, httpFlushError, http.Pusher +type rw130 rwState + +func (w *rw130) Unwrap() http.ResponseWriter { return w.w } +func (w *rw130) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw130) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw130) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw130) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw130) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 132/512: http.ResponseWriter, httpFlushError, http.Pusher, io.StringWriter +type rw131 rwState + +func (w *rw131) Unwrap() http.ResponseWriter { return w.w } +func (w *rw131) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw131) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw131) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw131) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw131) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw131) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 133/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler +type rw132 rwState + +func (w *rw132) Unwrap() http.ResponseWriter { return w.w } +func (w *rw132) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw132) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw132) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw132) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw132) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 134/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler, io.StringWriter +type rw133 rwState + +func (w *rw133) Unwrap() http.ResponseWriter { return w.w } +func (w *rw133) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw133) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw133) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw133) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw133) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw133) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 135/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler, http.Pusher +type rw134 rwState + +func (w *rw134) Unwrap() http.ResponseWriter { return w.w } +func (w *rw134) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw134) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw134) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw134) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw134) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw134) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 136/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw135 rwState + +func (w *rw135) Unwrap() http.ResponseWriter { return w.w } +func (w *rw135) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw135) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw135) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw135) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw135) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw135) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw135) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 137/512: http.ResponseWriter, httpFlushError, deadliner +type rw136 rwState + +func (w *rw136) Unwrap() http.ResponseWriter { return w.w } +func (w *rw136) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw136) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw136) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw136) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw136) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw136) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 138/512: http.ResponseWriter, httpFlushError, deadliner, io.StringWriter +type rw137 rwState + +func (w *rw137) Unwrap() http.ResponseWriter { return w.w } +func (w *rw137) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw137) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw137) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw137) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw137) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw137) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw137) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 139/512: http.ResponseWriter, httpFlushError, deadliner, http.Pusher +type rw138 rwState + +func (w *rw138) Unwrap() http.ResponseWriter { return w.w } +func (w *rw138) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw138) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw138) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw138) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw138) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw138) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw138) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 140/512: http.ResponseWriter, httpFlushError, deadliner, http.Pusher, io.StringWriter +type rw139 rwState + +func (w *rw139) Unwrap() http.ResponseWriter { return w.w } +func (w *rw139) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw139) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw139) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw139) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw139) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw139) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw139) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw139) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 141/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler +type rw140 rwState + +func (w *rw140) Unwrap() http.ResponseWriter { return w.w } +func (w *rw140) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw140) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw140) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw140) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw140) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw140) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw140) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 142/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler, io.StringWriter +type rw141 rwState + +func (w *rw141) Unwrap() http.ResponseWriter { return w.w } +func (w *rw141) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw141) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw141) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw141) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw141) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw141) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw141) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw141) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 143/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher +type rw142 rwState + +func (w *rw142) Unwrap() http.ResponseWriter { return w.w } +func (w *rw142) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw142) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw142) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw142) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw142) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw142) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw142) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw142) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 144/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw143 rwState + +func (w *rw143) Unwrap() http.ResponseWriter { return w.w } +func (w *rw143) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw143) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw143) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw143) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw143) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw143) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw143) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw143) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw143) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 145/512: http.ResponseWriter, httpFlushError, io.ReaderFrom +type rw144 rwState + +func (w *rw144) Unwrap() http.ResponseWriter { return w.w } +func (w *rw144) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw144) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw144) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw144) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw144) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 146/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, io.StringWriter +type rw145 rwState + +func (w *rw145) Unwrap() http.ResponseWriter { return w.w } +func (w *rw145) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw145) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw145) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw145) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw145) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw145) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 147/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, http.Pusher +type rw146 rwState + +func (w *rw146) Unwrap() http.ResponseWriter { return w.w } +func (w *rw146) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw146) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw146) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw146) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw146) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw146) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 148/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, http.Pusher, io.StringWriter +type rw147 rwState + +func (w *rw147) Unwrap() http.ResponseWriter { return w.w } +func (w *rw147) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw147) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw147) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw147) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw147) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw147) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw147) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 149/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler +type rw148 rwState + +func (w *rw148) Unwrap() http.ResponseWriter { return w.w } +func (w *rw148) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw148) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw148) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw148) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw148) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw148) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 150/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw149 rwState + +func (w *rw149) Unwrap() http.ResponseWriter { return w.w } +func (w *rw149) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw149) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw149) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw149) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw149) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw149) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw149) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 151/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw150 rwState + +func (w *rw150) Unwrap() http.ResponseWriter { return w.w } +func (w *rw150) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw150) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw150) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw150) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw150) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw150) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw150) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 152/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw151 rwState + +func (w *rw151) Unwrap() http.ResponseWriter { return w.w } +func (w *rw151) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw151) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw151) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw151) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw151) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw151) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw151) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw151) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 153/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner +type rw152 rwState + +func (w *rw152) Unwrap() http.ResponseWriter { return w.w } +func (w *rw152) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw152) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw152) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw152) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw152) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw152) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw152) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 154/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, io.StringWriter +type rw153 rwState + +func (w *rw153) Unwrap() http.ResponseWriter { return w.w } +func (w *rw153) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw153) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw153) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw153) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw153) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw153) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw153) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw153) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 155/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, http.Pusher +type rw154 rwState + +func (w *rw154) Unwrap() http.ResponseWriter { return w.w } +func (w *rw154) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw154) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw154) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw154) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw154) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw154) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw154) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw154) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 156/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw155 rwState + +func (w *rw155) Unwrap() http.ResponseWriter { return w.w } +func (w *rw155) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw155) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw155) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw155) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw155) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw155) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw155) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw155) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw155) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 157/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw156 rwState + +func (w *rw156) Unwrap() http.ResponseWriter { return w.w } +func (w *rw156) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw156) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw156) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw156) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw156) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw156) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw156) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw156) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 158/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw157 rwState + +func (w *rw157) Unwrap() http.ResponseWriter { return w.w } +func (w *rw157) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw157) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw157) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw157) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw157) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw157) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw157) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw157) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw157) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 159/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw158 rwState + +func (w *rw158) Unwrap() http.ResponseWriter { return w.w } +func (w *rw158) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw158) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw158) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw158) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw158) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw158) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw158) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw158) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw158) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 160/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw159 rwState + +func (w *rw159) Unwrap() http.ResponseWriter { return w.w } +func (w *rw159) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw159) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw159) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw159) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw159) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw159) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw159) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw159) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw159) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw159) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 161/512: http.ResponseWriter, httpFlushError, http.Hijacker +type rw160 rwState + +func (w *rw160) Unwrap() http.ResponseWriter { return w.w } +func (w *rw160) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw160) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw160) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw160) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw160) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 162/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.StringWriter +type rw161 rwState + +func (w *rw161) Unwrap() http.ResponseWriter { return w.w } +func (w *rw161) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw161) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw161) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw161) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw161) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw161) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 163/512: http.ResponseWriter, httpFlushError, http.Hijacker, http.Pusher +type rw162 rwState + +func (w *rw162) Unwrap() http.ResponseWriter { return w.w } +func (w *rw162) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw162) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw162) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw162) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw162) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw162) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 164/512: http.ResponseWriter, httpFlushError, http.Hijacker, http.Pusher, io.StringWriter +type rw163 rwState + +func (w *rw163) Unwrap() http.ResponseWriter { return w.w } +func (w *rw163) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw163) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw163) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw163) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw163) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw163) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw163) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 165/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler +type rw164 rwState + +func (w *rw164) Unwrap() http.ResponseWriter { return w.w } +func (w *rw164) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw164) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw164) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw164) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw164) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw164) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 166/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw165 rwState + +func (w *rw165) Unwrap() http.ResponseWriter { return w.w } +func (w *rw165) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw165) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw165) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw165) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw165) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw165) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw165) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 167/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw166 rwState + +func (w *rw166) Unwrap() http.ResponseWriter { return w.w } +func (w *rw166) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw166) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw166) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw166) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw166) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw166) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw166) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 168/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw167 rwState + +func (w *rw167) Unwrap() http.ResponseWriter { return w.w } +func (w *rw167) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw167) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw167) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw167) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw167) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw167) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw167) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw167) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 169/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner +type rw168 rwState + +func (w *rw168) Unwrap() http.ResponseWriter { return w.w } +func (w *rw168) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw168) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw168) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw168) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw168) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw168) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw168) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 170/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, io.StringWriter +type rw169 rwState + +func (w *rw169) Unwrap() http.ResponseWriter { return w.w } +func (w *rw169) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw169) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw169) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw169) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw169) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw169) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw169) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw169) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 171/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, http.Pusher +type rw170 rwState + +func (w *rw170) Unwrap() http.ResponseWriter { return w.w } +func (w *rw170) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw170) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw170) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw170) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw170) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw170) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw170) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw170) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 172/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw171 rwState + +func (w *rw171) Unwrap() http.ResponseWriter { return w.w } +func (w *rw171) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw171) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw171) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw171) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw171) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw171) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw171) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw171) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw171) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 173/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler +type rw172 rwState + +func (w *rw172) Unwrap() http.ResponseWriter { return w.w } +func (w *rw172) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw172) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw172) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw172) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw172) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw172) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw172) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw172) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 174/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw173 rwState + +func (w *rw173) Unwrap() http.ResponseWriter { return w.w } +func (w *rw173) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw173) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw173) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw173) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw173) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw173) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw173) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw173) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw173) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 175/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw174 rwState + +func (w *rw174) Unwrap() http.ResponseWriter { return w.w } +func (w *rw174) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw174) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw174) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw174) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw174) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw174) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw174) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw174) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw174) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 176/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw175 rwState + +func (w *rw175) Unwrap() http.ResponseWriter { return w.w } +func (w *rw175) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw175) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw175) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw175) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw175) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw175) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw175) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw175) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw175) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw175) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 177/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom +type rw176 rwState + +func (w *rw176) Unwrap() http.ResponseWriter { return w.w } +func (w *rw176) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw176) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw176) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw176) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw176) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw176) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 178/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw177 rwState + +func (w *rw177) Unwrap() http.ResponseWriter { return w.w } +func (w *rw177) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw177) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw177) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw177) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw177) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw177) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw177) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 179/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher +type rw178 rwState + +func (w *rw178) Unwrap() http.ResponseWriter { return w.w } +func (w *rw178) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw178) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw178) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw178) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw178) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw178) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw178) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 180/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw179 rwState + +func (w *rw179) Unwrap() http.ResponseWriter { return w.w } +func (w *rw179) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw179) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw179) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw179) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw179) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw179) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw179) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw179) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 181/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw180 rwState + +func (w *rw180) Unwrap() http.ResponseWriter { return w.w } +func (w *rw180) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw180) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw180) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw180) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw180) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw180) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw180) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 182/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw181 rwState + +func (w *rw181) Unwrap() http.ResponseWriter { return w.w } +func (w *rw181) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw181) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw181) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw181) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw181) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw181) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw181) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw181) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 183/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw182 rwState + +func (w *rw182) Unwrap() http.ResponseWriter { return w.w } +func (w *rw182) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw182) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw182) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw182) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw182) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw182) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw182) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw182) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 184/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw183 rwState + +func (w *rw183) Unwrap() http.ResponseWriter { return w.w } +func (w *rw183) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw183) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw183) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw183) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw183) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw183) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw183) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw183) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw183) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 185/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner +type rw184 rwState + +func (w *rw184) Unwrap() http.ResponseWriter { return w.w } +func (w *rw184) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw184) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw184) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw184) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw184) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw184) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw184) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw184) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 186/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw185 rwState + +func (w *rw185) Unwrap() http.ResponseWriter { return w.w } +func (w *rw185) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw185) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw185) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw185) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw185) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw185) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw185) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw185) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw185) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 187/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw186 rwState + +func (w *rw186) Unwrap() http.ResponseWriter { return w.w } +func (w *rw186) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw186) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw186) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw186) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw186) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw186) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw186) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw186) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw186) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 188/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw187 rwState + +func (w *rw187) Unwrap() http.ResponseWriter { return w.w } +func (w *rw187) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw187) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw187) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw187) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw187) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw187) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw187) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw187) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw187) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw187) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 189/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw188 rwState + +func (w *rw188) Unwrap() http.ResponseWriter { return w.w } +func (w *rw188) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw188) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw188) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw188) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw188) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw188) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw188) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw188) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw188) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 190/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw189 rwState + +func (w *rw189) Unwrap() http.ResponseWriter { return w.w } +func (w *rw189) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw189) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw189) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw189) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw189) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw189) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw189) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw189) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw189) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw189) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 191/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw190 rwState + +func (w *rw190) Unwrap() http.ResponseWriter { return w.w } +func (w *rw190) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw190) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw190) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw190) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw190) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw190) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw190) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw190) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw190) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw190) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 192/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw191 rwState + +func (w *rw191) Unwrap() http.ResponseWriter { return w.w } +func (w *rw191) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw191) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw191) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw191) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw191) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw191) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw191) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw191) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw191) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw191) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw191) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 193/512: http.ResponseWriter, httpFlushError, http.CloseNotifier +type rw192 rwState + +func (w *rw192) Unwrap() http.ResponseWriter { return w.w } +func (w *rw192) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw192) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw192) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw192) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw192) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 194/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.StringWriter +type rw193 rwState + +func (w *rw193) Unwrap() http.ResponseWriter { return w.w } +func (w *rw193) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw193) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw193) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw193) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw193) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw193) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 195/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Pusher +type rw194 rwState + +func (w *rw194) Unwrap() http.ResponseWriter { return w.w } +func (w *rw194) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw194) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw194) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw194) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw194) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw194) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 196/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Pusher, io.StringWriter +type rw195 rwState + +func (w *rw195) Unwrap() http.ResponseWriter { return w.w } +func (w *rw195) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw195) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw195) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw195) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw195) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw195) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw195) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 197/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler +type rw196 rwState + +func (w *rw196) Unwrap() http.ResponseWriter { return w.w } +func (w *rw196) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw196) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw196) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw196) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw196) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw196) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 198/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw197 rwState + +func (w *rw197) Unwrap() http.ResponseWriter { return w.w } +func (w *rw197) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw197) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw197) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw197) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw197) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw197) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw197) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 199/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw198 rwState + +func (w *rw198) Unwrap() http.ResponseWriter { return w.w } +func (w *rw198) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw198) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw198) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw198) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw198) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw198) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw198) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 200/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw199 rwState + +func (w *rw199) Unwrap() http.ResponseWriter { return w.w } +func (w *rw199) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw199) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw199) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw199) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw199) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw199) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw199) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw199) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 201/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner +type rw200 rwState + +func (w *rw200) Unwrap() http.ResponseWriter { return w.w } +func (w *rw200) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw200) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw200) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw200) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw200) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw200) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw200) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 202/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, io.StringWriter +type rw201 rwState + +func (w *rw201) Unwrap() http.ResponseWriter { return w.w } +func (w *rw201) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw201) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw201) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw201) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw201) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw201) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw201) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw201) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 203/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, http.Pusher +type rw202 rwState + +func (w *rw202) Unwrap() http.ResponseWriter { return w.w } +func (w *rw202) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw202) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw202) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw202) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw202) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw202) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw202) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw202) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 204/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw203 rwState + +func (w *rw203) Unwrap() http.ResponseWriter { return w.w } +func (w *rw203) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw203) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw203) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw203) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw203) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw203) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw203) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw203) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw203) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 205/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw204 rwState + +func (w *rw204) Unwrap() http.ResponseWriter { return w.w } +func (w *rw204) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw204) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw204) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw204) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw204) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw204) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw204) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw204) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 206/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw205 rwState + +func (w *rw205) Unwrap() http.ResponseWriter { return w.w } +func (w *rw205) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw205) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw205) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw205) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw205) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw205) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw205) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw205) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw205) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 207/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw206 rwState + +func (w *rw206) Unwrap() http.ResponseWriter { return w.w } +func (w *rw206) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw206) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw206) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw206) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw206) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw206) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw206) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw206) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw206) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 208/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw207 rwState + +func (w *rw207) Unwrap() http.ResponseWriter { return w.w } +func (w *rw207) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw207) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw207) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw207) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw207) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw207) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw207) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw207) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw207) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw207) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 209/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom +type rw208 rwState + +func (w *rw208) Unwrap() http.ResponseWriter { return w.w } +func (w *rw208) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw208) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw208) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw208) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw208) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw208) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 210/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw209 rwState + +func (w *rw209) Unwrap() http.ResponseWriter { return w.w } +func (w *rw209) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw209) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw209) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw209) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw209) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw209) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw209) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 211/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw210 rwState + +func (w *rw210) Unwrap() http.ResponseWriter { return w.w } +func (w *rw210) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw210) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw210) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw210) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw210) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw210) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw210) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 212/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw211 rwState + +func (w *rw211) Unwrap() http.ResponseWriter { return w.w } +func (w *rw211) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw211) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw211) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw211) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw211) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw211) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw211) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw211) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 213/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw212 rwState + +func (w *rw212) Unwrap() http.ResponseWriter { return w.w } +func (w *rw212) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw212) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw212) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw212) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw212) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw212) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw212) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 214/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw213 rwState + +func (w *rw213) Unwrap() http.ResponseWriter { return w.w } +func (w *rw213) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw213) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw213) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw213) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw213) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw213) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw213) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw213) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 215/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw214 rwState + +func (w *rw214) Unwrap() http.ResponseWriter { return w.w } +func (w *rw214) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw214) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw214) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw214) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw214) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw214) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw214) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw214) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 216/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw215 rwState + +func (w *rw215) Unwrap() http.ResponseWriter { return w.w } +func (w *rw215) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw215) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw215) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw215) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw215) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw215) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw215) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw215) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw215) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 217/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner +type rw216 rwState + +func (w *rw216) Unwrap() http.ResponseWriter { return w.w } +func (w *rw216) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw216) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw216) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw216) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw216) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw216) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw216) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw216) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 218/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw217 rwState + +func (w *rw217) Unwrap() http.ResponseWriter { return w.w } +func (w *rw217) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw217) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw217) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw217) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw217) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw217) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw217) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw217) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw217) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 219/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw218 rwState + +func (w *rw218) Unwrap() http.ResponseWriter { return w.w } +func (w *rw218) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw218) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw218) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw218) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw218) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw218) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw218) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw218) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw218) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 220/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw219 rwState + +func (w *rw219) Unwrap() http.ResponseWriter { return w.w } +func (w *rw219) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw219) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw219) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw219) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw219) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw219) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw219) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw219) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw219) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw219) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 221/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw220 rwState + +func (w *rw220) Unwrap() http.ResponseWriter { return w.w } +func (w *rw220) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw220) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw220) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw220) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw220) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw220) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw220) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw220) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw220) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 222/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw221 rwState + +func (w *rw221) Unwrap() http.ResponseWriter { return w.w } +func (w *rw221) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw221) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw221) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw221) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw221) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw221) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw221) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw221) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw221) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw221) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 223/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw222 rwState + +func (w *rw222) Unwrap() http.ResponseWriter { return w.w } +func (w *rw222) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw222) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw222) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw222) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw222) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw222) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw222) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw222) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw222) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw222) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 224/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw223 rwState + +func (w *rw223) Unwrap() http.ResponseWriter { return w.w } +func (w *rw223) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw223) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw223) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw223) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw223) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw223) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw223) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw223) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw223) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw223) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw223) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 225/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker +type rw224 rwState + +func (w *rw224) Unwrap() http.ResponseWriter { return w.w } +func (w *rw224) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw224) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw224) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw224) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw224) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw224) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 226/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw225 rwState + +func (w *rw225) Unwrap() http.ResponseWriter { return w.w } +func (w *rw225) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw225) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw225) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw225) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw225) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw225) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw225) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 227/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher +type rw226 rwState + +func (w *rw226) Unwrap() http.ResponseWriter { return w.w } +func (w *rw226) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw226) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw226) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw226) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw226) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw226) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw226) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 228/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw227 rwState + +func (w *rw227) Unwrap() http.ResponseWriter { return w.w } +func (w *rw227) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw227) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw227) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw227) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw227) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw227) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw227) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw227) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 229/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw228 rwState + +func (w *rw228) Unwrap() http.ResponseWriter { return w.w } +func (w *rw228) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw228) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw228) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw228) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw228) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw228) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw228) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 230/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw229 rwState + +func (w *rw229) Unwrap() http.ResponseWriter { return w.w } +func (w *rw229) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw229) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw229) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw229) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw229) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw229) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw229) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw229) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 231/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw230 rwState + +func (w *rw230) Unwrap() http.ResponseWriter { return w.w } +func (w *rw230) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw230) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw230) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw230) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw230) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw230) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw230) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw230) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 232/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw231 rwState + +func (w *rw231) Unwrap() http.ResponseWriter { return w.w } +func (w *rw231) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw231) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw231) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw231) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw231) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw231) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw231) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw231) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw231) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 233/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner +type rw232 rwState + +func (w *rw232) Unwrap() http.ResponseWriter { return w.w } +func (w *rw232) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw232) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw232) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw232) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw232) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw232) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw232) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw232) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 234/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw233 rwState + +func (w *rw233) Unwrap() http.ResponseWriter { return w.w } +func (w *rw233) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw233) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw233) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw233) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw233) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw233) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw233) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw233) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw233) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 235/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw234 rwState + +func (w *rw234) Unwrap() http.ResponseWriter { return w.w } +func (w *rw234) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw234) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw234) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw234) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw234) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw234) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw234) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw234) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw234) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 236/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw235 rwState + +func (w *rw235) Unwrap() http.ResponseWriter { return w.w } +func (w *rw235) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw235) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw235) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw235) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw235) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw235) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw235) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw235) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw235) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw235) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 237/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw236 rwState + +func (w *rw236) Unwrap() http.ResponseWriter { return w.w } +func (w *rw236) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw236) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw236) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw236) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw236) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw236) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw236) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw236) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw236) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 238/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw237 rwState + +func (w *rw237) Unwrap() http.ResponseWriter { return w.w } +func (w *rw237) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw237) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw237) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw237) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw237) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw237) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw237) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw237) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw237) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw237) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 239/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw238 rwState + +func (w *rw238) Unwrap() http.ResponseWriter { return w.w } +func (w *rw238) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw238) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw238) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw238) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw238) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw238) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw238) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw238) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw238) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw238) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 240/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw239 rwState + +func (w *rw239) Unwrap() http.ResponseWriter { return w.w } +func (w *rw239) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw239) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw239) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw239) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw239) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw239) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw239) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw239) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw239) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw239) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw239) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 241/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw240 rwState + +func (w *rw240) Unwrap() http.ResponseWriter { return w.w } +func (w *rw240) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw240) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw240) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw240) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw240) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw240) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw240) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 242/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw241 rwState + +func (w *rw241) Unwrap() http.ResponseWriter { return w.w } +func (w *rw241) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw241) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw241) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw241) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw241) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw241) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw241) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw241) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 243/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw242 rwState + +func (w *rw242) Unwrap() http.ResponseWriter { return w.w } +func (w *rw242) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw242) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw242) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw242) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw242) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw242) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw242) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw242) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 244/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw243 rwState + +func (w *rw243) Unwrap() http.ResponseWriter { return w.w } +func (w *rw243) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw243) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw243) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw243) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw243) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw243) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw243) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw243) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw243) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 245/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw244 rwState + +func (w *rw244) Unwrap() http.ResponseWriter { return w.w } +func (w *rw244) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw244) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw244) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw244) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw244) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw244) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw244) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw244) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 246/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw245 rwState + +func (w *rw245) Unwrap() http.ResponseWriter { return w.w } +func (w *rw245) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw245) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw245) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw245) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw245) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw245) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw245) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw245) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw245) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 247/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw246 rwState + +func (w *rw246) Unwrap() http.ResponseWriter { return w.w } +func (w *rw246) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw246) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw246) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw246) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw246) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw246) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw246) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw246) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw246) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 248/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw247 rwState + +func (w *rw247) Unwrap() http.ResponseWriter { return w.w } +func (w *rw247) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw247) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw247) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw247) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw247) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw247) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw247) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw247) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw247) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw247) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 249/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw248 rwState + +func (w *rw248) Unwrap() http.ResponseWriter { return w.w } +func (w *rw248) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw248) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw248) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw248) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw248) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw248) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw248) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw248) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw248) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 250/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw249 rwState + +func (w *rw249) Unwrap() http.ResponseWriter { return w.w } +func (w *rw249) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw249) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw249) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw249) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw249) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw249) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw249) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw249) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw249) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw249) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 251/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw250 rwState + +func (w *rw250) Unwrap() http.ResponseWriter { return w.w } +func (w *rw250) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw250) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw250) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw250) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw250) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw250) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw250) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw250) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw250) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw250) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 252/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw251 rwState + +func (w *rw251) Unwrap() http.ResponseWriter { return w.w } +func (w *rw251) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw251) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw251) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw251) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw251) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw251) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw251) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw251) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw251) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw251) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw251) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 253/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw252 rwState + +func (w *rw252) Unwrap() http.ResponseWriter { return w.w } +func (w *rw252) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw252) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw252) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw252) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw252) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw252) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw252) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw252) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw252) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw252) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 254/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw253 rwState + +func (w *rw253) Unwrap() http.ResponseWriter { return w.w } +func (w *rw253) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw253) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw253) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw253) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw253) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw253) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw253) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw253) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw253) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw253) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw253) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 255/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw254 rwState + +func (w *rw254) Unwrap() http.ResponseWriter { return w.w } +func (w *rw254) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw254) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw254) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw254) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw254) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw254) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw254) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw254) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw254) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw254) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw254) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 256/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw255 rwState + +func (w *rw255) Unwrap() http.ResponseWriter { return w.w } +func (w *rw255) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw255) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw255) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw255) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw255) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw255) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw255) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw255) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw255) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw255) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw255) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw255) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 257/512: http.ResponseWriter, http.Flusher +type rw256 rwState + +func (w *rw256) Unwrap() http.ResponseWriter { return w.w } +func (w *rw256) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw256) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw256) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw256) Flush() { + (*rwState)(w).doFlush() +} + +// combination 258/512: http.ResponseWriter, http.Flusher, io.StringWriter +type rw257 rwState + +func (w *rw257) Unwrap() http.ResponseWriter { return w.w } +func (w *rw257) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw257) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw257) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw257) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw257) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 259/512: http.ResponseWriter, http.Flusher, http.Pusher +type rw258 rwState + +func (w *rw258) Unwrap() http.ResponseWriter { return w.w } +func (w *rw258) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw258) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw258) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw258) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw258) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 260/512: http.ResponseWriter, http.Flusher, http.Pusher, io.StringWriter +type rw259 rwState + +func (w *rw259) Unwrap() http.ResponseWriter { return w.w } +func (w *rw259) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw259) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw259) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw259) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw259) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw259) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 261/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler +type rw260 rwState + +func (w *rw260) Unwrap() http.ResponseWriter { return w.w } +func (w *rw260) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw260) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw260) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw260) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw260) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 262/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler, io.StringWriter +type rw261 rwState + +func (w *rw261) Unwrap() http.ResponseWriter { return w.w } +func (w *rw261) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw261) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw261) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw261) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw261) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw261) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 263/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler, http.Pusher +type rw262 rwState + +func (w *rw262) Unwrap() http.ResponseWriter { return w.w } +func (w *rw262) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw262) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw262) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw262) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw262) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw262) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 264/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw263 rwState + +func (w *rw263) Unwrap() http.ResponseWriter { return w.w } +func (w *rw263) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw263) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw263) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw263) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw263) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw263) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw263) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 265/512: http.ResponseWriter, http.Flusher, deadliner +type rw264 rwState + +func (w *rw264) Unwrap() http.ResponseWriter { return w.w } +func (w *rw264) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw264) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw264) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw264) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw264) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw264) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 266/512: http.ResponseWriter, http.Flusher, deadliner, io.StringWriter +type rw265 rwState + +func (w *rw265) Unwrap() http.ResponseWriter { return w.w } +func (w *rw265) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw265) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw265) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw265) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw265) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw265) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw265) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 267/512: http.ResponseWriter, http.Flusher, deadliner, http.Pusher +type rw266 rwState + +func (w *rw266) Unwrap() http.ResponseWriter { return w.w } +func (w *rw266) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw266) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw266) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw266) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw266) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw266) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw266) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 268/512: http.ResponseWriter, http.Flusher, deadliner, http.Pusher, io.StringWriter +type rw267 rwState + +func (w *rw267) Unwrap() http.ResponseWriter { return w.w } +func (w *rw267) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw267) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw267) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw267) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw267) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw267) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw267) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw267) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 269/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler +type rw268 rwState + +func (w *rw268) Unwrap() http.ResponseWriter { return w.w } +func (w *rw268) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw268) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw268) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw268) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw268) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw268) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw268) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 270/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler, io.StringWriter +type rw269 rwState + +func (w *rw269) Unwrap() http.ResponseWriter { return w.w } +func (w *rw269) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw269) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw269) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw269) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw269) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw269) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw269) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw269) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 271/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler, http.Pusher +type rw270 rwState + +func (w *rw270) Unwrap() http.ResponseWriter { return w.w } +func (w *rw270) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw270) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw270) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw270) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw270) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw270) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw270) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw270) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 272/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw271 rwState + +func (w *rw271) Unwrap() http.ResponseWriter { return w.w } +func (w *rw271) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw271) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw271) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw271) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw271) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw271) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw271) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw271) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw271) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 273/512: http.ResponseWriter, http.Flusher, io.ReaderFrom +type rw272 rwState + +func (w *rw272) Unwrap() http.ResponseWriter { return w.w } +func (w *rw272) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw272) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw272) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw272) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw272) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 274/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, io.StringWriter +type rw273 rwState + +func (w *rw273) Unwrap() http.ResponseWriter { return w.w } +func (w *rw273) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw273) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw273) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw273) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw273) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw273) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 275/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, http.Pusher +type rw274 rwState + +func (w *rw274) Unwrap() http.ResponseWriter { return w.w } +func (w *rw274) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw274) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw274) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw274) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw274) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw274) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 276/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, http.Pusher, io.StringWriter +type rw275 rwState + +func (w *rw275) Unwrap() http.ResponseWriter { return w.w } +func (w *rw275) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw275) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw275) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw275) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw275) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw275) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw275) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 277/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler +type rw276 rwState + +func (w *rw276) Unwrap() http.ResponseWriter { return w.w } +func (w *rw276) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw276) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw276) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw276) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw276) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw276) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 278/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw277 rwState + +func (w *rw277) Unwrap() http.ResponseWriter { return w.w } +func (w *rw277) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw277) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw277) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw277) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw277) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw277) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw277) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 279/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw278 rwState + +func (w *rw278) Unwrap() http.ResponseWriter { return w.w } +func (w *rw278) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw278) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw278) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw278) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw278) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw278) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw278) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 280/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw279 rwState + +func (w *rw279) Unwrap() http.ResponseWriter { return w.w } +func (w *rw279) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw279) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw279) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw279) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw279) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw279) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw279) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw279) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 281/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner +type rw280 rwState + +func (w *rw280) Unwrap() http.ResponseWriter { return w.w } +func (w *rw280) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw280) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw280) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw280) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw280) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw280) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw280) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 282/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, io.StringWriter +type rw281 rwState + +func (w *rw281) Unwrap() http.ResponseWriter { return w.w } +func (w *rw281) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw281) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw281) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw281) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw281) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw281) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw281) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw281) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 283/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, http.Pusher +type rw282 rwState + +func (w *rw282) Unwrap() http.ResponseWriter { return w.w } +func (w *rw282) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw282) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw282) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw282) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw282) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw282) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw282) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw282) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 284/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw283 rwState + +func (w *rw283) Unwrap() http.ResponseWriter { return w.w } +func (w *rw283) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw283) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw283) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw283) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw283) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw283) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw283) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw283) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw283) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 285/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw284 rwState + +func (w *rw284) Unwrap() http.ResponseWriter { return w.w } +func (w *rw284) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw284) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw284) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw284) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw284) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw284) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw284) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw284) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 286/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw285 rwState + +func (w *rw285) Unwrap() http.ResponseWriter { return w.w } +func (w *rw285) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw285) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw285) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw285) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw285) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw285) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw285) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw285) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw285) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 287/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw286 rwState + +func (w *rw286) Unwrap() http.ResponseWriter { return w.w } +func (w *rw286) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw286) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw286) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw286) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw286) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw286) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw286) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw286) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw286) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 288/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw287 rwState + +func (w *rw287) Unwrap() http.ResponseWriter { return w.w } +func (w *rw287) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw287) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw287) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw287) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw287) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw287) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw287) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw287) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw287) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw287) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 289/512: http.ResponseWriter, http.Flusher, http.Hijacker +type rw288 rwState + +func (w *rw288) Unwrap() http.ResponseWriter { return w.w } +func (w *rw288) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw288) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw288) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw288) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw288) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 290/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.StringWriter +type rw289 rwState + +func (w *rw289) Unwrap() http.ResponseWriter { return w.w } +func (w *rw289) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw289) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw289) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw289) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw289) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw289) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 291/512: http.ResponseWriter, http.Flusher, http.Hijacker, http.Pusher +type rw290 rwState + +func (w *rw290) Unwrap() http.ResponseWriter { return w.w } +func (w *rw290) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw290) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw290) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw290) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw290) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw290) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 292/512: http.ResponseWriter, http.Flusher, http.Hijacker, http.Pusher, io.StringWriter +type rw291 rwState + +func (w *rw291) Unwrap() http.ResponseWriter { return w.w } +func (w *rw291) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw291) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw291) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw291) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw291) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw291) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw291) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 293/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler +type rw292 rwState + +func (w *rw292) Unwrap() http.ResponseWriter { return w.w } +func (w *rw292) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw292) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw292) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw292) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw292) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw292) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 294/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw293 rwState + +func (w *rw293) Unwrap() http.ResponseWriter { return w.w } +func (w *rw293) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw293) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw293) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw293) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw293) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw293) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw293) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 295/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw294 rwState + +func (w *rw294) Unwrap() http.ResponseWriter { return w.w } +func (w *rw294) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw294) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw294) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw294) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw294) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw294) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw294) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 296/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw295 rwState + +func (w *rw295) Unwrap() http.ResponseWriter { return w.w } +func (w *rw295) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw295) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw295) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw295) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw295) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw295) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw295) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw295) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 297/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner +type rw296 rwState + +func (w *rw296) Unwrap() http.ResponseWriter { return w.w } +func (w *rw296) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw296) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw296) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw296) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw296) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw296) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw296) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 298/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, io.StringWriter +type rw297 rwState + +func (w *rw297) Unwrap() http.ResponseWriter { return w.w } +func (w *rw297) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw297) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw297) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw297) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw297) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw297) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw297) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw297) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 299/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, http.Pusher +type rw298 rwState + +func (w *rw298) Unwrap() http.ResponseWriter { return w.w } +func (w *rw298) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw298) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw298) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw298) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw298) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw298) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw298) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw298) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 300/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw299 rwState + +func (w *rw299) Unwrap() http.ResponseWriter { return w.w } +func (w *rw299) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw299) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw299) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw299) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw299) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw299) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw299) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw299) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw299) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 301/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler +type rw300 rwState + +func (w *rw300) Unwrap() http.ResponseWriter { return w.w } +func (w *rw300) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw300) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw300) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw300) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw300) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw300) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw300) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw300) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 302/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw301 rwState + +func (w *rw301) Unwrap() http.ResponseWriter { return w.w } +func (w *rw301) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw301) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw301) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw301) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw301) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw301) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw301) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw301) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw301) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 303/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw302 rwState + +func (w *rw302) Unwrap() http.ResponseWriter { return w.w } +func (w *rw302) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw302) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw302) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw302) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw302) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw302) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw302) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw302) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw302) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 304/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw303 rwState + +func (w *rw303) Unwrap() http.ResponseWriter { return w.w } +func (w *rw303) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw303) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw303) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw303) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw303) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw303) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw303) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw303) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw303) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw303) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 305/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom +type rw304 rwState + +func (w *rw304) Unwrap() http.ResponseWriter { return w.w } +func (w *rw304) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw304) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw304) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw304) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw304) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw304) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 306/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw305 rwState + +func (w *rw305) Unwrap() http.ResponseWriter { return w.w } +func (w *rw305) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw305) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw305) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw305) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw305) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw305) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw305) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 307/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, http.Pusher +type rw306 rwState + +func (w *rw306) Unwrap() http.ResponseWriter { return w.w } +func (w *rw306) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw306) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw306) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw306) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw306) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw306) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw306) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 308/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw307 rwState + +func (w *rw307) Unwrap() http.ResponseWriter { return w.w } +func (w *rw307) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw307) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw307) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw307) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw307) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw307) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw307) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw307) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 309/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw308 rwState + +func (w *rw308) Unwrap() http.ResponseWriter { return w.w } +func (w *rw308) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw308) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw308) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw308) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw308) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw308) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw308) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 310/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw309 rwState + +func (w *rw309) Unwrap() http.ResponseWriter { return w.w } +func (w *rw309) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw309) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw309) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw309) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw309) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw309) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw309) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw309) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 311/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw310 rwState + +func (w *rw310) Unwrap() http.ResponseWriter { return w.w } +func (w *rw310) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw310) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw310) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw310) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw310) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw310) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw310) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw310) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 312/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw311 rwState + +func (w *rw311) Unwrap() http.ResponseWriter { return w.w } +func (w *rw311) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw311) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw311) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw311) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw311) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw311) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw311) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw311) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw311) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 313/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner +type rw312 rwState + +func (w *rw312) Unwrap() http.ResponseWriter { return w.w } +func (w *rw312) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw312) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw312) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw312) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw312) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw312) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw312) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw312) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 314/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw313 rwState + +func (w *rw313) Unwrap() http.ResponseWriter { return w.w } +func (w *rw313) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw313) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw313) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw313) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw313) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw313) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw313) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw313) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw313) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 315/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw314 rwState + +func (w *rw314) Unwrap() http.ResponseWriter { return w.w } +func (w *rw314) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw314) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw314) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw314) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw314) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw314) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw314) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw314) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw314) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 316/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw315 rwState + +func (w *rw315) Unwrap() http.ResponseWriter { return w.w } +func (w *rw315) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw315) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw315) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw315) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw315) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw315) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw315) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw315) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw315) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw315) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 317/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw316 rwState + +func (w *rw316) Unwrap() http.ResponseWriter { return w.w } +func (w *rw316) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw316) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw316) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw316) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw316) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw316) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw316) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw316) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw316) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 318/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw317 rwState + +func (w *rw317) Unwrap() http.ResponseWriter { return w.w } +func (w *rw317) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw317) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw317) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw317) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw317) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw317) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw317) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw317) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw317) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw317) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 319/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw318 rwState + +func (w *rw318) Unwrap() http.ResponseWriter { return w.w } +func (w *rw318) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw318) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw318) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw318) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw318) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw318) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw318) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw318) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw318) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw318) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 320/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw319 rwState + +func (w *rw319) Unwrap() http.ResponseWriter { return w.w } +func (w *rw319) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw319) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw319) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw319) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw319) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw319) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw319) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw319) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw319) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw319) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw319) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 321/512: http.ResponseWriter, http.Flusher, http.CloseNotifier +type rw320 rwState + +func (w *rw320) Unwrap() http.ResponseWriter { return w.w } +func (w *rw320) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw320) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw320) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw320) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw320) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 322/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.StringWriter +type rw321 rwState + +func (w *rw321) Unwrap() http.ResponseWriter { return w.w } +func (w *rw321) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw321) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw321) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw321) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw321) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw321) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 323/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Pusher +type rw322 rwState + +func (w *rw322) Unwrap() http.ResponseWriter { return w.w } +func (w *rw322) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw322) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw322) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw322) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw322) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw322) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 324/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Pusher, io.StringWriter +type rw323 rwState + +func (w *rw323) Unwrap() http.ResponseWriter { return w.w } +func (w *rw323) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw323) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw323) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw323) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw323) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw323) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw323) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 325/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler +type rw324 rwState + +func (w *rw324) Unwrap() http.ResponseWriter { return w.w } +func (w *rw324) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw324) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw324) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw324) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw324) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw324) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 326/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw325 rwState + +func (w *rw325) Unwrap() http.ResponseWriter { return w.w } +func (w *rw325) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw325) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw325) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw325) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw325) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw325) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw325) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 327/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw326 rwState + +func (w *rw326) Unwrap() http.ResponseWriter { return w.w } +func (w *rw326) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw326) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw326) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw326) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw326) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw326) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw326) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 328/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw327 rwState + +func (w *rw327) Unwrap() http.ResponseWriter { return w.w } +func (w *rw327) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw327) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw327) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw327) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw327) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw327) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw327) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw327) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 329/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner +type rw328 rwState + +func (w *rw328) Unwrap() http.ResponseWriter { return w.w } +func (w *rw328) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw328) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw328) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw328) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw328) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw328) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw328) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 330/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, io.StringWriter +type rw329 rwState + +func (w *rw329) Unwrap() http.ResponseWriter { return w.w } +func (w *rw329) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw329) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw329) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw329) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw329) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw329) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw329) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw329) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 331/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, http.Pusher +type rw330 rwState + +func (w *rw330) Unwrap() http.ResponseWriter { return w.w } +func (w *rw330) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw330) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw330) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw330) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw330) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw330) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw330) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw330) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 332/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw331 rwState + +func (w *rw331) Unwrap() http.ResponseWriter { return w.w } +func (w *rw331) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw331) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw331) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw331) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw331) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw331) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw331) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw331) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw331) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 333/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw332 rwState + +func (w *rw332) Unwrap() http.ResponseWriter { return w.w } +func (w *rw332) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw332) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw332) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw332) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw332) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw332) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw332) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw332) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 334/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw333 rwState + +func (w *rw333) Unwrap() http.ResponseWriter { return w.w } +func (w *rw333) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw333) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw333) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw333) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw333) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw333) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw333) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw333) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw333) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 335/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw334 rwState + +func (w *rw334) Unwrap() http.ResponseWriter { return w.w } +func (w *rw334) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw334) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw334) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw334) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw334) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw334) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw334) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw334) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw334) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 336/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw335 rwState + +func (w *rw335) Unwrap() http.ResponseWriter { return w.w } +func (w *rw335) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw335) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw335) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw335) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw335) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw335) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw335) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw335) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw335) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw335) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 337/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom +type rw336 rwState + +func (w *rw336) Unwrap() http.ResponseWriter { return w.w } +func (w *rw336) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw336) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw336) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw336) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw336) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw336) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 338/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw337 rwState + +func (w *rw337) Unwrap() http.ResponseWriter { return w.w } +func (w *rw337) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw337) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw337) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw337) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw337) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw337) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw337) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 339/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw338 rwState + +func (w *rw338) Unwrap() http.ResponseWriter { return w.w } +func (w *rw338) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw338) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw338) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw338) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw338) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw338) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw338) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 340/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw339 rwState + +func (w *rw339) Unwrap() http.ResponseWriter { return w.w } +func (w *rw339) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw339) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw339) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw339) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw339) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw339) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw339) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw339) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 341/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw340 rwState + +func (w *rw340) Unwrap() http.ResponseWriter { return w.w } +func (w *rw340) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw340) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw340) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw340) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw340) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw340) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw340) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 342/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw341 rwState + +func (w *rw341) Unwrap() http.ResponseWriter { return w.w } +func (w *rw341) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw341) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw341) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw341) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw341) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw341) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw341) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw341) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 343/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw342 rwState + +func (w *rw342) Unwrap() http.ResponseWriter { return w.w } +func (w *rw342) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw342) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw342) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw342) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw342) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw342) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw342) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw342) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 344/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw343 rwState + +func (w *rw343) Unwrap() http.ResponseWriter { return w.w } +func (w *rw343) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw343) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw343) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw343) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw343) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw343) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw343) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw343) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw343) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 345/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner +type rw344 rwState + +func (w *rw344) Unwrap() http.ResponseWriter { return w.w } +func (w *rw344) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw344) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw344) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw344) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw344) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw344) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw344) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw344) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 346/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw345 rwState + +func (w *rw345) Unwrap() http.ResponseWriter { return w.w } +func (w *rw345) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw345) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw345) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw345) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw345) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw345) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw345) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw345) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw345) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 347/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw346 rwState + +func (w *rw346) Unwrap() http.ResponseWriter { return w.w } +func (w *rw346) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw346) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw346) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw346) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw346) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw346) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw346) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw346) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw346) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 348/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw347 rwState + +func (w *rw347) Unwrap() http.ResponseWriter { return w.w } +func (w *rw347) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw347) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw347) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw347) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw347) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw347) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw347) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw347) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw347) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw347) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 349/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw348 rwState + +func (w *rw348) Unwrap() http.ResponseWriter { return w.w } +func (w *rw348) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw348) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw348) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw348) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw348) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw348) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw348) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw348) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw348) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 350/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw349 rwState + +func (w *rw349) Unwrap() http.ResponseWriter { return w.w } +func (w *rw349) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw349) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw349) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw349) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw349) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw349) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw349) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw349) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw349) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw349) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 351/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw350 rwState + +func (w *rw350) Unwrap() http.ResponseWriter { return w.w } +func (w *rw350) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw350) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw350) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw350) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw350) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw350) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw350) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw350) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw350) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw350) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 352/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw351 rwState + +func (w *rw351) Unwrap() http.ResponseWriter { return w.w } +func (w *rw351) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw351) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw351) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw351) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw351) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw351) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw351) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw351) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw351) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw351) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw351) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 353/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker +type rw352 rwState + +func (w *rw352) Unwrap() http.ResponseWriter { return w.w } +func (w *rw352) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw352) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw352) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw352) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw352) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw352) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 354/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw353 rwState + +func (w *rw353) Unwrap() http.ResponseWriter { return w.w } +func (w *rw353) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw353) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw353) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw353) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw353) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw353) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw353) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 355/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, http.Pusher +type rw354 rwState + +func (w *rw354) Unwrap() http.ResponseWriter { return w.w } +func (w *rw354) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw354) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw354) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw354) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw354) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw354) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw354) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 356/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw355 rwState + +func (w *rw355) Unwrap() http.ResponseWriter { return w.w } +func (w *rw355) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw355) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw355) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw355) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw355) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw355) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw355) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw355) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 357/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw356 rwState + +func (w *rw356) Unwrap() http.ResponseWriter { return w.w } +func (w *rw356) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw356) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw356) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw356) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw356) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw356) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw356) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 358/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw357 rwState + +func (w *rw357) Unwrap() http.ResponseWriter { return w.w } +func (w *rw357) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw357) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw357) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw357) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw357) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw357) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw357) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw357) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 359/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw358 rwState + +func (w *rw358) Unwrap() http.ResponseWriter { return w.w } +func (w *rw358) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw358) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw358) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw358) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw358) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw358) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw358) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw358) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 360/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw359 rwState + +func (w *rw359) Unwrap() http.ResponseWriter { return w.w } +func (w *rw359) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw359) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw359) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw359) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw359) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw359) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw359) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw359) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw359) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 361/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner +type rw360 rwState + +func (w *rw360) Unwrap() http.ResponseWriter { return w.w } +func (w *rw360) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw360) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw360) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw360) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw360) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw360) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw360) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw360) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 362/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw361 rwState + +func (w *rw361) Unwrap() http.ResponseWriter { return w.w } +func (w *rw361) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw361) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw361) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw361) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw361) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw361) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw361) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw361) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw361) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 363/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw362 rwState + +func (w *rw362) Unwrap() http.ResponseWriter { return w.w } +func (w *rw362) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw362) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw362) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw362) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw362) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw362) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw362) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw362) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw362) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 364/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw363 rwState + +func (w *rw363) Unwrap() http.ResponseWriter { return w.w } +func (w *rw363) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw363) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw363) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw363) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw363) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw363) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw363) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw363) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw363) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw363) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 365/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw364 rwState + +func (w *rw364) Unwrap() http.ResponseWriter { return w.w } +func (w *rw364) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw364) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw364) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw364) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw364) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw364) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw364) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw364) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw364) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 366/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw365 rwState + +func (w *rw365) Unwrap() http.ResponseWriter { return w.w } +func (w *rw365) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw365) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw365) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw365) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw365) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw365) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw365) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw365) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw365) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw365) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 367/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw366 rwState + +func (w *rw366) Unwrap() http.ResponseWriter { return w.w } +func (w *rw366) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw366) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw366) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw366) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw366) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw366) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw366) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw366) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw366) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw366) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 368/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw367 rwState + +func (w *rw367) Unwrap() http.ResponseWriter { return w.w } +func (w *rw367) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw367) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw367) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw367) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw367) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw367) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw367) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw367) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw367) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw367) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw367) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 369/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw368 rwState + +func (w *rw368) Unwrap() http.ResponseWriter { return w.w } +func (w *rw368) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw368) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw368) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw368) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw368) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw368) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw368) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 370/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw369 rwState + +func (w *rw369) Unwrap() http.ResponseWriter { return w.w } +func (w *rw369) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw369) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw369) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw369) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw369) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw369) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw369) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw369) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 371/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw370 rwState + +func (w *rw370) Unwrap() http.ResponseWriter { return w.w } +func (w *rw370) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw370) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw370) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw370) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw370) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw370) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw370) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw370) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 372/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw371 rwState + +func (w *rw371) Unwrap() http.ResponseWriter { return w.w } +func (w *rw371) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw371) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw371) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw371) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw371) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw371) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw371) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw371) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw371) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 373/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw372 rwState + +func (w *rw372) Unwrap() http.ResponseWriter { return w.w } +func (w *rw372) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw372) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw372) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw372) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw372) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw372) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw372) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw372) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 374/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw373 rwState + +func (w *rw373) Unwrap() http.ResponseWriter { return w.w } +func (w *rw373) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw373) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw373) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw373) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw373) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw373) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw373) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw373) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw373) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 375/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw374 rwState + +func (w *rw374) Unwrap() http.ResponseWriter { return w.w } +func (w *rw374) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw374) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw374) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw374) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw374) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw374) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw374) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw374) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw374) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 376/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw375 rwState + +func (w *rw375) Unwrap() http.ResponseWriter { return w.w } +func (w *rw375) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw375) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw375) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw375) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw375) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw375) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw375) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw375) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw375) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw375) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 377/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw376 rwState + +func (w *rw376) Unwrap() http.ResponseWriter { return w.w } +func (w *rw376) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw376) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw376) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw376) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw376) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw376) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw376) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw376) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw376) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 378/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw377 rwState + +func (w *rw377) Unwrap() http.ResponseWriter { return w.w } +func (w *rw377) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw377) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw377) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw377) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw377) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw377) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw377) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw377) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw377) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw377) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 379/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw378 rwState + +func (w *rw378) Unwrap() http.ResponseWriter { return w.w } +func (w *rw378) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw378) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw378) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw378) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw378) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw378) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw378) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw378) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw378) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw378) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 380/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw379 rwState + +func (w *rw379) Unwrap() http.ResponseWriter { return w.w } +func (w *rw379) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw379) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw379) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw379) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw379) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw379) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw379) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw379) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw379) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw379) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw379) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 381/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw380 rwState + +func (w *rw380) Unwrap() http.ResponseWriter { return w.w } +func (w *rw380) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw380) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw380) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw380) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw380) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw380) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw380) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw380) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw380) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw380) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 382/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw381 rwState + +func (w *rw381) Unwrap() http.ResponseWriter { return w.w } +func (w *rw381) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw381) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw381) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw381) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw381) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw381) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw381) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw381) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw381) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw381) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw381) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 383/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw382 rwState + +func (w *rw382) Unwrap() http.ResponseWriter { return w.w } +func (w *rw382) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw382) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw382) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw382) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw382) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw382) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw382) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw382) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw382) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw382) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw382) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 384/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw383 rwState + +func (w *rw383) Unwrap() http.ResponseWriter { return w.w } +func (w *rw383) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw383) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw383) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw383) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw383) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw383) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw383) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw383) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw383) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw383) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw383) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw383) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 385/512: http.ResponseWriter, http.Flusher, httpFlushError +type rw384 rwState + +func (w *rw384) Unwrap() http.ResponseWriter { return w.w } +func (w *rw384) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw384) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw384) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw384) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw384) FlushError() error { + return (*rwState)(w).doFlushError() +} + +// combination 386/512: http.ResponseWriter, http.Flusher, httpFlushError, io.StringWriter +type rw385 rwState + +func (w *rw385) Unwrap() http.ResponseWriter { return w.w } +func (w *rw385) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw385) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw385) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw385) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw385) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw385) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 387/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Pusher +type rw386 rwState + +func (w *rw386) Unwrap() http.ResponseWriter { return w.w } +func (w *rw386) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw386) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw386) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw386) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw386) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw386) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 388/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Pusher, io.StringWriter +type rw387 rwState + +func (w *rw387) Unwrap() http.ResponseWriter { return w.w } +func (w *rw387) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw387) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw387) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw387) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw387) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw387) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw387) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 389/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler +type rw388 rwState + +func (w *rw388) Unwrap() http.ResponseWriter { return w.w } +func (w *rw388) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw388) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw388) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw388) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw388) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw388) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 390/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler, io.StringWriter +type rw389 rwState + +func (w *rw389) Unwrap() http.ResponseWriter { return w.w } +func (w *rw389) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw389) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw389) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw389) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw389) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw389) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw389) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 391/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler, http.Pusher +type rw390 rwState + +func (w *rw390) Unwrap() http.ResponseWriter { return w.w } +func (w *rw390) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw390) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw390) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw390) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw390) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw390) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw390) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 392/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw391 rwState + +func (w *rw391) Unwrap() http.ResponseWriter { return w.w } +func (w *rw391) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw391) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw391) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw391) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw391) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw391) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw391) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw391) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 393/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner +type rw392 rwState + +func (w *rw392) Unwrap() http.ResponseWriter { return w.w } +func (w *rw392) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw392) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw392) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw392) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw392) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw392) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw392) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 394/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, io.StringWriter +type rw393 rwState + +func (w *rw393) Unwrap() http.ResponseWriter { return w.w } +func (w *rw393) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw393) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw393) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw393) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw393) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw393) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw393) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw393) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 395/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, http.Pusher +type rw394 rwState + +func (w *rw394) Unwrap() http.ResponseWriter { return w.w } +func (w *rw394) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw394) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw394) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw394) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw394) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw394) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw394) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw394) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 396/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, http.Pusher, io.StringWriter +type rw395 rwState + +func (w *rw395) Unwrap() http.ResponseWriter { return w.w } +func (w *rw395) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw395) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw395) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw395) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw395) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw395) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw395) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw395) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw395) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 397/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler +type rw396 rwState + +func (w *rw396) Unwrap() http.ResponseWriter { return w.w } +func (w *rw396) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw396) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw396) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw396) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw396) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw396) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw396) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw396) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 398/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler, io.StringWriter +type rw397 rwState + +func (w *rw397) Unwrap() http.ResponseWriter { return w.w } +func (w *rw397) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw397) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw397) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw397) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw397) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw397) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw397) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw397) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw397) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 399/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher +type rw398 rwState + +func (w *rw398) Unwrap() http.ResponseWriter { return w.w } +func (w *rw398) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw398) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw398) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw398) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw398) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw398) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw398) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw398) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw398) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 400/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw399 rwState + +func (w *rw399) Unwrap() http.ResponseWriter { return w.w } +func (w *rw399) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw399) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw399) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw399) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw399) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw399) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw399) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw399) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw399) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw399) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 401/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom +type rw400 rwState + +func (w *rw400) Unwrap() http.ResponseWriter { return w.w } +func (w *rw400) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw400) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw400) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw400) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw400) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw400) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 402/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, io.StringWriter +type rw401 rwState + +func (w *rw401) Unwrap() http.ResponseWriter { return w.w } +func (w *rw401) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw401) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw401) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw401) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw401) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw401) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw401) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 403/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, http.Pusher +type rw402 rwState + +func (w *rw402) Unwrap() http.ResponseWriter { return w.w } +func (w *rw402) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw402) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw402) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw402) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw402) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw402) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw402) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 404/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, http.Pusher, io.StringWriter +type rw403 rwState + +func (w *rw403) Unwrap() http.ResponseWriter { return w.w } +func (w *rw403) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw403) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw403) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw403) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw403) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw403) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw403) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw403) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 405/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler +type rw404 rwState + +func (w *rw404) Unwrap() http.ResponseWriter { return w.w } +func (w *rw404) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw404) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw404) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw404) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw404) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw404) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw404) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 406/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw405 rwState + +func (w *rw405) Unwrap() http.ResponseWriter { return w.w } +func (w *rw405) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw405) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw405) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw405) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw405) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw405) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw405) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw405) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 407/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw406 rwState + +func (w *rw406) Unwrap() http.ResponseWriter { return w.w } +func (w *rw406) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw406) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw406) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw406) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw406) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw406) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw406) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw406) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 408/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw407 rwState + +func (w *rw407) Unwrap() http.ResponseWriter { return w.w } +func (w *rw407) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw407) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw407) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw407) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw407) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw407) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw407) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw407) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw407) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 409/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner +type rw408 rwState + +func (w *rw408) Unwrap() http.ResponseWriter { return w.w } +func (w *rw408) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw408) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw408) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw408) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw408) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw408) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw408) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw408) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 410/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, io.StringWriter +type rw409 rwState + +func (w *rw409) Unwrap() http.ResponseWriter { return w.w } +func (w *rw409) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw409) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw409) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw409) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw409) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw409) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw409) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw409) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw409) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 411/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, http.Pusher +type rw410 rwState + +func (w *rw410) Unwrap() http.ResponseWriter { return w.w } +func (w *rw410) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw410) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw410) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw410) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw410) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw410) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw410) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw410) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw410) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 412/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw411 rwState + +func (w *rw411) Unwrap() http.ResponseWriter { return w.w } +func (w *rw411) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw411) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw411) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw411) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw411) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw411) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw411) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw411) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw411) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw411) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 413/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw412 rwState + +func (w *rw412) Unwrap() http.ResponseWriter { return w.w } +func (w *rw412) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw412) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw412) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw412) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw412) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw412) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw412) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw412) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw412) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 414/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw413 rwState + +func (w *rw413) Unwrap() http.ResponseWriter { return w.w } +func (w *rw413) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw413) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw413) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw413) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw413) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw413) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw413) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw413) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw413) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw413) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 415/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw414 rwState + +func (w *rw414) Unwrap() http.ResponseWriter { return w.w } +func (w *rw414) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw414) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw414) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw414) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw414) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw414) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw414) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw414) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw414) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw414) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 416/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw415 rwState + +func (w *rw415) Unwrap() http.ResponseWriter { return w.w } +func (w *rw415) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw415) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw415) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw415) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw415) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw415) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw415) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw415) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw415) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw415) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw415) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 417/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker +type rw416 rwState + +func (w *rw416) Unwrap() http.ResponseWriter { return w.w } +func (w *rw416) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw416) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw416) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw416) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw416) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw416) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 418/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.StringWriter +type rw417 rwState + +func (w *rw417) Unwrap() http.ResponseWriter { return w.w } +func (w *rw417) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw417) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw417) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw417) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw417) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw417) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw417) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 419/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, http.Pusher +type rw418 rwState + +func (w *rw418) Unwrap() http.ResponseWriter { return w.w } +func (w *rw418) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw418) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw418) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw418) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw418) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw418) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw418) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 420/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, http.Pusher, io.StringWriter +type rw419 rwState + +func (w *rw419) Unwrap() http.ResponseWriter { return w.w } +func (w *rw419) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw419) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw419) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw419) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw419) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw419) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw419) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw419) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 421/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler +type rw420 rwState + +func (w *rw420) Unwrap() http.ResponseWriter { return w.w } +func (w *rw420) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw420) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw420) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw420) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw420) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw420) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw420) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 422/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw421 rwState + +func (w *rw421) Unwrap() http.ResponseWriter { return w.w } +func (w *rw421) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw421) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw421) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw421) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw421) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw421) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw421) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw421) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 423/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw422 rwState + +func (w *rw422) Unwrap() http.ResponseWriter { return w.w } +func (w *rw422) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw422) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw422) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw422) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw422) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw422) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw422) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw422) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 424/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw423 rwState + +func (w *rw423) Unwrap() http.ResponseWriter { return w.w } +func (w *rw423) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw423) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw423) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw423) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw423) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw423) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw423) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw423) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw423) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 425/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner +type rw424 rwState + +func (w *rw424) Unwrap() http.ResponseWriter { return w.w } +func (w *rw424) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw424) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw424) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw424) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw424) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw424) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw424) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw424) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 426/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, io.StringWriter +type rw425 rwState + +func (w *rw425) Unwrap() http.ResponseWriter { return w.w } +func (w *rw425) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw425) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw425) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw425) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw425) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw425) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw425) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw425) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw425) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 427/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, http.Pusher +type rw426 rwState + +func (w *rw426) Unwrap() http.ResponseWriter { return w.w } +func (w *rw426) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw426) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw426) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw426) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw426) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw426) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw426) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw426) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw426) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 428/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw427 rwState + +func (w *rw427) Unwrap() http.ResponseWriter { return w.w } +func (w *rw427) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw427) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw427) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw427) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw427) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw427) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw427) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw427) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw427) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw427) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 429/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler +type rw428 rwState + +func (w *rw428) Unwrap() http.ResponseWriter { return w.w } +func (w *rw428) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw428) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw428) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw428) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw428) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw428) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw428) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw428) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw428) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 430/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw429 rwState + +func (w *rw429) Unwrap() http.ResponseWriter { return w.w } +func (w *rw429) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw429) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw429) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw429) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw429) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw429) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw429) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw429) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw429) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw429) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 431/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw430 rwState + +func (w *rw430) Unwrap() http.ResponseWriter { return w.w } +func (w *rw430) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw430) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw430) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw430) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw430) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw430) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw430) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw430) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw430) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw430) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 432/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw431 rwState + +func (w *rw431) Unwrap() http.ResponseWriter { return w.w } +func (w *rw431) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw431) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw431) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw431) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw431) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw431) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw431) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw431) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw431) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw431) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw431) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 433/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom +type rw432 rwState + +func (w *rw432) Unwrap() http.ResponseWriter { return w.w } +func (w *rw432) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw432) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw432) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw432) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw432) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw432) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw432) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 434/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw433 rwState + +func (w *rw433) Unwrap() http.ResponseWriter { return w.w } +func (w *rw433) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw433) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw433) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw433) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw433) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw433) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw433) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw433) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 435/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher +type rw434 rwState + +func (w *rw434) Unwrap() http.ResponseWriter { return w.w } +func (w *rw434) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw434) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw434) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw434) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw434) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw434) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw434) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw434) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 436/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw435 rwState + +func (w *rw435) Unwrap() http.ResponseWriter { return w.w } +func (w *rw435) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw435) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw435) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw435) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw435) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw435) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw435) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw435) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw435) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 437/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw436 rwState + +func (w *rw436) Unwrap() http.ResponseWriter { return w.w } +func (w *rw436) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw436) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw436) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw436) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw436) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw436) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw436) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw436) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 438/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw437 rwState + +func (w *rw437) Unwrap() http.ResponseWriter { return w.w } +func (w *rw437) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw437) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw437) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw437) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw437) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw437) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw437) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw437) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw437) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 439/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw438 rwState + +func (w *rw438) Unwrap() http.ResponseWriter { return w.w } +func (w *rw438) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw438) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw438) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw438) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw438) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw438) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw438) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw438) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw438) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 440/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw439 rwState + +func (w *rw439) Unwrap() http.ResponseWriter { return w.w } +func (w *rw439) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw439) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw439) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw439) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw439) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw439) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw439) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw439) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw439) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw439) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 441/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner +type rw440 rwState + +func (w *rw440) Unwrap() http.ResponseWriter { return w.w } +func (w *rw440) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw440) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw440) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw440) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw440) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw440) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw440) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw440) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw440) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 442/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw441 rwState + +func (w *rw441) Unwrap() http.ResponseWriter { return w.w } +func (w *rw441) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw441) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw441) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw441) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw441) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw441) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw441) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw441) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw441) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw441) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 443/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw442 rwState + +func (w *rw442) Unwrap() http.ResponseWriter { return w.w } +func (w *rw442) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw442) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw442) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw442) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw442) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw442) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw442) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw442) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw442) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw442) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 444/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw443 rwState + +func (w *rw443) Unwrap() http.ResponseWriter { return w.w } +func (w *rw443) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw443) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw443) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw443) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw443) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw443) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw443) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw443) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw443) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw443) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw443) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 445/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw444 rwState + +func (w *rw444) Unwrap() http.ResponseWriter { return w.w } +func (w *rw444) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw444) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw444) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw444) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw444) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw444) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw444) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw444) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw444) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw444) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 446/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw445 rwState + +func (w *rw445) Unwrap() http.ResponseWriter { return w.w } +func (w *rw445) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw445) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw445) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw445) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw445) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw445) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw445) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw445) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw445) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw445) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw445) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 447/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw446 rwState + +func (w *rw446) Unwrap() http.ResponseWriter { return w.w } +func (w *rw446) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw446) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw446) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw446) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw446) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw446) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw446) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw446) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw446) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw446) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw446) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 448/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw447 rwState + +func (w *rw447) Unwrap() http.ResponseWriter { return w.w } +func (w *rw447) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw447) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw447) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw447) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw447) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw447) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw447) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw447) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw447) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw447) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw447) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw447) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 449/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier +type rw448 rwState + +func (w *rw448) Unwrap() http.ResponseWriter { return w.w } +func (w *rw448) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw448) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw448) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw448) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw448) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw448) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 450/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.StringWriter +type rw449 rwState + +func (w *rw449) Unwrap() http.ResponseWriter { return w.w } +func (w *rw449) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw449) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw449) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw449) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw449) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw449) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw449) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 451/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Pusher +type rw450 rwState + +func (w *rw450) Unwrap() http.ResponseWriter { return w.w } +func (w *rw450) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw450) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw450) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw450) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw450) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw450) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw450) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 452/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Pusher, io.StringWriter +type rw451 rwState + +func (w *rw451) Unwrap() http.ResponseWriter { return w.w } +func (w *rw451) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw451) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw451) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw451) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw451) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw451) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw451) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw451) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 453/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler +type rw452 rwState + +func (w *rw452) Unwrap() http.ResponseWriter { return w.w } +func (w *rw452) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw452) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw452) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw452) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw452) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw452) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw452) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 454/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw453 rwState + +func (w *rw453) Unwrap() http.ResponseWriter { return w.w } +func (w *rw453) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw453) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw453) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw453) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw453) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw453) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw453) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw453) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 455/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw454 rwState + +func (w *rw454) Unwrap() http.ResponseWriter { return w.w } +func (w *rw454) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw454) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw454) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw454) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw454) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw454) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw454) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw454) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 456/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw455 rwState + +func (w *rw455) Unwrap() http.ResponseWriter { return w.w } +func (w *rw455) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw455) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw455) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw455) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw455) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw455) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw455) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw455) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw455) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 457/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner +type rw456 rwState + +func (w *rw456) Unwrap() http.ResponseWriter { return w.w } +func (w *rw456) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw456) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw456) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw456) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw456) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw456) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw456) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw456) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 458/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, io.StringWriter +type rw457 rwState + +func (w *rw457) Unwrap() http.ResponseWriter { return w.w } +func (w *rw457) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw457) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw457) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw457) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw457) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw457) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw457) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw457) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw457) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 459/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, http.Pusher +type rw458 rwState + +func (w *rw458) Unwrap() http.ResponseWriter { return w.w } +func (w *rw458) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw458) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw458) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw458) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw458) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw458) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw458) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw458) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw458) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 460/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw459 rwState + +func (w *rw459) Unwrap() http.ResponseWriter { return w.w } +func (w *rw459) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw459) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw459) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw459) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw459) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw459) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw459) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw459) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw459) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw459) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 461/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw460 rwState + +func (w *rw460) Unwrap() http.ResponseWriter { return w.w } +func (w *rw460) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw460) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw460) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw460) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw460) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw460) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw460) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw460) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw460) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 462/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw461 rwState + +func (w *rw461) Unwrap() http.ResponseWriter { return w.w } +func (w *rw461) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw461) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw461) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw461) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw461) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw461) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw461) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw461) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw461) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw461) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 463/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw462 rwState + +func (w *rw462) Unwrap() http.ResponseWriter { return w.w } +func (w *rw462) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw462) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw462) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw462) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw462) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw462) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw462) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw462) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw462) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw462) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 464/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw463 rwState + +func (w *rw463) Unwrap() http.ResponseWriter { return w.w } +func (w *rw463) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw463) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw463) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw463) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw463) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw463) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw463) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw463) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw463) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw463) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw463) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 465/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom +type rw464 rwState + +func (w *rw464) Unwrap() http.ResponseWriter { return w.w } +func (w *rw464) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw464) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw464) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw464) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw464) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw464) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw464) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 466/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw465 rwState + +func (w *rw465) Unwrap() http.ResponseWriter { return w.w } +func (w *rw465) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw465) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw465) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw465) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw465) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw465) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw465) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw465) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 467/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw466 rwState + +func (w *rw466) Unwrap() http.ResponseWriter { return w.w } +func (w *rw466) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw466) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw466) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw466) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw466) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw466) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw466) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw466) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 468/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw467 rwState + +func (w *rw467) Unwrap() http.ResponseWriter { return w.w } +func (w *rw467) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw467) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw467) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw467) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw467) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw467) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw467) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw467) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw467) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 469/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw468 rwState + +func (w *rw468) Unwrap() http.ResponseWriter { return w.w } +func (w *rw468) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw468) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw468) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw468) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw468) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw468) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw468) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw468) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 470/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw469 rwState + +func (w *rw469) Unwrap() http.ResponseWriter { return w.w } +func (w *rw469) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw469) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw469) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw469) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw469) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw469) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw469) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw469) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw469) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 471/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw470 rwState + +func (w *rw470) Unwrap() http.ResponseWriter { return w.w } +func (w *rw470) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw470) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw470) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw470) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw470) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw470) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw470) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw470) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw470) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 472/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw471 rwState + +func (w *rw471) Unwrap() http.ResponseWriter { return w.w } +func (w *rw471) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw471) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw471) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw471) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw471) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw471) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw471) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw471) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw471) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw471) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 473/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner +type rw472 rwState + +func (w *rw472) Unwrap() http.ResponseWriter { return w.w } +func (w *rw472) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw472) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw472) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw472) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw472) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw472) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw472) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw472) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw472) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 474/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw473 rwState + +func (w *rw473) Unwrap() http.ResponseWriter { return w.w } +func (w *rw473) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw473) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw473) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw473) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw473) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw473) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw473) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw473) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw473) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw473) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 475/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw474 rwState + +func (w *rw474) Unwrap() http.ResponseWriter { return w.w } +func (w *rw474) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw474) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw474) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw474) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw474) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw474) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw474) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw474) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw474) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw474) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 476/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw475 rwState + +func (w *rw475) Unwrap() http.ResponseWriter { return w.w } +func (w *rw475) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw475) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw475) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw475) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw475) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw475) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw475) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw475) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw475) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw475) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw475) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 477/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw476 rwState + +func (w *rw476) Unwrap() http.ResponseWriter { return w.w } +func (w *rw476) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw476) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw476) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw476) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw476) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw476) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw476) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw476) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw476) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw476) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 478/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw477 rwState + +func (w *rw477) Unwrap() http.ResponseWriter { return w.w } +func (w *rw477) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw477) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw477) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw477) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw477) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw477) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw477) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw477) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw477) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw477) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw477) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 479/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw478 rwState + +func (w *rw478) Unwrap() http.ResponseWriter { return w.w } +func (w *rw478) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw478) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw478) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw478) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw478) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw478) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw478) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw478) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw478) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw478) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw478) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 480/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw479 rwState + +func (w *rw479) Unwrap() http.ResponseWriter { return w.w } +func (w *rw479) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw479) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw479) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw479) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw479) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw479) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw479) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw479) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw479) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw479) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw479) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw479) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 481/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker +type rw480 rwState + +func (w *rw480) Unwrap() http.ResponseWriter { return w.w } +func (w *rw480) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw480) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw480) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw480) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw480) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw480) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw480) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 482/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw481 rwState + +func (w *rw481) Unwrap() http.ResponseWriter { return w.w } +func (w *rw481) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw481) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw481) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw481) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw481) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw481) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw481) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw481) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 483/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher +type rw482 rwState + +func (w *rw482) Unwrap() http.ResponseWriter { return w.w } +func (w *rw482) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw482) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw482) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw482) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw482) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw482) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw482) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw482) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 484/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw483 rwState + +func (w *rw483) Unwrap() http.ResponseWriter { return w.w } +func (w *rw483) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw483) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw483) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw483) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw483) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw483) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw483) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw483) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw483) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 485/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw484 rwState + +func (w *rw484) Unwrap() http.ResponseWriter { return w.w } +func (w *rw484) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw484) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw484) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw484) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw484) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw484) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw484) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw484) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 486/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw485 rwState + +func (w *rw485) Unwrap() http.ResponseWriter { return w.w } +func (w *rw485) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw485) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw485) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw485) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw485) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw485) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw485) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw485) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw485) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 487/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw486 rwState + +func (w *rw486) Unwrap() http.ResponseWriter { return w.w } +func (w *rw486) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw486) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw486) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw486) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw486) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw486) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw486) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw486) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw486) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 488/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw487 rwState + +func (w *rw487) Unwrap() http.ResponseWriter { return w.w } +func (w *rw487) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw487) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw487) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw487) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw487) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw487) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw487) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw487) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw487) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw487) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 489/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner +type rw488 rwState + +func (w *rw488) Unwrap() http.ResponseWriter { return w.w } +func (w *rw488) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw488) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw488) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw488) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw488) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw488) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw488) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw488) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw488) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 490/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw489 rwState + +func (w *rw489) Unwrap() http.ResponseWriter { return w.w } +func (w *rw489) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw489) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw489) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw489) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw489) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw489) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw489) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw489) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw489) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw489) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 491/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw490 rwState + +func (w *rw490) Unwrap() http.ResponseWriter { return w.w } +func (w *rw490) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw490) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw490) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw490) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw490) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw490) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw490) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw490) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw490) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw490) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 492/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw491 rwState + +func (w *rw491) Unwrap() http.ResponseWriter { return w.w } +func (w *rw491) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw491) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw491) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw491) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw491) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw491) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw491) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw491) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw491) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw491) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw491) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 493/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw492 rwState + +func (w *rw492) Unwrap() http.ResponseWriter { return w.w } +func (w *rw492) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw492) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw492) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw492) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw492) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw492) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw492) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw492) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw492) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw492) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 494/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw493 rwState + +func (w *rw493) Unwrap() http.ResponseWriter { return w.w } +func (w *rw493) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw493) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw493) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw493) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw493) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw493) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw493) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw493) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw493) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw493) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw493) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 495/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw494 rwState + +func (w *rw494) Unwrap() http.ResponseWriter { return w.w } +func (w *rw494) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw494) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw494) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw494) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw494) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw494) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw494) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw494) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw494) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw494) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw494) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 496/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw495 rwState + +func (w *rw495) Unwrap() http.ResponseWriter { return w.w } +func (w *rw495) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw495) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw495) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw495) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw495) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw495) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw495) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw495) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw495) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw495) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw495) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw495) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 497/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw496 rwState + +func (w *rw496) Unwrap() http.ResponseWriter { return w.w } +func (w *rw496) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw496) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw496) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw496) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw496) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw496) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw496) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw496) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 498/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw497 rwState + +func (w *rw497) Unwrap() http.ResponseWriter { return w.w } +func (w *rw497) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw497) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw497) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw497) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw497) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw497) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw497) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw497) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw497) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 499/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw498 rwState + +func (w *rw498) Unwrap() http.ResponseWriter { return w.w } +func (w *rw498) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw498) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw498) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw498) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw498) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw498) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw498) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw498) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw498) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 500/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw499 rwState + +func (w *rw499) Unwrap() http.ResponseWriter { return w.w } +func (w *rw499) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw499) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw499) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw499) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw499) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw499) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw499) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw499) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw499) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw499) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 501/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw500 rwState + +func (w *rw500) Unwrap() http.ResponseWriter { return w.w } +func (w *rw500) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw500) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw500) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw500) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw500) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw500) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw500) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw500) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw500) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 502/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw501 rwState + +func (w *rw501) Unwrap() http.ResponseWriter { return w.w } +func (w *rw501) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw501) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw501) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw501) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw501) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw501) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw501) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw501) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw501) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw501) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 503/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw502 rwState + +func (w *rw502) Unwrap() http.ResponseWriter { return w.w } +func (w *rw502) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw502) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw502) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw502) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw502) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw502) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw502) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw502) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw502) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw502) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 504/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw503 rwState + +func (w *rw503) Unwrap() http.ResponseWriter { return w.w } +func (w *rw503) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw503) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw503) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw503) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw503) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw503) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw503) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw503) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw503) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw503) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw503) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 505/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw504 rwState + +func (w *rw504) Unwrap() http.ResponseWriter { return w.w } +func (w *rw504) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw504) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw504) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw504) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw504) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw504) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw504) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw504) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw504) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw504) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 506/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw505 rwState + +func (w *rw505) Unwrap() http.ResponseWriter { return w.w } +func (w *rw505) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw505) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw505) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw505) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw505) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw505) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw505) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw505) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw505) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw505) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw505) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 507/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw506 rwState + +func (w *rw506) Unwrap() http.ResponseWriter { return w.w } +func (w *rw506) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw506) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw506) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw506) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw506) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw506) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw506) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw506) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw506) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw506) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw506) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 508/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw507 rwState + +func (w *rw507) Unwrap() http.ResponseWriter { return w.w } +func (w *rw507) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw507) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw507) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw507) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw507) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw507) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw507) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw507) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw507) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw507) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw507) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw507) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 509/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw508 rwState + +func (w *rw508) Unwrap() http.ResponseWriter { return w.w } +func (w *rw508) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw508) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw508) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw508) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw508) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw508) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw508) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw508) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw508) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw508) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw508) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 510/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw509 rwState + +func (w *rw509) Unwrap() http.ResponseWriter { return w.w } +func (w *rw509) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw509) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw509) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw509) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw509) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw509) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw509) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw509) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw509) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw509) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw509) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw509) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 511/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw510 rwState + +func (w *rw510) Unwrap() http.ResponseWriter { return w.w } +func (w *rw510) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw510) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw510) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw510) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw510) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw510) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw510) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw510) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw510) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw510) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw510) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw510) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 512/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw511 rwState + +func (w *rw511) Unwrap() http.ResponseWriter { return w.w } +func (w *rw511) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw511) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw511) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw511) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw511) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw511) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw511) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw511) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw511) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw511) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw511) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw511) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw511) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +type Unwrapper interface { + Unwrap() http.ResponseWriter +} + +// Unwrap returns the underlying http.ResponseWriter from within zero or more +// layers of httpsnoop wrappers. +func Unwrap(w http.ResponseWriter) http.ResponseWriter { + if rw, ok := w.(Unwrapper); ok { + // recurse until rw.Unwrap() returns a non-Unwrapper + return Unwrap(rw.Unwrap()) + } + return w +} diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go deleted file mode 100644 index 101cedde..00000000 --- a/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go +++ /dev/null @@ -1,436 +0,0 @@ -// +build go1.8 -// Code generated by "httpsnoop/codegen"; DO NOT EDIT. - -package httpsnoop - -import ( - "bufio" - "io" - "net" - "net/http" -) - -// HeaderFunc is part of the http.ResponseWriter interface. -type HeaderFunc func() http.Header - -// WriteHeaderFunc is part of the http.ResponseWriter interface. -type WriteHeaderFunc func(code int) - -// WriteFunc is part of the http.ResponseWriter interface. -type WriteFunc func(b []byte) (int, error) - -// FlushFunc is part of the http.Flusher interface. -type FlushFunc func() - -// CloseNotifyFunc is part of the http.CloseNotifier interface. -type CloseNotifyFunc func() <-chan bool - -// HijackFunc is part of the http.Hijacker interface. -type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) - -// ReadFromFunc is part of the io.ReaderFrom interface. -type ReadFromFunc func(src io.Reader) (int64, error) - -// PushFunc is part of the http.Pusher interface. -type PushFunc func(target string, opts *http.PushOptions) error - -// Hooks defines a set of method interceptors for methods included in -// http.ResponseWriter as well as some others. You can think of them as -// middleware for the function calls they target. See Wrap for more details. -type Hooks struct { - Header func(HeaderFunc) HeaderFunc - WriteHeader func(WriteHeaderFunc) WriteHeaderFunc - Write func(WriteFunc) WriteFunc - Flush func(FlushFunc) FlushFunc - CloseNotify func(CloseNotifyFunc) CloseNotifyFunc - Hijack func(HijackFunc) HijackFunc - ReadFrom func(ReadFromFunc) ReadFromFunc - Push func(PushFunc) PushFunc -} - -// Wrap returns a wrapped version of w that provides the exact same interface -// as w. Specifically if w implements any combination of: -// -// - http.Flusher -// - http.CloseNotifier -// - http.Hijacker -// - io.ReaderFrom -// - http.Pusher -// -// The wrapped version will implement the exact same combination. If no hooks -// are set, the wrapped version also behaves exactly as w. Hooks targeting -// methods not supported by w are ignored. Any other hooks will intercept the -// method they target and may modify the call's arguments and/or return values. -// The CaptureMetrics implementation serves as a working example for how the -// hooks can be used. -func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { - rw := &rw{w: w, h: hooks} - _, i0 := w.(http.Flusher) - _, i1 := w.(http.CloseNotifier) - _, i2 := w.(http.Hijacker) - _, i3 := w.(io.ReaderFrom) - _, i4 := w.(http.Pusher) - switch { - // combination 1/32 - case !i0 && !i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - }{rw, rw} - // combination 2/32 - case !i0 && !i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Pusher - }{rw, rw, rw} - // combination 3/32 - case !i0 && !i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - }{rw, rw, rw} - // combination 4/32 - case !i0 && !i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw} - // combination 5/32 - case !i0 && !i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - }{rw, rw, rw} - // combination 6/32 - case !i0 && !i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - http.Pusher - }{rw, rw, rw, rw} - // combination 7/32 - case !i0 && !i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 8/32 - case !i0 && !i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 9/32 - case !i0 && i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - }{rw, rw, rw} - // combination 10/32 - case !i0 && i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Pusher - }{rw, rw, rw, rw} - // combination 11/32 - case !i0 && i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 12/32 - case !i0 && i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 13/32 - case !i0 && i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw} - // combination 14/32 - case !i0 && i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 15/32 - case !i0 && i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 16/32 - case !i0 && i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 17/32 - case i0 && !i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - }{rw, rw, rw} - // combination 18/32 - case i0 && !i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Pusher - }{rw, rw, rw, rw} - // combination 19/32 - case i0 && !i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 20/32 - case i0 && !i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 21/32 - case i0 && !i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - }{rw, rw, rw, rw} - // combination 22/32 - case i0 && !i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 23/32 - case i0 && !i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 24/32 - case i0 && !i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 25/32 - case i0 && i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - }{rw, rw, rw, rw} - // combination 26/32 - case i0 && i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 27/32 - case i0 && i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 28/32 - case i0 && i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 29/32 - case i0 && i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw, rw} - // combination 30/32 - case i0 && i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 31/32 - case i0 && i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw, rw} - // combination 32/32 - case i0 && i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw, rw} - } - panic("unreachable") -} - -type rw struct { - w http.ResponseWriter - h Hooks -} - -func (w *rw) Unwrap() http.ResponseWriter { - return w.w -} - -func (w *rw) Header() http.Header { - f := w.w.(http.ResponseWriter).Header - if w.h.Header != nil { - f = w.h.Header(f) - } - return f() -} - -func (w *rw) WriteHeader(code int) { - f := w.w.(http.ResponseWriter).WriteHeader - if w.h.WriteHeader != nil { - f = w.h.WriteHeader(f) - } - f(code) -} - -func (w *rw) Write(b []byte) (int, error) { - f := w.w.(http.ResponseWriter).Write - if w.h.Write != nil { - f = w.h.Write(f) - } - return f(b) -} - -func (w *rw) Flush() { - f := w.w.(http.Flusher).Flush - if w.h.Flush != nil { - f = w.h.Flush(f) - } - f() -} - -func (w *rw) CloseNotify() <-chan bool { - f := w.w.(http.CloseNotifier).CloseNotify - if w.h.CloseNotify != nil { - f = w.h.CloseNotify(f) - } - return f() -} - -func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { - f := w.w.(http.Hijacker).Hijack - if w.h.Hijack != nil { - f = w.h.Hijack(f) - } - return f() -} - -func (w *rw) ReadFrom(src io.Reader) (int64, error) { - f := w.w.(io.ReaderFrom).ReadFrom - if w.h.ReadFrom != nil { - f = w.h.ReadFrom(f) - } - return f(src) -} - -func (w *rw) Push(target string, opts *http.PushOptions) error { - f := w.w.(http.Pusher).Push - if w.h.Push != nil { - f = w.h.Push(f) - } - return f(target, opts) -} - -type Unwrapper interface { - Unwrap() http.ResponseWriter -} - -// Unwrap returns the underlying http.ResponseWriter from within zero or more -// layers of httpsnoop wrappers. -func Unwrap(w http.ResponseWriter) http.ResponseWriter { - if rw, ok := w.(Unwrapper); ok { - // recurse until rw.Unwrap() returns a non-Unwrapper - return Unwrap(rw.Unwrap()) - } else { - return w - } -} diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go deleted file mode 100644 index e0951df1..00000000 --- a/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go +++ /dev/null @@ -1,278 +0,0 @@ -// +build !go1.8 -// Code generated by "httpsnoop/codegen"; DO NOT EDIT. - -package httpsnoop - -import ( - "bufio" - "io" - "net" - "net/http" -) - -// HeaderFunc is part of the http.ResponseWriter interface. -type HeaderFunc func() http.Header - -// WriteHeaderFunc is part of the http.ResponseWriter interface. -type WriteHeaderFunc func(code int) - -// WriteFunc is part of the http.ResponseWriter interface. -type WriteFunc func(b []byte) (int, error) - -// FlushFunc is part of the http.Flusher interface. -type FlushFunc func() - -// CloseNotifyFunc is part of the http.CloseNotifier interface. -type CloseNotifyFunc func() <-chan bool - -// HijackFunc is part of the http.Hijacker interface. -type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) - -// ReadFromFunc is part of the io.ReaderFrom interface. -type ReadFromFunc func(src io.Reader) (int64, error) - -// Hooks defines a set of method interceptors for methods included in -// http.ResponseWriter as well as some others. You can think of them as -// middleware for the function calls they target. See Wrap for more details. -type Hooks struct { - Header func(HeaderFunc) HeaderFunc - WriteHeader func(WriteHeaderFunc) WriteHeaderFunc - Write func(WriteFunc) WriteFunc - Flush func(FlushFunc) FlushFunc - CloseNotify func(CloseNotifyFunc) CloseNotifyFunc - Hijack func(HijackFunc) HijackFunc - ReadFrom func(ReadFromFunc) ReadFromFunc -} - -// Wrap returns a wrapped version of w that provides the exact same interface -// as w. Specifically if w implements any combination of: -// -// - http.Flusher -// - http.CloseNotifier -// - http.Hijacker -// - io.ReaderFrom -// -// The wrapped version will implement the exact same combination. If no hooks -// are set, the wrapped version also behaves exactly as w. Hooks targeting -// methods not supported by w are ignored. Any other hooks will intercept the -// method they target and may modify the call's arguments and/or return values. -// The CaptureMetrics implementation serves as a working example for how the -// hooks can be used. -func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { - rw := &rw{w: w, h: hooks} - _, i0 := w.(http.Flusher) - _, i1 := w.(http.CloseNotifier) - _, i2 := w.(http.Hijacker) - _, i3 := w.(io.ReaderFrom) - switch { - // combination 1/16 - case !i0 && !i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - }{rw, rw} - // combination 2/16 - case !i0 && !i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - }{rw, rw, rw} - // combination 3/16 - case !i0 && !i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - }{rw, rw, rw} - // combination 4/16 - case !i0 && !i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 5/16 - case !i0 && i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - }{rw, rw, rw} - // combination 6/16 - case !i0 && i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 7/16 - case !i0 && i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw} - // combination 8/16 - case !i0 && i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 9/16 - case i0 && !i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - }{rw, rw, rw} - // combination 10/16 - case i0 && !i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 11/16 - case i0 && !i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - }{rw, rw, rw, rw} - // combination 12/16 - case i0 && !i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 13/16 - case i0 && i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - }{rw, rw, rw, rw} - // combination 14/16 - case i0 && i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 15/16 - case i0 && i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw, rw} - // combination 16/16 - case i0 && i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw, rw} - } - panic("unreachable") -} - -type rw struct { - w http.ResponseWriter - h Hooks -} - -func (w *rw) Unwrap() http.ResponseWriter { - return w.w -} - -func (w *rw) Header() http.Header { - f := w.w.(http.ResponseWriter).Header - if w.h.Header != nil { - f = w.h.Header(f) - } - return f() -} - -func (w *rw) WriteHeader(code int) { - f := w.w.(http.ResponseWriter).WriteHeader - if w.h.WriteHeader != nil { - f = w.h.WriteHeader(f) - } - f(code) -} - -func (w *rw) Write(b []byte) (int, error) { - f := w.w.(http.ResponseWriter).Write - if w.h.Write != nil { - f = w.h.Write(f) - } - return f(b) -} - -func (w *rw) Flush() { - f := w.w.(http.Flusher).Flush - if w.h.Flush != nil { - f = w.h.Flush(f) - } - f() -} - -func (w *rw) CloseNotify() <-chan bool { - f := w.w.(http.CloseNotifier).CloseNotify - if w.h.CloseNotify != nil { - f = w.h.CloseNotify(f) - } - return f() -} - -func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { - f := w.w.(http.Hijacker).Hijack - if w.h.Hijack != nil { - f = w.h.Hijack(f) - } - return f() -} - -func (w *rw) ReadFrom(src io.Reader) (int64, error) { - f := w.w.(io.ReaderFrom).ReadFrom - if w.h.ReadFrom != nil { - f = w.h.ReadFrom(f) - } - return f(src) -} - -type Unwrapper interface { - Unwrap() http.ResponseWriter -} - -// Unwrap returns the underlying http.ResponseWriter from within zero or more -// layers of httpsnoop wrappers. -func Unwrap(w http.ResponseWriter) http.ResponseWriter { - if rw, ok := w.(Unwrapper); ok { - // recurse until rw.Unwrap() returns a non-Unwrapper - return Unwrap(rw.Unwrap()) - } else { - return w - } -} diff --git a/vendor/github.com/fxamacker/cbor/v2/.golangci.yml b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml index 38cb9ae1..08081fbd 100644 --- a/vendor/github.com/fxamacker/cbor/v2/.golangci.yml +++ b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml @@ -1,104 +1,116 @@ -# Do not delete linter settings. Linters like gocritic can be enabled on the command line. - -linters-settings: - depguard: - rules: - prevent_unmaintained_packages: - list-mode: strict - files: - - $all - - "!$test" - allow: - - $gostd - - github.com/x448/float16 - deny: - - pkg: io/ioutil - desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil" - dupl: - threshold: 100 - funlen: - lines: 100 - statements: 50 - goconst: - ignore-tests: true - min-len: 2 - min-occurrences: 3 - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - - commentedOutCode - - dupImport # https://github.com/go-critic/go-critic/issues/845 - - ifElseChain - - octalLiteral - - paramTypeCombine - - whyNoLint - gofmt: - simplify: false - goimports: - local-prefixes: github.com/fxamacker/cbor - golint: - min-confidence: 0 - govet: - check-shadowing: true - lll: - line-length: 140 - maligned: - suggest-new: true - misspell: - locale: US - staticcheck: - checks: ["all"] - +version: "2" linters: - disable-all: true + default: none enable: - asciicheck - bidichk - depguard - errcheck - - exportloopref + - forbidigo - goconst - gocritic - gocyclo - - gofmt - - goimports - goprintffuncname - gosec - - gosimple - govet - ineffassign - misspell - nilerr - revive - staticcheck - - stylecheck - - typecheck - unconvert - unused - + settings: + depguard: + rules: + prevent_unmaintained_packages: + list-mode: strict + files: + - $all + - '!$test' + allow: + - $gostd + - github.com/x448/float16 + deny: + - pkg: io/ioutil + desc: 'replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil' + dupl: + threshold: 100 + funlen: + lines: 100 + statements: 50 + goconst: + min-len: 2 + min-occurrences: 3 + gocritic: + disabled-checks: + - commentedOutCode + - dupImport + - ifElseChain + - octalLiteral + - paramTypeCombine + - whyNoLint + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + govet: + enable: + - shadow + lll: + line-length: 140 + misspell: + locale: US + staticcheck: + checks: + - all + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - path: decode.go + text: string ` overflows ` has (\d+) occurrences, make it a constant + - path: decode.go + text: string ` \(range is \[` has (\d+) occurrences, make it a constant + - path: decode.go + text: string `, ` has (\d+) occurrences, make it a constant + - path: decode.go + text: string ` overflows Go's int64` has (\d+) occurrences, make it a constant + - path: decode.go + text: string `\]\)` has (\d+) occurrences, make it a constant + - path: valid.go + text: string ` for type ` has (\d+) occurrences, make it a constant + - path: valid.go + text: 'string `cbor: ` has (\d+) occurrences, make it a constant' + - linters: + - goconst + path: (.+)_test\.go + paths: + - third_party$ + - builtin$ + - examples$ issues: - # max-issues-per-linter default is 50. Set to 0 to disable limit. max-issues-per-linter: 0 - # max-same-issues default is 3. Set to 0 to disable limit. max-same-issues: 0 - - exclude-rules: - - path: decode.go - text: "string ` overflows ` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string ` \\(range is \\[` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string `, ` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string ` overflows Go's int64` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string `\\]\\)` has (\\d+) occurrences, make it a constant" - - path: valid.go - text: "string ` for type ` has (\\d+) occurrences, make it a constant" - - path: valid.go - text: "string `cbor: ` has (\\d+) occurrences, make it a constant" +formatters: + enable: + - gofmt + - goimports + settings: + gofmt: + simplify: false + goimports: + local-prefixes: + - github.com/fxamacker/cbor + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/vendor/github.com/fxamacker/cbor/v2/README.md b/vendor/github.com/fxamacker/cbor/v2/README.md index d072b81c..f9ae78ec 100644 --- a/vendor/github.com/fxamacker/cbor/v2/README.md +++ b/vendor/github.com/fxamacker/cbor/v2/README.md @@ -702,21 +702,20 @@ Default limits may need to be increased for systems handling very large data (e. ## Status -[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. -- Add opt-in support for `encoding.TextMarshaler` and `encoding.TextUnmarshaler` to encode and decode from CBOR text string. -- Add opt-in support for `json.Marshaler` and `json.Unmarshaler` via user-provided transcoding function. -- Update docs for TimeMode, Tag, RawTag, and add example for Embedded JSON Tag for CBOR. +v2.9.1 (Mar 29-30, 2026) includes important bugfixes, defensive checks, improved code quality, and more tests. Although not public, the fuzzer was also improved by adding more fuzz tests. -v2.9.0 passed fuzz tests and is production quality. +v2.9.1 passed fuzz tests and is production quality. The minimum version of Go required to build: - v2.8.0 and newer releases require go 1.20+. - v2.7.1 and older releases require go 1.17+. -For more details, see [release notes](https://github.com/fxamacker/cbor/releases). +For more details, see [v2.9.1 release notes](https://github.com/fxamacker/cbor/releases). ### Prior Releases +[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. It passed fuzz tests (billions of executions) and is production quality. + [v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality. [v2.7.0](https://github.com/fxamacker/cbor/releases/tag/v2.7.0) (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. diff --git a/vendor/github.com/fxamacker/cbor/v2/cache.go b/vendor/github.com/fxamacker/cbor/v2/cache.go index 5051f110..5743f3eb 100644 --- a/vendor/github.com/fxamacker/cbor/v2/cache.go +++ b/vendor/github.com/fxamacker/cbor/v2/cache.go @@ -92,94 +92,126 @@ func newTypeInfo(t reflect.Type) *typeInfo { } type decodingStructType struct { - fields fields - fieldIndicesByName map[string]int - err error - toArray bool + fields decodingFields + fieldIndicesByName map[string]int // Only populated if toArray is false + fieldIndicesByIntKey map[int64]int // Only populated if toArray is false + err error + toArray bool } -// The stdlib errors.Join was introduced in Go 1.20, and we still support Go 1.17, so instead, -// here's a very basic implementation of an aggregated error. -type multierror []error - -func (m multierror) Error() string { - var sb strings.Builder - for i, err := range m { - sb.WriteString(err.Error()) - if i < len(m)-1 { - sb.WriteString(", ") - } - } - return sb.String() -} - -func getDecodingStructType(t reflect.Type) *decodingStructType { +func getDecodingStructType(t reflect.Type) (*decodingStructType, error) { if v, _ := decodingStructTypeCache.Load(t); v != nil { - return v.(*decodingStructType) + structType := v.(*decodingStructType) + if structType.err != nil { + return nil, structType.err + } + return structType, nil } flds, structOptions := getFields(t) toArray := hasToArrayOption(structOptions) - var errs []error - for i := 0; i < len(flds); i++ { - if flds[i].keyAsInt { - nameAsInt, numErr := strconv.Atoi(flds[i].name) - if numErr != nil { - errs = append(errs, errors.New("cbor: failed to parse field name \""+flds[i].name+"\" to int ("+numErr.Error()+")")) - break + if toArray { + return getDecodingStructToArrayType(t, flds) + } + + fieldIndicesByName := make(map[string]int, len(flds)) + var fieldIndicesByIntKey map[int64]int + + decFlds := make(decodingFields, len(flds)) + for i, f := range flds { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if f.keyAsInt && f.nameAsInt == 0 { + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &decodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err } - flds[i].nameAsInt = int64(nameAsInt) } - flds[i].typInfo = getTypeInfo(flds[i].typ) - } + if f.keyAsInt { + if fieldIndicesByIntKey == nil { + fieldIndicesByIntKey = make(map[int64]int, len(flds)) + } + // The duplication check is only a safeguard, since getFields() already deduplicates fields. + if _, ok := fieldIndicesByIntKey[f.nameAsInt]; ok { + structType := &decodingStructType{ + err: fmt.Errorf("cbor: two or more fields of %v have the same keyasint value %d", t, f.nameAsInt), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err + } + fieldIndicesByIntKey[f.nameAsInt] = i + } else { + // The duplication check is only a safeguard, since getFields() already deduplicates fields. + if _, ok := fieldIndicesByName[f.name]; ok { + structType := &decodingStructType{ + err: fmt.Errorf("cbor: two or more fields of %v have the same name %q", t, f.name), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err + } + fieldIndicesByName[f.name] = i + } - fieldIndicesByName := make(map[string]int, len(flds)) - for i, fld := range flds { - if _, ok := fieldIndicesByName[fld.name]; ok { - errs = append(errs, fmt.Errorf("cbor: two or more fields of %v have the same name %q", t, fld.name)) - continue + decFlds[i] = &decodingField{ + field: *f, + typInfo: getTypeInfo(f.typ), } - fieldIndicesByName[fld.name] = i } - var err error - { - var multi multierror - for _, each := range errs { - if each != nil { - multi = append(multi, each) + structType := &decodingStructType{ + fields: decFlds, + fieldIndicesByName: fieldIndicesByName, + fieldIndicesByIntKey: fieldIndicesByIntKey, + } + decodingStructTypeCache.Store(t, structType) + return structType, nil +} + +func getDecodingStructToArrayType(t reflect.Type, flds fields) (*decodingStructType, error) { + decFlds := make(decodingFields, len(flds)) + for i, f := range flds { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if f.keyAsInt && f.nameAsInt == 0 { + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &decodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err } } - if len(multi) == 1 { - err = multi[0] - } else if len(multi) > 1 { - err = multi + + decFlds[i] = &decodingField{ + field: *f, + typInfo: getTypeInfo(f.typ), } } structType := &decodingStructType{ - fields: flds, - fieldIndicesByName: fieldIndicesByName, - err: err, - toArray: toArray, + fields: decFlds, + toArray: true, } decodingStructTypeCache.Store(t, structType) - return structType + return structType, nil } type encodingStructType struct { - fields fields - bytewiseFields fields - lengthFirstFields fields - omitEmptyFieldsIdx []int + fields encodingFields + bytewiseFields encodingFields // Only populated if toArray is false + lengthFirstFields encodingFields // Only populated if toArray is false + omitEmptyFieldsIdx []int // Only populated if toArray is false err error toArray bool } -func (st *encodingStructType) getFields(em *encMode) fields { +func (st *encodingStructType) getFields(em *encMode) encodingFields { switch em.sort { case SortNone, SortFastShuffle: return st.fields @@ -191,7 +223,7 @@ func (st *encodingStructType) getFields(em *encMode) fields { } type bytewiseFieldSorter struct { - fields fields + fields encodingFields } func (x *bytewiseFieldSorter) Len() int { @@ -203,11 +235,11 @@ func (x *bytewiseFieldSorter) Swap(i, j int) { } func (x *bytewiseFieldSorter) Less(i, j int) bool { - return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0 + return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) < 0 } type lengthFirstFieldSorter struct { - fields fields + fields encodingFields } func (x *lengthFirstFieldSorter) Len() int { @@ -222,13 +254,16 @@ func (x *lengthFirstFieldSorter) Less(i, j int) bool { if len(x.fields[i].cborName) != len(x.fields[j].cborName) { return len(x.fields[i].cborName) < len(x.fields[j].cborName) } - return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0 + return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) < 0 } func getEncodingStructType(t reflect.Type) (*encodingStructType, error) { if v, _ := encodingStructTypeCache.Load(t); v != nil { structType := v.(*encodingStructType) - return structType, structType.err + if structType.err != nil { + return nil, structType.err + } + return structType, nil } flds, structOptions := getFields(t) @@ -237,111 +272,119 @@ func getEncodingStructType(t reflect.Type) (*encodingStructType, error) { return getEncodingStructToArrayType(t, flds) } - var err error var hasKeyAsInt bool var hasKeyAsStr bool var omitEmptyIdx []int + + encFlds := make(encodingFields, len(flds)) + e := getEncodeBuffer() - for i := 0; i < len(flds); i++ { + defer putEncodeBuffer(e) + + for i, f := range flds { + encFlds[i] = &encodingField{field: *f} + ef := encFlds[i] + // Get field's encodeFunc - flds[i].ef, flds[i].ief, flds[i].izf = getEncodeFunc(flds[i].typ) - if flds[i].ef == nil { - err = &UnsupportedTypeError{t} - break + ef.ef, ef.ief, ef.izf = getEncodeFunc(f.typ) + if ef.ef == nil { + structType := &encodingStructType{err: &UnsupportedTypeError{t}} + encodingStructTypeCache.Store(t, structType) + return nil, structType.err } // Encode field name - if flds[i].keyAsInt { - nameAsInt, numErr := strconv.Atoi(flds[i].name) - if numErr != nil { - err = errors.New("cbor: failed to parse field name \"" + flds[i].name + "\" to int (" + numErr.Error() + ")") - break + if f.keyAsInt { + if f.nameAsInt == 0 { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &encodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + encodingStructTypeCache.Store(t, structType) + return nil, structType.err + } } - flds[i].nameAsInt = int64(nameAsInt) + nameAsInt := f.nameAsInt if nameAsInt >= 0 { - encodeHead(e, byte(cborTypePositiveInt), uint64(nameAsInt)) + encodeHead(e, byte(cborTypePositiveInt), uint64(nameAsInt)) //nolint:gosec } else { n := nameAsInt*(-1) - 1 - encodeHead(e, byte(cborTypeNegativeInt), uint64(n)) + encodeHead(e, byte(cborTypeNegativeInt), uint64(n)) //nolint:gosec } - flds[i].cborName = make([]byte, e.Len()) - copy(flds[i].cborName, e.Bytes()) + ef.cborName = make([]byte, e.Len()) + copy(ef.cborName, e.Bytes()) e.Reset() hasKeyAsInt = true } else { - encodeHead(e, byte(cborTypeTextString), uint64(len(flds[i].name))) - flds[i].cborName = make([]byte, e.Len()+len(flds[i].name)) - n := copy(flds[i].cborName, e.Bytes()) - copy(flds[i].cborName[n:], flds[i].name) + encodeHead(e, byte(cborTypeTextString), uint64(len(f.name))) + ef.cborName = make([]byte, e.Len()+len(f.name)) + n := copy(ef.cborName, e.Bytes()) + copy(ef.cborName[n:], f.name) e.Reset() // If cborName contains a text string, then cborNameByteString contains a // string that has the byte string major type but is otherwise identical to // cborName. - flds[i].cborNameByteString = make([]byte, len(flds[i].cborName)) - copy(flds[i].cborNameByteString, flds[i].cborName) + ef.cborNameByteString = make([]byte, len(ef.cborName)) + copy(ef.cborNameByteString, ef.cborName) // Reset encoded CBOR type to byte string, preserving the "additional // information" bits: - flds[i].cborNameByteString[0] = byte(cborTypeByteString) | - getAdditionalInformation(flds[i].cborNameByteString[0]) + ef.cborNameByteString[0] = byte(cborTypeByteString) | + getAdditionalInformation(ef.cborNameByteString[0]) hasKeyAsStr = true } // Check if field can be omitted when empty - if flds[i].omitEmpty { + if f.omitEmpty { omitEmptyIdx = append(omitEmptyIdx, i) } } - putEncodeBuffer(e) - - if err != nil { - structType := &encodingStructType{err: err} - encodingStructTypeCache.Store(t, structType) - return structType, structType.err - } // Sort fields by canonical order - bytewiseFields := make(fields, len(flds)) - copy(bytewiseFields, flds) + bytewiseFields := make(encodingFields, len(encFlds)) + copy(bytewiseFields, encFlds) sort.Sort(&bytewiseFieldSorter{bytewiseFields}) lengthFirstFields := bytewiseFields if hasKeyAsInt && hasKeyAsStr { - lengthFirstFields = make(fields, len(flds)) - copy(lengthFirstFields, flds) + lengthFirstFields = make(encodingFields, len(encFlds)) + copy(lengthFirstFields, encFlds) sort.Sort(&lengthFirstFieldSorter{lengthFirstFields}) } structType := &encodingStructType{ - fields: flds, + fields: encFlds, bytewiseFields: bytewiseFields, lengthFirstFields: lengthFirstFields, omitEmptyFieldsIdx: omitEmptyIdx, } encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return structType, nil } func getEncodingStructToArrayType(t reflect.Type, flds fields) (*encodingStructType, error) { - for i := 0; i < len(flds); i++ { - // Get field's encodeFunc - flds[i].ef, flds[i].ief, flds[i].izf = getEncodeFunc(flds[i].typ) - if flds[i].ef == nil { + encFlds := make(encodingFields, len(flds)) + for i, f := range flds { + encFlds[i] = &encodingField{field: *f} + encFlds[i].ef, encFlds[i].ief, encFlds[i].izf = getEncodeFunc(f.typ) + if encFlds[i].ef == nil { structType := &encodingStructType{err: &UnsupportedTypeError{t}} encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return nil, structType.err } } structType := &encodingStructType{ - fields: flds, + fields: encFlds, toArray: true, } encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return structType, nil } func getEncodeFunc(t reflect.Type) (encodeFunc, isEmptyFunc, isZeroFunc) { diff --git a/vendor/github.com/fxamacker/cbor/v2/decode.go b/vendor/github.com/fxamacker/cbor/v2/decode.go index f0bdc3b3..03fd7f8b 100644 --- a/vendor/github.com/fxamacker/cbor/v2/decode.go +++ b/vendor/github.com/fxamacker/cbor/v2/decode.go @@ -16,7 +16,6 @@ import ( "math/big" "reflect" "strconv" - "strings" "time" "unicode/utf8" @@ -326,14 +325,14 @@ func (dmkm DupMapKeyMode) valid() bool { return dmkm >= 0 && dmkm < maxDupMapKeyMode } -// IndefLengthMode specifies whether to allow indefinite length items. +// IndefLengthMode specifies whether to allow indefinite-length items. type IndefLengthMode int const ( - // IndefLengthAllowed allows indefinite length items. + // IndefLengthAllowed allows indefinite-length items. IndefLengthAllowed IndefLengthMode = iota - // IndefLengthForbidden disallows indefinite length items. + // IndefLengthForbidden disallows indefinite-length items. IndefLengthForbidden maxIndefLengthMode @@ -378,6 +377,7 @@ const ( // - int64 if value fits // - big.Int or *big.Int (see BigIntDecMode) if value < math.MinInt64 // - return UnmarshalTypeError if value > math.MaxInt64 + // // Deprecated: IntDecConvertSigned should not be used. // Please use other options, such as IntDecConvertSignedOrError, IntDecConvertSignedOrBigInt, IntDecConvertNone. IntDecConvertSigned @@ -811,7 +811,7 @@ type DecOptions struct { // Default is 128*1024=131072 and it can be set to [16, 2147483647] MaxMapPairs int - // IndefLength specifies whether to allow indefinite length CBOR items. + // IndefLength specifies whether to allow indefinite-length CBOR items. IndefLength IndefLengthMode // TagsMd specifies whether to allow CBOR tags (major type 6). @@ -1055,7 +1055,7 @@ func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore } if !opts.ExtraReturnErrors.valid() { - return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors))) + return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors))) //nolint:gosec } if opts.DefaultMapType != nil && opts.DefaultMapType.Kind() != reflect.Map { @@ -1149,8 +1149,8 @@ func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore unrecognizedTagToAny: opts.UnrecognizedTagToAny, timeTagToAny: opts.TimeTagToAny, simpleValues: simpleValues, - nanDec: opts.NaN, - infDec: opts.Inf, + nan: opts.NaN, + inf: opts.Inf, byteStringToTime: opts.ByteStringToTime, byteStringExpectedFormat: opts.ByteStringExpectedFormat, bignumTag: opts.BignumTag, @@ -1230,8 +1230,8 @@ type decMode struct { unrecognizedTagToAny UnrecognizedTagToAnyMode timeTagToAny TimeTagToAnyMode simpleValues *SimpleValueRegistry - nanDec NaNMode - infDec InfMode + nan NaNMode + inf InfMode byteStringToTime ByteStringToTimeMode byteStringExpectedFormat ByteStringExpectedFormatMode bignumTag BignumTagMode @@ -1272,8 +1272,8 @@ func (dm *decMode) DecOptions() DecOptions { UnrecognizedTagToAny: dm.unrecognizedTagToAny, TimeTagToAny: dm.timeTagToAny, SimpleValues: simpleValues, - NaN: dm.nanDec, - Inf: dm.infDec, + NaN: dm.nan, + Inf: dm.inf, ByteStringToTime: dm.byteStringToTime, ByteStringExpectedFormat: dm.byteStringExpectedFormat, BignumTag: dm.bignumTag, @@ -1583,11 +1583,11 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin _, ai, val := d.getHead() switch ai { case additionalInformationAsFloat16: - f := float64(float16.Frombits(uint16(val)).Float32()) + f := float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec return fillFloat(t, f, v) case additionalInformationAsFloat32: - f := float64(math.Float32frombits(uint32(val))) + f := float64(math.Float32frombits(uint32(val))) //nolint:gosec return fillFloat(t, f, v) case additionalInformationAsFloat64: @@ -1595,10 +1595,10 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin return fillFloat(t, f, v) default: // ai <= 24 - if d.dm.simpleValues.rejected[SimpleValue(val)] { + if d.dm.simpleValues.rejected[SimpleValue(val)] { //nolint:gosec return &UnacceptableDataItemError{ CBORType: t.String(), - Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", + Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", //nolint:gosec } } @@ -1677,20 +1677,23 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin return d.parseToValue(v, tInfo) case cborTypeArray: - if tInfo.nonPtrKind == reflect.Slice { + switch tInfo.nonPtrKind { + case reflect.Slice: return d.parseArrayToSlice(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Array { + case reflect.Array: return d.parseArrayToArray(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Struct { + case reflect.Struct: return d.parseArrayToStruct(v, tInfo) } + d.skip() return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()} case cborTypeMap: - if tInfo.nonPtrKind == reflect.Struct { + switch tInfo.nonPtrKind { + case reflect.Struct: return d.parseMapToStruct(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Map { + case reflect.Map: return d.parseMapToMap(v, tInfo) } d.skip() @@ -1745,8 +1748,8 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { // Read tag number _, _, tagNum := d.getHead() if tagNum != 0 && tagNum != 1 { - d.skip() // skip tag content - return time.Time{}, false, errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1") + d.skip() // skip tag content + return time.Time{}, false, errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1") //nolint:gosec } } } else { @@ -1815,10 +1818,10 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { var f float64 switch ai { case additionalInformationAsFloat16: - f = float64(float16.Frombits(uint16(val)).Float32()) + f = float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec case additionalInformationAsFloat32: - f = float64(math.Float32frombits(uint32(val))) + f = float64(math.Float32frombits(uint32(val))) //nolint:gosec case additionalInformationAsFloat64: f = math.Float64frombits(val) @@ -1832,6 +1835,13 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { return time.Time{}, true, nil } seconds, fractional := math.Modf(f) + if seconds > math.MaxInt64 || seconds < math.MinInt64 { + return time.Time{}, false, &UnmarshalTypeError{ + CBORType: t.String(), + GoType: typeTime.String(), + errorMsg: fmt.Sprintf("%v overflows Go's int64", f), + } + } return time.Unix(int64(seconds), int64(fractional*1e9)), true, nil default: @@ -2145,14 +2155,14 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc case cborTypePrimitives: _, ai, val := d.getHead() - if ai <= 24 && d.dm.simpleValues.rejected[SimpleValue(val)] { + if ai <= 24 && d.dm.simpleValues.rejected[SimpleValue(val)] { //nolint:gosec return nil, &UnacceptableDataItemError{ CBORType: t.String(), - Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", + Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", //nolint:gosec } } if ai < 20 || ai == 24 { - return SimpleValue(val), nil + return SimpleValue(val), nil //nolint:gosec } switch ai { @@ -2165,11 +2175,11 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc return nil, nil case additionalInformationAsFloat16: - f := float64(float16.Frombits(uint16(val)).Float32()) + f := float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec return f, nil case additionalInformationAsFloat32: - f := float64(math.Float32frombits(uint32(val))) + f := float64(math.Float32frombits(uint32(val))) //nolint:gosec return f, nil case additionalInformationAsFloat64: @@ -2202,16 +2212,16 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc func (d *decoder) parseByteString() ([]byte, bool) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() if !indefiniteLength { - b := d.data[d.off : d.off+int(val)] - d.off += int(val) + b := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec return b, false } - // Process indefinite length string chunks. + // Process indefinite-length string chunks. b := []byte{} for !d.foundBreak() { _, _, val = d.getHead() - b = append(b, d.data[d.off:d.off+int(val)]...) - d.off += int(val) + b = append(b, d.data[d.off:d.off+int(val)]...) //nolint:gosec + d.off += int(val) //nolint:gosec } return b, true } @@ -2300,19 +2310,19 @@ func (d *decoder) applyByteStringTextConversion( func (d *decoder) parseTextString() ([]byte, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() if !indefiniteLength { - b := d.data[d.off : d.off+int(val)] - d.off += int(val) + b := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(b) { return nil, &SemanticError{"cbor: invalid UTF-8 string"} } return b, nil } - // Process indefinite length string chunks. + // Process indefinite-length string chunks. b := []byte{} for !d.foundBreak() { _, _, val = d.getHead() - x := d.data[d.off : d.off+int(val)] - d.off += int(val) + x := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(x) { for !d.foundBreak() { d.skip() // Skip remaining chunk on error @@ -2327,7 +2337,7 @@ func (d *decoder) parseTextString() ([]byte, error) { func (d *decoder) parseArray() ([]any, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance } @@ -2349,7 +2359,7 @@ func (d *decoder) parseArray() ([]any, error) { func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance } @@ -2371,7 +2381,7 @@ func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error { func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec gi := 0 vLen := v.Len() var err error @@ -2400,7 +2410,7 @@ func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error { func (d *decoder) parseMap() (any, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec m := make(map[any]any) var k, e any var err, lastErr error @@ -2465,7 +2475,7 @@ func (d *decoder) parseMap() (any, error) { func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if v.IsNil() { mapsize := count if !hasSize { @@ -2566,9 +2576,9 @@ func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //noli } func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { - structType := getDecodingStructType(tInfo.nonPtrType) - if structType.err != nil { - return structType.err + structType, structTypeErr := getDecodingStructType(tInfo.nonPtrType) + if structTypeErr != nil { + return structTypeErr } if !structType.toArray { @@ -2584,7 +2594,7 @@ func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { start := d.off _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size } @@ -2637,11 +2647,72 @@ func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { return err } -// parseMapToStruct needs to be fast so gocyclo can be ignored for now. +// skipMapEntriesFromIndex skips remaining map entries starting from index i. +func (d *decoder) skipMapEntriesFromIndex(i, count int, hasSize bool) { + for ; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { + d.skip() + d.skip() + } +} + +// skipMapForDupKey skips the current map value and all remaining map entries, +// then returns a DupMapKeyError for the given key at map index i. +func (d *decoder) skipMapForDupKey(dupKey any, i, count int, hasSize bool) error { + // Skip the value of the duplicate key. + d.skip() + // Skip all remaining map entries. + d.skipMapEntriesFromIndex(i+1, count, hasSize) + return &DupMapKeyError{dupKey, i} +} + +// skipMapForUnknownField skips the current map value and all remaining map entries, +// then returns a UnknownFieldError for the given key at map index i. +func (d *decoder) skipMapForUnknownField(i, count int, hasSize bool) error { + // Skip the value of the unknown key. + d.skip() + // Skip all remaining map entries. + d.skipMapEntriesFromIndex(i+1, count, hasSize) + return &UnknownFieldError{i} +} + +// decodeToStructField decodes the next CBOR value into the struct field f in v. +// If the field cannot be resolved, the CBOR value is skipped. +func (d *decoder) decodeToStructField(v reflect.Value, f *decodingField, tInfo *typeInfo) error { + var fv reflect.Value + + if len(f.idx) == 1 { + fv = v.Field(f.idx[0]) + } else { + var err error + fv, err = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { + // Return a new value for embedded field null pointer to point to, or return error. + if !v.CanSet() { + return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) + } + v.Set(reflect.New(v.Type().Elem())) + return v, nil + }) + if !fv.IsValid() { + d.skip() + return err + } + } + + err := d.parseToValue(fv, f.typInfo) + if err != nil { + if typeError, ok := err.(*UnmarshalTypeError); ok { + typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name + } + return err + } + + return nil +} + func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo - structType := getDecodingStructType(tInfo.nonPtrType) - if structType.err != nil { - return structType.err + structType, structTypeErr := getDecodingStructType(tInfo.nonPtrType) + if structTypeErr != nil { + return structTypeErr } if structType.toArray { @@ -2654,14 +2725,12 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n } } - var err, lastErr error - // Get CBOR map size _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec - // Keeps track of matched struct fields + // Keep track of matched struct fields to detect duplicate map keys. var foundFldIdx []bool { const maxStackFields = 128 @@ -2675,99 +2744,80 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n } } - // Keeps track of CBOR map keys to detect duplicate map key - keyCount := 0 - var mapKeys map[any]struct{} - - errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0 + // Keep track of unmatched CBOR map keys to detect duplicate map keys. + var unmatchedMapKeys map[any]struct{} -MapEntryLoop: - for j := 0; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - var f *field + var err error - // If duplicate field detection is enabled and the key at index j did not match any - // field, k will hold the map key. - var k any + caseInsensitive := d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive + for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { t := d.nextCBORType() - if t == cborTypeTextString || (t == cborTypeByteString && d.dm.fieldNameByteString == FieldNameByteStringAllowed) { + + // Reclassify disallowed byte string keys so they fall to the default case. + // keyType is only used for branch control. + keyType := t + if t == cborTypeByteString && d.dm.fieldNameByteString != FieldNameByteStringAllowed { + keyType = 0xff + } + + switch keyType { + case cborTypeTextString, cborTypeByteString: var keyBytes []byte if t == cborTypeTextString { - keyBytes, lastErr = d.parseTextString() - if lastErr != nil { + var parseErr error + keyBytes, parseErr = d.parseTextString() + if parseErr != nil { if err == nil { - err = lastErr + err = parseErr } - d.skip() // skip value + d.skip() // Skip value continue } } else { // cborTypeByteString keyBytes, _ = d.parseByteString() } - // Check for exact match on field name. - if i, ok := structType.fieldIndicesByName[string(keyBytes)]; ok { - fld := structType.fields[i] + // Find matching struct field (exact match, then case-insensitive fallback). + if fldIdx, ok := findStructFieldByKey(structType, keyBytes, caseInsensitive); ok { + fld := structType.fields[fldIdx] - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{fld.name, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() + switch checkDupField(d.dm, foundFldIdx, fldIdx) { + case mapActionParseValueAndContinue: + if fieldErr := d.decodeToStructField(v, fld, tInfo); fieldErr != nil && err == nil { + err = fieldErr } - return err - } else { - // discard repeated match + continue + case mapActionSkipAllAndReturnError: + return d.skipMapForDupKey(string(keyBytes), i, count, hasSize) + case mapActionSkipValueAndContinue: d.skip() - continue MapEntryLoop + continue } } - // Find field with case-insensitive match - if f == nil && d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive { - keyLen := len(keyBytes) - keyString := string(keyBytes) - for i := 0; i < len(structType.fields); i++ { - fld := structType.fields[i] - if len(fld.name) == keyLen && strings.EqualFold(fld.name, keyString) { - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{keyString, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } else { - // discard repeated match - d.skip() - continue MapEntryLoop - } - break - } - } + // No matching struct field found. + if unmatchedErr := handleUnmatchedMapKey(d, string(keyBytes), i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } - if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil { - k = string(keyBytes) - } - } else if t <= cborTypeNegativeInt { // uint/int + case cborTypePositiveInt, cborTypeNegativeInt: var nameAsInt int64 if t == cborTypePositiveInt { _, _, val := d.getHead() - nameAsInt = int64(val) + if val > math.MaxInt64 { + if err == nil { + err = &UnmarshalTypeError{ + CBORType: t.String(), + GoType: reflect.TypeOf(int64(0)).String(), + errorMsg: strconv.FormatUint(val, 10) + " overflows Go's int64", + } + } + d.skip() // skip value + continue + } + nameAsInt = int64(val) //nolint:gosec } else { _, _, val := d.getHead() if val > math.MaxInt64 { @@ -2781,39 +2831,35 @@ MapEntryLoop: d.skip() // skip value continue } - nameAsInt = int64(-1) ^ int64(val) - } - - // Find field - for i := 0; i < len(structType.fields); i++ { - fld := structType.fields[i] - if fld.keyAsInt && fld.nameAsInt == nameAsInt { - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{nameAsInt, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } else { - // discard repeated match - d.skip() - continue MapEntryLoop + nameAsInt = int64(-1) ^ int64(val) //nolint:gosec + } + + // Find field by integer key + if fldIdx, ok := structType.fieldIndicesByIntKey[nameAsInt]; ok { + fld := structType.fields[fldIdx] + + switch checkDupField(d.dm, foundFldIdx, fldIdx) { + case mapActionParseValueAndContinue: + if fieldErr := d.decodeToStructField(v, fld, tInfo); fieldErr != nil && err == nil { + err = fieldErr } - break + continue + case mapActionSkipAllAndReturnError: + return d.skipMapForDupKey(nameAsInt, i, count, hasSize) + case mapActionSkipValueAndContinue: + d.skip() + continue } } - if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil { - k = nameAsInt + // No matching struct field found. + if unmatchedErr := handleUnmatchedMapKey(d, nameAsInt, i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } - } else { + + default: + // CBOR map keys that can't be matched to any struct field. + if err == nil { err = &UnmarshalTypeError{ CBORType: t.String(), @@ -2821,97 +2867,31 @@ MapEntryLoop: errorMsg: "map key is of type " + t.String() + " and cannot be used to match struct field name", } } + + var otherKey any if d.dm.dupMapKey == DupMapKeyEnforcedAPF { // parse key - k, lastErr = d.parse(true) - if lastErr != nil { + var parseErr error + otherKey, parseErr = d.parse(true) + if parseErr != nil { d.skip() // skip value continue } // Detect if CBOR map key can be used as Go map key. - if !isHashableValue(reflect.ValueOf(k)) { + if !isHashableValue(reflect.ValueOf(otherKey)) { d.skip() // skip value continue } } else { d.skip() // skip key } - } - - if f == nil { - if errOnUnknownField { - err = &UnknownFieldError{j} - d.skip() // Skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } - - // Two map keys that match the same struct field are immediately considered - // duplicates. This check detects duplicates between two map keys that do - // not match a struct field. If unknown field errors are enabled, then this - // check is never reached. - if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - if mapKeys == nil { - mapKeys = make(map[any]struct{}, 1) - } - mapKeys[k] = struct{}{} - newKeyCount := len(mapKeys) - if newKeyCount == keyCount { - err = &DupMapKeyError{k, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } - keyCount = newKeyCount - } - - d.skip() // Skip value - continue - } - - // Get field value by index - var fv reflect.Value - if len(f.idx) == 1 { - fv = v.Field(f.idx[0]) - } else { - fv, lastErr = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { - // Return a new value for embedded field null pointer to point to, or return error. - if !v.CanSet() { - return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) - } - v.Set(reflect.New(v.Type().Elem())) - return v, nil - }) - if lastErr != nil && err == nil { - err = lastErr - } - if !fv.IsValid() { - d.skip() - continue - } - } - if lastErr = d.parseToValue(fv, f.typInfo); lastErr != nil { - if err == nil { - if typeError, ok := lastErr.(*UnmarshalTypeError); ok { - typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name - err = typeError - } else { - err = lastErr - } + if unmatchedErr := handleUnmatchedMapKey(d, otherKey, i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } } } + return err } @@ -2958,15 +2938,15 @@ func (d *decoder) skip() { switch t { case cborTypeByteString, cborTypeTextString: - d.off += int(val) + d.off += int(val) //nolint:gosec case cborTypeArray: - for i := 0; i < int(val); i++ { + for i := 0; i < int(val); i++ { //nolint:gosec d.skip() } case cborTypeMap: - for i := 0; i < int(val)*2; i++ { + for i := 0; i < int(val)*2; i++ { //nolint:gosec d.skip() } diff --git a/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go b/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go new file mode 100644 index 00000000..3c8c423a --- /dev/null +++ b/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go @@ -0,0 +1,98 @@ +// Copyright (c) Faye Amacker. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +package cbor + +import "strings" + +// mapAction represents the next action during decoding a CBOR map to a Go struct. +type mapAction int + +const ( + mapActionParseValueAndContinue mapAction = iota // The caller should process the map value. + mapActionSkipValueAndContinue // The caller should skip the map value. + mapActionSkipAllAndReturnError // The caller should skip the rest of the map and return an error. +) + +// checkDupField checks if a struct field at index i has already been matched and returns the next action. +// If not matched, it marks the field as matched and returns mapActionParseValueAndContinue. +// If matched and DupMapKeyEnforcedAPF is specified in the given dm, it returns mapActionSkipAllAndReturnError. +// If matched and DupMapKeyEnforcedAPF is not specified in the given dm, it returns mapActionSkipValueAndContinue. +func checkDupField(dm *decMode, foundFldIdx []bool, i int) mapAction { + if !foundFldIdx[i] { + foundFldIdx[i] = true + return mapActionParseValueAndContinue + } + if dm.dupMapKey == DupMapKeyEnforcedAPF { + return mapActionSkipAllAndReturnError + } + return mapActionSkipValueAndContinue +} + +// findStructFieldByKey finds a struct field matching keyBytes by name. +// It tries an exact match first. If no exact match is found and +// caseInsensitive is true, it falls back to a case-insensitive search. +// findStructFieldByKey returns the field index and true, or -1 and false. +func findStructFieldByKey( + structType *decodingStructType, + keyBytes []byte, + caseInsensitive bool, +) (int, bool) { + if fldIdx, ok := structType.fieldIndicesByName[string(keyBytes)]; ok { + return fldIdx, true + } + if caseInsensitive { + return findFieldCaseInsensitive(structType.fields, string(keyBytes)) + } + return -1, false +} + +// findFieldCaseInsensitive returns the index of the first field whose name +// case-insensitively matches key, or -1 and false if no field matches. +func findFieldCaseInsensitive(flds decodingFields, key string) (int, bool) { + keyLen := len(key) + for i, f := range flds { + if f.keyAsInt { + continue + } + if len(f.name) == keyLen && strings.EqualFold(f.name, key) { + return i, true + } + } + return -1, false +} + +// handleUnmatchedMapKey handles a map entry whose key does not match any struct +// field. It can return UnknownFieldError or DupMapKeyError. +// handleUnmatchedMapKey consumes the CBOR value, so the caller doesn't need to skip any values. +// If an error is returned, the caller should abort parsing the map and return the error. +// If no error is returned, the caller should continue to process the next map pair. +func handleUnmatchedMapKey( + d *decoder, + key any, + i int, + count int, + hasSize bool, + // *map[any]struct{} is used here because we use lazy initialization for uks + uks *map[any]struct{}, //nolint:gocritic +) error { + errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0 + + if errOnUnknownField { + return d.skipMapForUnknownField(i, count, hasSize) + } + + if d.dm.dupMapKey == DupMapKeyEnforcedAPF { + if *uks == nil { + *uks = make(map[any]struct{}) + } + if _, dup := (*uks)[key]; dup { + return d.skipMapForDupKey(key, i, count, hasSize) + } + (*uks)[key] = struct{}{} + } + + // Skip value. + d.skip() + return nil +} diff --git a/vendor/github.com/fxamacker/cbor/v2/diagnose.go b/vendor/github.com/fxamacker/cbor/v2/diagnose.go index 44afb866..42a67ad1 100644 --- a/vendor/github.com/fxamacker/cbor/v2/diagnose.go +++ b/vendor/github.com/fxamacker/cbor/v2/diagnose.go @@ -51,11 +51,8 @@ const ( maxByteStringEncoding ) -func (bse ByteStringEncoding) valid() error { - if bse >= maxByteStringEncoding { - return errors.New("cbor: invalid ByteStringEncoding " + strconv.Itoa(int(bse))) - } - return nil +func (bse ByteStringEncoding) valid() bool { + return bse < maxByteStringEncoding } // DiagOptions specifies Diag options. @@ -104,8 +101,8 @@ func (opts DiagOptions) DiagMode() (DiagMode, error) { } func (opts DiagOptions) diagMode() (*diagMode, error) { - if err := opts.ByteStringEncoding.valid(); err != nil { - return nil, err + if !opts.ByteStringEncoding.valid() { + return nil, errors.New("cbor: invalid ByteStringEncoding " + strconv.Itoa(int(opts.ByteStringEncoding))) } decMode, err := DecOptions{ @@ -360,7 +357,7 @@ func (di *diagnose) item() error { //nolint:gocyclo case cborTypeArray: _, _, val := di.d.getHead() - count := int(val) + count := int(val) //nolint:gosec di.w.WriteByte('[') for i := 0; i < count; i++ { @@ -376,7 +373,7 @@ func (di *diagnose) item() error { //nolint:gocyclo case cborTypeMap: _, _, val := di.d.getHead() - count := int(val) + count := int(val) //nolint:gosec di.w.WriteByte('{') for i := 0; i < count; i++ { @@ -477,8 +474,8 @@ func (di *diagnose) item() error { //nolint:gocyclo func (di *diagnose) writeU16(val rune) { di.w.WriteString("\\u") var in [2]byte - in[0] = byte(val >> 8) - in[1] = byte(val) + in[0] = byte(val >> 8) //nolint:gosec + in[1] = byte(val) //nolint:gosec sz := hex.EncodedLen(len(in)) di.w.Grow(sz) dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz] @@ -608,7 +605,7 @@ func (di *diagnose) encodeTextString(val string, quote byte) error { c, size := utf8.DecodeRuneInString(val[i:]) switch { - case c == utf8.RuneError: + case c == utf8.RuneError && size == 1: return &SemanticError{"cbor: invalid UTF-8 string"} case c < utf16SurrSelf: @@ -631,7 +628,7 @@ func (di *diagnose) encodeFloat(ai byte, val uint64) error { f64 := float64(0) switch ai { case additionalInformationAsFloat16: - f16 := float16.Frombits(uint16(val)) + f16 := float16.Frombits(uint16(val)) //nolint:gosec switch { case f16.IsNaN(): di.w.WriteString("NaN") @@ -647,7 +644,7 @@ func (di *diagnose) encodeFloat(ai byte, val uint64) error { } case additionalInformationAsFloat32: - f32 := math.Float32frombits(uint32(val)) + f32 := math.Float32frombits(uint32(val)) //nolint:gosec switch { case f32 != f32: di.w.WriteString("NaN") diff --git a/vendor/github.com/fxamacker/cbor/v2/encode.go b/vendor/github.com/fxamacker/cbor/v2/encode.go index c550617c..e65a29d8 100644 --- a/vendor/github.com/fxamacker/cbor/v2/encode.go +++ b/vendor/github.com/fxamacker/cbor/v2/encode.go @@ -30,7 +30,7 @@ import ( // If value implements the Marshaler interface, Marshal calls its // MarshalCBOR method. // -// If value implements encoding.BinaryMarshaler, Marhsal calls its +// If value implements encoding.BinaryMarshaler, Marshal calls its // MarshalBinary method and encode it as CBOR byte string. // // Boolean values encode as CBOR booleans (type 7). @@ -343,7 +343,7 @@ const ( // non-UTC timezone then a "localtime - UTC" numeric offset will be included as specified in RFC3339. // NOTE: User applications can avoid including the RFC3339 numeric offset by: // - providing a time.Time value set to UTC, or - // - using the TimeUnix, TimeUnixMicro, or TimeUnixDynamic option instead of TimeRFC3339. + // - using the TimeUnix, TimeUnixMicro, TimeUnixDynamic, or TimeRFC3339NanoUTC option. TimeRFC3339 // TimeRFC3339Nano causes time.Time to encode to a CBOR time (tag 0) with a text string content @@ -351,9 +351,13 @@ const ( // non-UTC timezone then a "localtime - UTC" numeric offset will be included as specified in RFC3339. // NOTE: User applications can avoid including the RFC3339 numeric offset by: // - providing a time.Time value set to UTC, or - // - using the TimeUnix, TimeUnixMicro, or TimeUnixDynamic option instead of TimeRFC3339Nano. + // - using the TimeUnix, TimeUnixMicro, TimeUnixDynamic, or TimeRFC3339NanoUTC option. TimeRFC3339Nano + // TimeRFC3339NanoUTC causes time.Time to encode to a CBOR time (tag 0) with a text string content + // representing UTC time using nanosecond precision in RFC3339 format. + TimeRFC3339NanoUTC + maxTimeMode ) @@ -436,7 +440,7 @@ const ( // FieldNameToTextString encodes struct fields to CBOR text string (major type 3). FieldNameToTextString FieldNameMode = iota - // FieldNameToTextString encodes struct fields to CBOR byte string (major type 2). + // FieldNameToByteString encodes struct fields to CBOR byte string (major type 2). FieldNameToByteString maxFieldNameMode @@ -567,7 +571,7 @@ type EncOptions struct { // RFC3339 format gets tag number 0, and numeric epoch time tag number 1. TimeTag EncTagMode - // IndefLength specifies whether to allow indefinite length CBOR items. + // IndefLength specifies whether to allow indefinite-length CBOR items. IndefLength IndefLengthMode // NilContainers specifies how to encode nil slices and maps. @@ -1132,10 +1136,11 @@ func encodeFloat(e *bytes.Buffer, em *encMode, v reflect.Value) error { if fopt == ShortestFloat16 { var f16 float16.Float16 p := float16.PrecisionFromfloat32(f32) - if p == float16.PrecisionExact { + switch p { + case float16.PrecisionExact: // Roundtrip float32->float16->float32 test isn't needed. f16 = float16.Fromfloat32(f32) - } else if p == float16.PrecisionUnknown { + case float16.PrecisionUnknown: // Try roundtrip float32->float16->float32 to determine if float32 can fit into float16. f16 = float16.Fromfloat32(f32) if f16.Float32() == f32 { @@ -1293,10 +1298,10 @@ func encodeByteString(e *bytes.Buffer, em *encMode, v reflect.Value) error { if slen == 0 { return e.WriteByte(byte(cborTypeByteString)) } - encodeHead(e, byte(cborTypeByteString), uint64(slen)) + encodeHead(e, byte(cborTypeByteString), uint64(slen)) //nolint:gosec if vk == reflect.Array { for i := 0; i < slen; i++ { - e.WriteByte(byte(v.Index(i).Uint())) + e.WriteByte(byte(v.Index(i).Uint())) //nolint:gosec } return nil } @@ -1333,7 +1338,7 @@ func (ae arrayEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) if alen == 0 { return e.WriteByte(byte(cborTypeArray)) } - encodeHead(e, byte(cborTypeArray), uint64(alen)) + encodeHead(e, byte(cborTypeArray), uint64(alen)) //nolint:gosec for i := 0; i < alen; i++ { if err := ae.f(e, em, v.Index(i)); err != nil { return err @@ -1364,7 +1369,7 @@ func (me mapEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) er return e.WriteByte(byte(cborTypeMap)) } - encodeHead(e, byte(cborTypeMap), uint64(mlen)) + encodeHead(e, byte(cborTypeMap), uint64(mlen)) //nolint:gosec if em.sort == SortNone || em.sort == SortFastShuffle || mlen <= 1 { return me.e(e, em, v, nil) } @@ -1427,7 +1432,7 @@ func (x *bytewiseKeyValueSorter) Swap(i, j int) { func (x *bytewiseKeyValueSorter) Less(i, j int) bool { kvi, kvj := x.kvs[i], x.kvs[j] - return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0 + return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) < 0 } type lengthFirstKeyValueSorter struct { @@ -1448,7 +1453,7 @@ func (x *lengthFirstKeyValueSorter) Less(i, j int) bool { if keyLengthDifference := (kvi.valueOffset - kvi.offset) - (kvj.valueOffset - kvj.offset); keyLengthDifference != 0 { return keyLengthDifference < 0 } - return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0 + return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) < 0 } var keyValuePool = sync.Pool{} @@ -1535,8 +1540,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // Head is rewritten later if actual encoded field count is different from struct field count. encodedHeadLen := encodeHead(e, byte(cborTypeMap), uint64(len(flds))) - kvbegin := e.Len() - kvcount := 0 + kvBeginOffset := e.Len() + kvCount := 0 for offset := 0; offset < len(flds); offset++ { f := flds[(start+offset)%len(flds)] @@ -1582,10 +1587,10 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { return err } - kvcount++ + kvCount++ } - if len(flds) == kvcount { + if len(flds) == kvCount { // Encoded element count in head is the same as actual element count. return nil } @@ -1593,8 +1598,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // Overwrite the bytes that were reserved for the head before encoding the map entries. var actualHeadLen int { - headbuf := *bytes.NewBuffer(e.Bytes()[kvbegin-encodedHeadLen : kvbegin-encodedHeadLen : kvbegin]) - actualHeadLen = encodeHead(&headbuf, byte(cborTypeMap), uint64(kvcount)) + headbuf := *bytes.NewBuffer(e.Bytes()[kvBeginOffset-encodedHeadLen : kvBeginOffset-encodedHeadLen : kvBeginOffset]) + actualHeadLen = encodeHead(&headbuf, byte(cborTypeMap), uint64(kvCount)) } if actualHeadLen == encodedHeadLen { @@ -1607,8 +1612,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // encoded. The encoded entries are offset to the right by the number of excess reserved // bytes. Shift the entries left to remove the gap. excessReservedBytes := encodedHeadLen - actualHeadLen - dst := e.Bytes()[kvbegin-excessReservedBytes : e.Len()-excessReservedBytes] - src := e.Bytes()[kvbegin:e.Len()] + dst := e.Bytes()[kvBeginOffset-excessReservedBytes : e.Len()-excessReservedBytes] + src := e.Bytes()[kvBeginOffset:e.Len()] copy(dst, src) // After shifting, the excess bytes are at the end of the output buffer and they are @@ -1633,7 +1638,7 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { } if em.timeTag == EncTagRequired { tagNumber := 1 - if em.time == TimeRFC3339 || em.time == TimeRFC3339Nano { + if em.time == TimeRFC3339 || em.time == TimeRFC3339Nano || em.time == TimeRFC3339NanoUTC { tagNumber = 0 } encodeHead(e, byte(cborTypeTag), uint64(tagNumber)) @@ -1650,7 +1655,7 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { case TimeUnixDynamic: t = t.UTC().Round(time.Microsecond) - secs, nsecs := t.Unix(), uint64(t.Nanosecond()) + secs, nsecs := t.Unix(), uint64(t.Nanosecond()) //nolint:gosec if nsecs == 0 { return encodeInt(e, em, reflect.ValueOf(secs)) } @@ -1661,6 +1666,10 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { s := t.Format(time.RFC3339) return encodeString(e, em, reflect.ValueOf(s)) + case TimeRFC3339NanoUTC: + s := t.UTC().Format(time.RFC3339Nano) + return encodeString(e, em, reflect.ValueOf(s)) + default: // TimeRFC3339Nano s := t.Format(time.RFC3339Nano) return encodeString(e, em, reflect.ValueOf(s)) diff --git a/vendor/github.com/fxamacker/cbor/v2/simplevalue.go b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go index 30f72814..9912e855 100644 --- a/vendor/github.com/fxamacker/cbor/v2/simplevalue.go +++ b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go @@ -93,6 +93,6 @@ func (sv *SimpleValue) unmarshalCBOR(data []byte) error { // It is safe to cast val to uint8 here because // - data is already verified to be well-formed CBOR simple value and // - val is <= math.MaxUint8. - *sv = SimpleValue(val) + *sv = SimpleValue(val) //nolint:gosec return nil } diff --git a/vendor/github.com/fxamacker/cbor/v2/stream.go b/vendor/github.com/fxamacker/cbor/v2/stream.go index 7ac6d7d6..da4c8f21 100644 --- a/vendor/github.com/fxamacker/cbor/v2/stream.go +++ b/vendor/github.com/fxamacker/cbor/v2/stream.go @@ -171,14 +171,20 @@ func NewEncoder(w io.Writer) *Encoder { // Encode writes the CBOR encoding of v. func (enc *Encoder) Encode(v any) error { - if len(enc.indefTypes) > 0 && v != nil { - indefType := enc.indefTypes[len(enc.indefTypes)-1] - if indefType == cborTypeTextString { + if len(enc.indefTypes) > 0 { + switch enc.indefTypes[len(enc.indefTypes)-1] { + case cborTypeTextString: + if v == nil { + return errors.New("cbor: cannot encode nil for indefinite-length text string") + } k := reflect.TypeOf(v).Kind() if k != reflect.String { return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length text string") } - } else if indefType == cborTypeByteString { + case cborTypeByteString: + if v == nil { + return errors.New("cbor: cannot encode nil for indefinite-length byte string") + } t := reflect.TypeOf(v) k := t.Kind() if (k != reflect.Array && k != reflect.Slice) || t.Elem().Kind() != reflect.Uint8 { @@ -198,35 +204,35 @@ func (enc *Encoder) Encode(v any) error { return err } -// StartIndefiniteByteString starts byte string encoding of indefinite length. +// StartIndefiniteByteString starts indefinite-length byte string encoding. // Subsequent calls of (*Encoder).Encode() encodes definite length byte strings // ("chunks") as one contiguous string until EndIndefinite is called. func (enc *Encoder) StartIndefiniteByteString() error { return enc.startIndefinite(cborTypeByteString) } -// StartIndefiniteTextString starts text string encoding of indefinite length. +// StartIndefiniteTextString starts indefinite-length text string encoding. // Subsequent calls of (*Encoder).Encode() encodes definite length text strings // ("chunks") as one contiguous string until EndIndefinite is called. func (enc *Encoder) StartIndefiniteTextString() error { return enc.startIndefinite(cborTypeTextString) } -// StartIndefiniteArray starts array encoding of indefinite length. +// StartIndefiniteArray starts indefinite-length array encoding. // Subsequent calls of (*Encoder).Encode() encodes elements of the array // until EndIndefinite is called. func (enc *Encoder) StartIndefiniteArray() error { return enc.startIndefinite(cborTypeArray) } -// StartIndefiniteMap starts array encoding of indefinite length. +// StartIndefiniteMap starts indefinite-length map encoding. // Subsequent calls of (*Encoder).Encode() encodes elements of the map // until EndIndefinite is called. func (enc *Encoder) StartIndefiniteMap() error { return enc.startIndefinite(cborTypeMap) } -// EndIndefinite closes last opened indefinite length value. +// EndIndefinite closes last opened indefinite-length value. func (enc *Encoder) EndIndefinite() error { if len(enc.indefTypes) == 0 { return errors.New("cbor: cannot encode \"break\" code outside indefinite length values") @@ -238,18 +244,22 @@ func (enc *Encoder) EndIndefinite() error { return err } -var cborIndefHeader = map[cborType][]byte{ - cborTypeByteString: {cborByteStringWithIndefiniteLengthHead}, - cborTypeTextString: {cborTextStringWithIndefiniteLengthHead}, - cborTypeArray: {cborArrayWithIndefiniteLengthHead}, - cborTypeMap: {cborMapWithIndefiniteLengthHead}, -} - func (enc *Encoder) startIndefinite(typ cborType) error { if enc.em.indefLength == IndefLengthForbidden { return &IndefiniteLengthError{typ} } - _, err := enc.w.Write(cborIndefHeader[typ]) + var head byte + switch typ { + case cborTypeByteString: + head = cborByteStringWithIndefiniteLengthHead + case cborTypeTextString: + head = cborTextStringWithIndefiniteLengthHead + case cborTypeArray: + head = cborArrayWithIndefiniteLengthHead + case cborTypeMap: + head = cborMapWithIndefiniteLengthHead + } + _, err := enc.w.Write([]byte{head}) if err == nil { enc.indefTypes = append(enc.indefTypes, typ) } @@ -262,7 +272,9 @@ type RawMessage []byte // MarshalCBOR returns m or CBOR nil if m is nil. func (m RawMessage) MarshalCBOR() ([]byte, error) { if len(m) == 0 { - return cborNil, nil + b := make([]byte, len(cborNil)) + copy(b, cborNil) + return b, nil } return m, nil } diff --git a/vendor/github.com/fxamacker/cbor/v2/structfields.go b/vendor/github.com/fxamacker/cbor/v2/structfields.go index cf0a922c..b2d71f2e 100644 --- a/vendor/github.com/fxamacker/cbor/v2/structfields.go +++ b/vendor/github.com/fxamacker/cbor/v2/structfields.go @@ -6,27 +6,43 @@ package cbor import ( "reflect" "sort" + "strconv" "strings" ) +// field holds shared struct field metadata returned by getFields(). type field struct { - name string - nameAsInt int64 // used to decoder to match field name with CBOR int + name string + nameAsInt int64 // used to match field name with CBOR int + idx []int + typ reflect.Type // used during cache building only + keyAsInt bool // used to encode/decode field name as int + tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields) + omitEmpty bool // used to skip empty field + omitZero bool // used to skip zero field +} + +type fields []*field + +// encodingField extends field with encoding-specific data. +type encodingField struct { + field cborName []byte - cborNameByteString []byte // major type 2 name encoding iff cborName has major type 3 - idx []int - typ reflect.Type + cborNameByteString []byte // major type 2 name encoding if cborName has major type 3 ef encodeFunc ief isEmptyFunc izf isZeroFunc - typInfo *typeInfo // used to decoder to reuse type info - tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields) - omitEmpty bool // used to skip empty field - omitZero bool // used to skip zero field - keyAsInt bool // used to encode/decode field name as int } -type fields []*field +type encodingFields []*encodingField + +// decodingField extends field with decoding-specific data. +type decodingField struct { + field + typInfo *typeInfo // used by decoder to reuse type info +} + +type decodingFields []*decodingField // indexFieldSorter sorts fields by field idx at each level, breaking ties with idx depth. type indexFieldSorter struct { @@ -48,7 +64,7 @@ func (x *indexFieldSorter) Less(i, j int) bool { return iIdx[k] < jIdx[k] } } - return len(iIdx) <= len(jIdx) + return len(iIdx) < len(jIdx) } // nameLevelAndTagFieldSorter sorts fields by field name, idx depth, and presence of tag. @@ -69,6 +85,10 @@ func (x *nameLevelAndTagFieldSorter) Less(i, j int) bool { if fi.name != fj.name { return fi.name < fj.name } + // Fields with the same name but different keyAsInt are in separate namespaces. + if fi.keyAsInt != fj.keyAsInt { + return fi.keyAsInt + } if len(fi.idx) != len(fj.idx) { return len(fi.idx) < len(fj.idx) } @@ -117,22 +137,37 @@ func getFields(t reflect.Type) (flds fields, structOptions string) { } } + // Normalize keyasint field names to their canonical integer string form. + // This ensures that "01", "+1", and "1" are treated as the same key + // during deduplication. + for _, f := range flds { + if f.keyAsInt { + nameAsInt, err := strconv.Atoi(f.name) + if err != nil { + continue // Leave invalid names for callers to report. + } + f.nameAsInt = int64(nameAsInt) + f.name = strconv.Itoa(nameAsInt) + } + } + sort.Sort(&nameLevelAndTagFieldSorter{flds}) // Keep visible fields. j := 0 // index of next unique field for i := 0; i < len(flds); { name := flds[i].name + keyAsInt := flds[i].keyAsInt if i == len(flds)-1 || // last field - name != flds[i+1].name || // field i has unique field name + name != flds[i+1].name || flds[i+1].keyAsInt != keyAsInt || // field i has unique (name, keyAsInt) len(flds[i].idx) < len(flds[i+1].idx) || // field i is at a less nested level than field i+1 (flds[i].tagged && !flds[i+1].tagged) { // field i is tagged while field i+1 is not flds[j] = flds[i] j++ } - // Skip fields with the same field name. - for i++; i < len(flds) && name == flds[i].name; i++ { //nolint:revive + // Skip fields with the same (name, keyAsInt). + for i++; i < len(flds) && name == flds[i].name && keyAsInt == flds[i].keyAsInt; i++ { //nolint:revive } } if j != len(flds) { diff --git a/vendor/github.com/fxamacker/cbor/v2/valid.go b/vendor/github.com/fxamacker/cbor/v2/valid.go index b40793b9..850b9501 100644 --- a/vendor/github.com/fxamacker/cbor/v2/valid.go +++ b/vendor/github.com/fxamacker/cbor/v2/valid.go @@ -54,7 +54,7 @@ func (e *MaxMapPairsError) Error() string { return "cbor: exceeded max number of key-value pairs " + strconv.Itoa(e.maxMapPairs) + " for CBOR map" } -// IndefiniteLengthError indicates found disallowed indefinite length items. +// IndefiniteLengthError indicates found disallowed indefinite-length items. type IndefiniteLengthError struct { t cborType } @@ -113,7 +113,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err } return d.wellformedIndefiniteString(t, depth, checkBuiltinTags) } - valInt := int(val) + valInt := int(val) //nolint:gosec if valInt < 0 { // Detect integer overflow return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, causing integer overflow") @@ -136,7 +136,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err return d.wellformedIndefiniteArrayOrMap(t, depth, checkBuiltinTags) } - valInt := int(val) + valInt := int(val) //nolint:gosec if valInt < 0 { // Detect integer overflow return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, it would cause integer overflow") @@ -212,7 +212,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err return depth, nil } -// wellformedIndefiniteString checks indefinite length byte/text string's well-formedness and returns max depth and error. +// wellformedIndefiniteString checks indefinite-length byte/text string's well-formedness and returns max depth and error. func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltinTags bool) (int, error) { var err error for { @@ -223,7 +223,7 @@ func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltin d.off++ break } - // Peek ahead to get next type and indefinite length status. + // Peek ahead to get next type and indefinite-length status. nt, ai := parseInitialByte(d.data[d.off]) if t != nt { return 0, &SyntaxError{"cbor: wrong element type " + nt.String() + " for indefinite-length " + t.String()} @@ -238,7 +238,7 @@ func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltin return depth, nil } -// wellformedIndefiniteArrayOrMap checks indefinite length array/map's well-formedness and returns max depth and error. +// wellformedIndefiniteArrayOrMap checks indefinite-length array/map's well-formedness and returns max depth and error. func (d *decoder) wellformedIndefiniteArrayOrMap(t cborType, depth int, checkBuiltinTags bool) (int, error) { var err error maxDepth := depth @@ -326,7 +326,7 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) val = uint64(binary.BigEndian.Uint16(d.data[d.off : d.off+argumentSize])) d.off += argumentSize if t == cborTypePrimitives { - if err := d.acceptableFloat(float64(float16.Frombits(uint16(val)).Float32())); err != nil { + if err := d.acceptableFloat(float64(float16.Frombits(uint16(val)).Float32())); err != nil { //nolint:gosec return 0, 0, 0, err } } @@ -341,7 +341,7 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) val = uint64(binary.BigEndian.Uint32(d.data[d.off : d.off+argumentSize])) d.off += argumentSize if t == cborTypePrimitives { - if err := d.acceptableFloat(float64(math.Float32frombits(uint32(val)))); err != nil { + if err := d.acceptableFloat(float64(math.Float32frombits(uint32(val)))); err != nil { //nolint:gosec return 0, 0, 0, err } } @@ -379,12 +379,12 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) func (d *decoder) acceptableFloat(f float64) error { switch { - case d.dm.nanDec == NaNDecodeForbidden && math.IsNaN(f): + case d.dm.nan == NaNDecodeForbidden && math.IsNaN(f): return &UnacceptableDataItemError{ CBORType: cborTypePrimitives.String(), Message: "floating-point NaN", } - case d.dm.infDec == InfDecodeForbidden && math.IsInf(f, 0): + case d.dm.inf == InfDecodeForbidden && math.IsInf(f, 0): return &UnacceptableDataItemError{ CBORType: cborTypePrimitives.String(), Message: "floating-point infinity", diff --git a/vendor/github.com/go-openapi/jsonpointer/.gitignore b/vendor/github.com/go-openapi/jsonpointer/.gitignore index 769c2440..d8f4186f 100644 --- a/vendor/github.com/go-openapi/jsonpointer/.gitignore +++ b/vendor/github.com/go-openapi/jsonpointer/.gitignore @@ -1 +1,5 @@ -secrets.yml +*.out +*.cov +.idea +.env +.mcp.json diff --git a/vendor/github.com/go-openapi/jsonpointer/.golangci.yml b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml index d2fafb8a..9d273317 100644 --- a/vendor/github.com/go-openapi/jsonpointer/.golangci.yml +++ b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml @@ -1,56 +1,70 @@ -linters-settings: - gocyclo: - min-complexity: 45 - dupl: - threshold: 200 - goconst: - min-len: 2 - min-occurrences: 3 - +version: "2" linters: - enable-all: true + default: all disable: - - recvcheck - - unparam - - lll - - gochecknoinits - - gochecknoglobals + - depguard - funlen + - goconst - godox - - gocognit - - whitespace - - wsl - - wrapcheck - - testpackage + - gomodguard + - gomodguard_v2 + - exhaustruct - nlreturn - - errorlint - - nestif - - godot - - gofumpt + - nonamedreturns + - noinlineerr - paralleltest - - tparallel + - recvcheck + - testpackage - thelper - - exhaustruct + - tparallel - varnamelen - - gci - - depguard - - errchkjson - - inamedparam - - nonamedreturns - - musttag - - ireturn - - forcetypeassert - - cyclop - # deprecated linters - #- deadcode - #- interfacer - #- scopelint - #- varcheck - #- structcheck - #- golint - #- nosnakecase - #- maligned - #- goerr113 - #- ifshort - #- gomnd - #- exhaustivestruct + - whitespace + - wrapcheck + - wsl + - wsl_v5 + settings: + dupl: + threshold: 200 + goconst: + min-len: 2 + min-occurrences: 3 + cyclop: + max-complexity: 20 + gocyclo: + min-complexity: 20 + exhaustive: + default-signifies-exhaustive: true + default-case-required: true + lll: + line-length: 180 + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + - goimports + - gofumpt + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ +issues: + # Maximum issues count per one linter. + # Set to 0 to disable. + # Default: 50 + max-issues-per-linter: 0 + # Maximum count of issues with the same text. + # Set to 0 to disable. + # Default: 3 + max-same-issues: 0 diff --git a/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md b/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md index 9322b065..bac878f2 100644 --- a/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md +++ b/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md @@ -23,7 +23,9 @@ include: Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or + advances + * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic @@ -55,7 +57,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at ivan+abuse@flanders.co.nz. All +reported by contacting the project team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. @@ -68,7 +70,7 @@ members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] +available at [][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md b/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md new file mode 100644 index 00000000..de0bf5c0 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md @@ -0,0 +1,25 @@ +# Contributors + +- Repository: ['go-openapi/jsonpointer'] + +| Total Contributors | Total Contributions | +| --- | --- | +| 13 | 132 | + +| Username | All Time Contribution Count | All Commits | +| --- | --- | --- | +| @fredbi | 83 | | +| @casualjim | 33 | | +| @magodo | 3 | | +| @youyuanwu | 3 | | +| @alexandear | 2 | | +| @gaiaz-iusipov | 1 | | +| @gbjk | 1 | | +| @gordallott | 1 | | +| @ianlancetaylor | 1 | | +| @mfleader | 1 | | +| @Neo2308 | 1 | | +| @olivierlemasle | 1 | | +| @testwill | 1 | | + + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/jsonpointer/LICENSE b/vendor/github.com/go-openapi/jsonpointer/LICENSE index d6456956..261eeb9e 100644 --- a/vendor/github.com/go-openapi/jsonpointer/LICENSE +++ b/vendor/github.com/go-openapi/jsonpointer/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/vendor/github.com/go-openapi/jsonpointer/NOTICE b/vendor/github.com/go-openapi/jsonpointer/NOTICE new file mode 100644 index 00000000..201908d2 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/NOTICE @@ -0,0 +1,39 @@ +Copyright 2015-2025 go-swagger maintainers + +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +This software library, github.com/go-openapi/jsonpointer, includes software developed +by the go-swagger and go-openapi maintainers ("go-swagger maintainers"). + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this software except in compliance with the License. + +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0. + +This software is copied from, derived from, and inspired by other original software products. +It ships with copies of other software which license terms are recalled below. + +The original software was authored on 25-02-2013 by sigu-399 (https://github.com/sigu-399, sigu.399@gmail.com). + +github.com/sigu-399/jsonpointer +=========================== + +// SPDX-FileCopyrightText: Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) +// SPDX-License-Identifier: Apache-2.0 + +Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) + +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-openapi/jsonpointer/README.md b/vendor/github.com/go-openapi/jsonpointer/README.md index 0108f1d5..6e7929c6 100644 --- a/vendor/github.com/go-openapi/jsonpointer/README.md +++ b/vendor/github.com/go-openapi/jsonpointer/README.md @@ -1,19 +1,177 @@ -# gojsonpointer [![Build Status](https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonpointer/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer) +# jsonpointer -[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE) -[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer.svg)](https://pkg.go.dev/github.com/go-openapi/jsonpointer) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonpointer)](https://goreportcard.com/report/github.com/go-openapi/jsonpointer) + +[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vuln scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url] + + + +[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] + + +[![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] -An implementation of JSON Pointer - Go language +--- + +An implementation of JSON Pointer for golang, which supports go `struct`. + +## Announcements + +* **2026-07-07** : landing v1.0.0 + * stable API pledge + +* **2026-06-29** : reinsourced external dependency to swag (v0.24.0) + * module `github.com/go-openapi/swag/jsonname` is source directly here, so we no longer have any external dependency + * `jsonname` was never really used by any other package, so it makes sense to deprecate it away from the `swag` family + and retrofit its functionality here. `jsonpointer` no longer get external dependencies, besides test dependencies. + +* **2026-04-15** : added support for trailing "-" for arrays (v0.23.0) + * this brings full support of [RFC6901][RFC6901] + * this is supported for types relying on the reflection-based implemented + * API semantics remain essentially unaltered. Exception: `Pointer.Set(document any,value any) (document any, err error)` + can only perform a best-effort to mutate the input document in place. In the case of adding elements to an array with a + trailing "-", either pass a mutable array (`*[]T`) as the input document, or use the returned updated document instead. + * types that implement the `JSONSetable` interface may not implement the mutation implied by the trailing "-" + +* **2026-04-15** : added support for optional alternate JSON name providers + * for struct support the defaults might not suit all situations: there are known limitations + when it comes to handle untagged fields or embedded types. + * the default name provider in use is not fully aligned with go JSON stdlib + * exposed an option (or global setting) to change the provider that resolves a struct into json keys + * the default behavior is not altered ## Status -Completed YES -Tested YES +API is stable and feature-complete. + +The project continues to receive regular updates, bug fixes and hygiene maintenance (CI, linting, etc). + +## Import this library in your project + +```cmd +go get github.com/go-openapi/jsonpointer +``` + +## Basic usage + +See also some [examples](./examples_test.go) + +### Retrieving a value + +```go + import ( + "github.com/go-openapi/jsonpointer" + ) + + + var doc any + + ... + + pointer, err := jsonpointer.New("/foo/1") + if err != nil { + ... // error: e.g. invalid JSON pointer specification + } + + value, kind, err := pointer.Get(doc) + if err != nil { + ... // error: e.g. key not found, index out of bounds, etc. + } + + ... +``` + +### Setting a value + +```go + ... + var doc any + ... + pointer, err := jsonpointer.New("/foo/1") + if err != nil { + ... // error: e.g. invalid JSON pointer specification + } + + doc, err = p.Set(doc, "value") + if err != nil { + ... // error: e.g. key not found, index out of bounds, etc. + } +``` + +## Change log + +See ## References -http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 -### Note -The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented. + + +also known as [RFC6901][RFC6901]. + +## Licensing + +This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE). + +See the license [NOTICE](./NOTICE), which recalls the licensing terms of all the pieces of software +on top of which it has been built. + +## Limitations + +* [RFC6901][RFC6901] is now fully supported, including trailing "-" semantics for arrays (for `Set` operations). +* Default behavior: JSON name detection in go `struct`s + - Unlike go standard marshaling, untagged fields do not default to the go field name and are ignored. + - anonymous fields are not traversed if untagged + - the above limitations may be overcome by calling `UseGoNameProvider()` at initialization time. + - alternatively, users may inject the desired custom behavior for naming fields as an option. + +## Other documentation + +* [All-time contributors](./CONTRIBUTORS.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] + +## Cutting a new release + +Maintainers can cut a new release by either: + +* running [this workflow](https://github.com/go-openapi/jsonpointer/actions/workflows/bump-release.yml) +* or pushing a semver tag + * signed tags are preferred + * The tag message is prepended to release notes + + +[test-badge]: https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml/badge.svg +[test-url]: https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml +[cov-badge]: https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg +[cov-url]: https://codecov.io/gh/go-openapi/jsonpointer +[vuln-scan-badge]: https://github.com/go-openapi/jsonpointer/actions/workflows/scanner.yml/badge.svg +[vuln-scan-url]: https://github.com/go-openapi/jsonpointer/actions/workflows/scanner.yml +[codeql-badge]: https://github.com/go-openapi/jsonpointer/actions/workflows/codeql.yml/badge.svg +[codeql-url]: https://github.com/go-openapi/jsonpointer/actions/workflows/codeql.yml + +[release-badge]: https://badge.fury.io/gh/go-openapi%2Fjsonpointer.svg +[release-url]: https://badge.fury.io/gh/go-openapi%2Fjsonpointer + +[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/jsonpointer +[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/jsonpointer +[codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/jsonpointer +[codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/jsonpointer + +[godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer +[godoc-url]: http://pkg.go.dev/github.com/go-openapi/jsonpointer +[discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue +[discord-url]: https://discord.gg/FfnFYaC3k5 + + +[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg +[license-url]: https://github.com/go-openapi/jsonpointer/?tab=Apache-2.0-1-ov-file#readme + +[goversion-badge]: https://img.shields.io/github/go-mod/go-version/go-openapi/jsonpointer +[goversion-url]: https://github.com/go-openapi/jsonpointer/blob/master/go.mod +[top-badge]: https://img.shields.io/github/languages/top/go-openapi/jsonpointer +[commits-badge]: https://img.shields.io/github/commits-since/go-openapi/jsonpointer/latest +[RFC6901]: https://www.rfc-editor.org/rfc/rfc6901 + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/jsonpointer/SECURITY.md b/vendor/github.com/go-openapi/jsonpointer/SECURITY.md new file mode 100644 index 00000000..1fea2c57 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/SECURITY.md @@ -0,0 +1,37 @@ +# Security Policy + +This policy outlines the commitment and practices of the go-openapi maintainers regarding security. + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| O.x | :white_check_mark: | + +## Vulnerability checks in place + +This repository uses automated vulnerability scans, at every merged commit and at least once a week. + +We use: + +* [`GitHub CodeQL`][codeql-url] +* [`trivy`][trivy-url] +* [`govulncheck`][govulncheck-url] + +Reports are centralized in github security reports and visible only to the maintainers. + +## Reporting a vulnerability + +If you become aware of a security vulnerability that affects the current repository, +**please report it privately to the maintainers** +rather than opening a publicly visible GitHub issue. + +Please follow the instructions provided by github to [Privately report a security vulnerability][github-guidance-url]. + +> [!NOTE] +> On Github, navigate to the project's "Security" tab then click on "Report a vulnerability". + +[codeql-url]: https://github.com/github/codeql +[trivy-url]: https://trivy.dev/docs/latest/getting-started +[govulncheck-url]: https://go.dev/blog/govulncheck +[github-guidance-url]: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability diff --git a/vendor/github.com/go-openapi/jsonpointer/errors.go b/vendor/github.com/go-openapi/jsonpointer/errors.go index b84343d9..2ae6e3cf 100644 --- a/vendor/github.com/go-openapi/jsonpointer/errors.go +++ b/vendor/github.com/go-openapi/jsonpointer/errors.go @@ -1,5 +1,10 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package jsonpointer +import "fmt" + type pointerError string func (e pointerError) Error() string { @@ -7,12 +12,49 @@ func (e pointerError) Error() string { } const ( - // ErrPointer is an error raised by the jsonpointer package + // ErrPointer is a sentinel error raised by all errors from this package. ErrPointer pointerError = "JSON pointer error" - // ErrInvalidStart states that a JSON pointer must start with a separator ("/") - ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator + // ErrInvalidStart states that a JSON pointer must start with a separator ("/"). + ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator + `"` - // ErrUnsupportedValueType indicates that a value of the wrong type is being set + // ErrUnsupportedValueType indicates that a value of the wrong type is being set. ErrUnsupportedValueType pointerError = "only structs, pointers, maps and slices are supported for setting values" + + // ErrDashToken indicates use of the RFC 6901 "-" reference token in a context where it cannot be + // resolved. + // + // Per RFC 6901 §4 the "-" token refers to the (nonexistent) element after the last array element. + // It may only be used as the terminal token of a [Pointer.Set] against a slice, where it means + // "append". + // + // Any other use (get, offset, intermediate traversal, non-slice target) is an error condition that + // wraps this sentinel. + ErrDashToken pointerError = `the "-" array token cannot be resolved here` //nolint:gosec // G101 false positive: this is a JSON Pointer reference token, not a credential. ) + +const dashToken = "-" + +func errNoKey(key string) error { + return fmt.Errorf("object has no key %q: %w", key, ErrPointer) +} + +func errOutOfBounds(length, idx int) error { + return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", length-1, idx, ErrPointer) +} + +func errInvalidReference(token string) error { + return fmt.Errorf("invalid token reference %q: %w", token, ErrPointer) +} + +func errDashOnGet() error { + return fmt.Errorf("cannot resolve %q token on get: %w: %w", dashToken, ErrDashToken, ErrPointer) +} + +func errDashIntermediate() error { + return fmt.Errorf("the %q token may only appear as the terminal token of a pointer: %w: %w", dashToken, ErrDashToken, ErrPointer) +} + +func errDashOnOffset() error { + return fmt.Errorf("cannot compute offset for %q token (nonexistent element): %w: %w", dashToken, ErrDashToken, ErrPointer) +} diff --git a/vendor/github.com/go-openapi/jsonpointer/ifaces.go b/vendor/github.com/go-openapi/jsonpointer/ifaces.go new file mode 100644 index 00000000..31359c48 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/ifaces.go @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonpointer + +import "reflect" + +// JSONPointable is an interface for structs to implement, when they need to customize the json +// pointer process or want to avoid the use of reflection. +type JSONPointable interface { + // JSONLookup returns a value pointed at this (unescaped) key. + JSONLookup(key string) (any, error) +} + +// JSONSetable is an interface for structs to implement, when they need to customize the json +// pointer process or want to avoid the use of reflection. +// +// # Handling of the RFC 6901 "-" token +// +// When a type implementing JSONSetable is the terminal parent of a [Pointer.Set] call, the library +// passes the raw reference token to JSONSet without interpretation. +// +// In particular, the RFC 6901 "-" token (which conventionally means "append" for arrays, per RFC +// 6902) is forwarded verbatim as the key argument. +// +// Implementations that model an array-like container are expected to give "-" the append semantics; +// implementations that do not should return an error wrapping [ErrDashToken] (or [ErrPointer]) for +// clarity. +// +// Implementations are responsible for any in-place mutation: the library does not attempt to rebind +// the result of JSONSet into a parent container. +type JSONSetable interface { + // JSONSet sets the value pointed at the (unescaped) key. + // + // The key may be the RFC 6901 "-" token when the pointer targets a slice-like member; see the + // interface documentation for details. + JSONSet(key string, value any) error +} + +// NameProvider knows how to resolve go struct fields into json names. +// +// The default provider is brought by +// [github.com/go-openapi/jsonpointer/jsonname.DefaultJSONNameProvider]. +type NameProvider interface { + // GetGoName gets the go name for a json property name + GetGoName(subject any, name string) (string, bool) + + // GetGoNameForType gets the go name for a given type for a json property name + GetGoNameForType(tpe reflect.Type, name string) (string, bool) +} diff --git a/vendor/github.com/go-openapi/jsonpointer/jsonname/doc.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/doc.go new file mode 100644 index 00000000..79232eac --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/jsonname/doc.go @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package jsonname is a provider of json property names from go properties. +package jsonname diff --git a/vendor/github.com/go-openapi/jsonpointer/jsonname/go_name_provider.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/go_name_provider.go new file mode 100644 index 00000000..5eec18fb --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/jsonname/go_name_provider.go @@ -0,0 +1,288 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonname + +import ( + "reflect" + "strings" + "sync" +) + +var _ providerIface = (*GoNameProvider)(nil) + +// GoNameProvider resolves json property names to go struct field names following the same rules as +// the standard library's [encoding/json] package. +// +// Contrary to [NameProvider], it considers exported fields without a json tag, and promotes fields +// from anonymous embedded struct types. +// +// Rules (aligned with encoding/json): +// +// - unexported fields are ignored; +// - a field tagged `json:"-"` is ignored; +// - a field tagged `json:"-,"` is kept under the json name "-" (stdlib quirk); +// - a field tagged `json:""` or with no json tag at all keeps its Go name as json name; +// - anonymous struct fields without an explicit json tag have their fields +// promoted into the parent, following breadth-first depth rules: +// a shallower field wins over a deeper one; at equal depth, a conflict +// discards all conflicting fields unless exactly one has an explicit json tag. +// +// This type is safe for concurrent use. +type GoNameProvider struct { + lock sync.Mutex + index map[reflect.Type]nameIndex +} + +// NewGoNameProvider creates a new [GoNameProvider]. +func NewGoNameProvider() *GoNameProvider { + return &GoNameProvider{ + index: make(map[reflect.Type]nameIndex), + } +} + +// GetJSONNames gets all the json property names for a type. +func (n *GoNameProvider) GetJSONNames(subject any) []string { + n.lock.Lock() + defer n.lock.Unlock() + + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + names := n.nameIndexFor(tpe) + + res := make([]string, 0, len(names.jsonNames)) + for k := range names.jsonNames { + res = append(res, k) + } + + return res +} + +// GetJSONName gets the json name for a go property name. +func (n *GoNameProvider) GetJSONName(subject any, name string) (string, bool) { + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + + return n.GetJSONNameForType(tpe, name) +} + +// GetJSONNameForType gets the json name for a go property name on a given type. +func (n *GoNameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) { + n.lock.Lock() + defer n.lock.Unlock() + + names := n.nameIndexFor(tpe) + nme, ok := names.goNames[name] + + return nme, ok +} + +// GetGoName gets the go name for a json property name. +func (n *GoNameProvider) GetGoName(subject any, name string) (string, bool) { + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + + return n.GetGoNameForType(tpe, name) +} + +// GetGoNameForType gets the go name for a given type for a json property name. +func (n *GoNameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) { + n.lock.Lock() + defer n.lock.Unlock() + + names := n.nameIndexFor(tpe) + nme, ok := names.jsonNames[name] + + return nme, ok +} + +func (n *GoNameProvider) nameIndexFor(tpe reflect.Type) nameIndex { + if names, ok := n.index[tpe]; ok { + return names + } + + names := buildGoNameIndex(tpe) + n.index[tpe] = names + + return names +} + +// fieldEntry captures a candidate field discovered while walking a struct along with the +// indirection path from the root type (used to resolve conflicts by depth in the same way +// encoding/json does). +type fieldEntry struct { + goName string + jsonName string + index []int + tagged bool +} + +func buildGoNameIndex(tpe reflect.Type) nameIndex { + fields := collectGoFields(tpe) + + idx := make(map[string]string, len(fields)) + reverseIdx := make(map[string]string, len(fields)) + for _, f := range fields { + idx[f.jsonName] = f.goName + reverseIdx[f.goName] = f.jsonName + } + + return nameIndex{jsonNames: idx, goNames: reverseIdx} +} + +// collectGoFields walks tpe breadth-first along anonymous struct fields, +// reproducing the field selection performed by encoding/json.typeFields. +// +//nolint:gocognit // everything is inlined to help the compiler determine what escapes and what doesn't +func collectGoFields(tpe reflect.Type) []fieldEntry { + if tpe.Kind() != reflect.Struct { + return nil + } + + type queued struct { + typ reflect.Type + index []int + } + + current := []queued{} + next := []queued{{typ: tpe}} + visited := map[reflect.Type]bool{tpe: true} + + var ( + candidates []fieldEntry + count = map[string]int{} + nextCount = map[string]int{} + ) + + for len(next) > 0 { + current, next = next, current[:0] + count, nextCount = nextCount, count + for k := range nextCount { + delete(nextCount, k) + } + + for _, q := range current { + for i := range q.typ.NumField() { + sf := q.typ.Field(i) + + if sf.Anonymous { + ft := sf.Type + if ft.Kind() == reflect.Pointer { + ft = ft.Elem() + } + if !sf.IsExported() && ft.Kind() != reflect.Struct { + continue + } + } else if !sf.IsExported() { + continue + } + + tag := sf.Tag.Get("json") + if tag == "-" { + continue + } + jsonName, _ := parseJSONTag(tag) + tagged := jsonName != "" + + ft := sf.Type + if ft.Kind() == reflect.Pointer { + ft = ft.Elem() + } + + if sf.Anonymous && ft.Kind() == reflect.Struct && !tagged { + if visited[ft] { + continue + } + visited[ft] = true + + index := make([]int, len(q.index)+1) + copy(index, q.index) + index[len(q.index)] = i + next = append(next, queued{typ: ft, index: index}) + + continue + } + + name := jsonName + if name == "" { + name = sf.Name + } + + index := make([]int, len(q.index)+1) + copy(index, q.index) + index[len(q.index)] = i + + candidates = append(candidates, fieldEntry{ + goName: sf.Name, + jsonName: name, + index: index, + tagged: tagged, + }) + nextCount[name]++ + } + } + } + + return dominantFields(candidates) +} + +// dominantFields applies the Go encoding/json conflict resolution rules: at each JSON name, the +// shallowest field wins; at equal depth, a uniquely tagged candidate wins; otherwise all candidates +// for that name are dropped. +func dominantFields(candidates []fieldEntry) []fieldEntry { + byName := make(map[string][]fieldEntry, len(candidates)) + for _, c := range candidates { + byName[c.jsonName] = append(byName[c.jsonName], c) + } + + out := make([]fieldEntry, 0, len(byName)) + for _, group := range byName { + if len(group) == 1 { + out = append(out, group[0]) + + continue + } + + minDepth := len(group[0].index) + for _, c := range group[1:] { + if len(c.index) < minDepth { + minDepth = len(c.index) + } + } + + var shallow []fieldEntry + for _, c := range group { + if len(c.index) == minDepth { + shallow = append(shallow, c) + } + } + + if len(shallow) == 1 { + out = append(out, shallow[0]) + + continue + } + + var tagged []fieldEntry + for _, c := range shallow { + if c.tagged { + tagged = append(tagged, c) + } + } + if len(tagged) == 1 { + out = append(out, tagged[0]) + } + } + + return out +} + +// parseJSONTag returns the name component of a json struct tag and whether it carried any non-name +// option (kept for future-proofing, e.g. "omitempty"). +func parseJSONTag(tag string) (string, string) { + if tag == "" { + return "", "" + } + if before, after, ok := strings.Cut(tag, ","); ok { + return before, after + } + + return tag, "" +} diff --git a/vendor/github.com/go-openapi/jsonpointer/jsonname/ifaces.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/ifaces.go new file mode 100644 index 00000000..64871f0d --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/jsonname/ifaces.go @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonname + +import "reflect" + +// providerIface is an unexported compile-time contract that every name provider in this package is +// expected to satisfy. +// +// It mirrors the interface declared by the main consumer of this module: +// [github.com/go-openapi/jsonpointer.NameProvider]. +type providerIface interface { + GetGoName(subject any, name string) (string, bool) + GetGoNameForType(tpe reflect.Type, name string) (string, bool) +} diff --git a/vendor/github.com/go-openapi/jsonpointer/jsonname/name_provider.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/name_provider.go new file mode 100644 index 00000000..1bec2406 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/jsonname/name_provider.go @@ -0,0 +1,140 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonname + +import ( + "reflect" + "strings" + "sync" +) + +// DefaultJSONNameProvider is the default cache for types. +var DefaultJSONNameProvider = NewNameProvider() //nolint:gochecknoglobals // default settings, for backward compatible package-level settings + +var _ providerIface = (*NameProvider)(nil) + +// NameProvider represents an object capable of translating from go property names to json property +// names. +// +// This type is thread-safe. +// +// See [github.com/go-openapi/jsonpointer.Pointer] for an example. +type NameProvider struct { + lock *sync.Mutex + index map[reflect.Type]nameIndex +} + +type nameIndex struct { + jsonNames map[string]string + goNames map[string]string +} + +// NewNameProvider creates a new name provider. +func NewNameProvider() *NameProvider { + return &NameProvider{ + lock: &sync.Mutex{}, + index: make(map[reflect.Type]nameIndex), + } +} + +func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) { + for i := range tpe.NumField() { + targetDes := tpe.Field(i) + + if targetDes.PkgPath != "" { // unexported + continue + } + + if targetDes.Anonymous { // walk embedded structures tree down first + buildnameIndex(targetDes.Type, idx, reverseIdx) + continue + } + + if tag := targetDes.Tag.Get("json"); tag != "" { + + parts := strings.Split(tag, ",") + if len(parts) == 0 { + continue + } + + nm := parts[0] + if nm == "-" { + continue + } + if nm == "" { // empty string means we want to use the Go name + nm = targetDes.Name + } + + idx[nm] = targetDes.Name + reverseIdx[targetDes.Name] = nm + } + } +} + +func newNameIndex(tpe reflect.Type) nameIndex { + idx := make(map[string]string, tpe.NumField()) + reverseIdx := make(map[string]string, tpe.NumField()) + + buildnameIndex(tpe, idx, reverseIdx) + return nameIndex{jsonNames: idx, goNames: reverseIdx} +} + +// GetJSONNames gets all the json property names for a type. +func (n *NameProvider) GetJSONNames(subject any) []string { + n.lock.Lock() + defer n.lock.Unlock() + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + names, ok := n.index[tpe] + if !ok { + names = n.makeNameIndex(tpe) + } + + res := make([]string, 0, len(names.jsonNames)) + for k := range names.jsonNames { + res = append(res, k) + } + return res +} + +// GetJSONName gets the json name for a go property name. +func (n *NameProvider) GetJSONName(subject any, name string) (string, bool) { + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + return n.GetJSONNameForType(tpe, name) +} + +// GetJSONNameForType gets the json name for a go property name on a given type. +func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) { + n.lock.Lock() + defer n.lock.Unlock() + names, ok := n.index[tpe] + if !ok { + names = n.makeNameIndex(tpe) + } + nme, ok := names.goNames[name] + return nme, ok +} + +// GetGoName gets the go name for a json property name. +func (n *NameProvider) GetGoName(subject any, name string) (string, bool) { + tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() + return n.GetGoNameForType(tpe, name) +} + +// GetGoNameForType gets the go name for a given type for a json property name. +func (n *NameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) { + n.lock.Lock() + defer n.lock.Unlock() + names, ok := n.index[tpe] + if !ok { + names = n.makeNameIndex(tpe) + } + nme, ok := names.jsonNames[name] + return nme, ok +} + +func (n *NameProvider) makeNameIndex(tpe reflect.Type) nameIndex { + names := newNameIndex(tpe) + n.index[tpe] = names + return names +} diff --git a/vendor/github.com/go-openapi/jsonpointer/options.go b/vendor/github.com/go-openapi/jsonpointer/options.go new file mode 100644 index 00000000..223c1e5f --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/options.go @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonpointer + +import ( + "sync" + + "github.com/go-openapi/jsonpointer/jsonname" +) + +// Option to tune the behavior of a JSON [Pointer]. +type Option func(*options) + +var ( + //nolint:gochecknoglobals // package level defaults are provided as a convenient, backward-compatible way to adopt options. + defaultOptions = options{ + provider: jsonname.DefaultJSONNameProvider, + } + //nolint:gochecknoglobals // guards defaultOptions against concurrent SetDefaultNameProvider / read races (testing) + defaultOptionsMu sync.RWMutex +) + +// SetDefaultNameProvider sets the [NameProvider] as a package-level default. +// +// By default, the default provider is [jsonname.DefaultJSONNameProvider]. +// +// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], [GetForToken] and +// [SetForToken]. +// The typical usage is to call it once at initialization time. +// +// A nil provider is ignored. +func SetDefaultNameProvider(provider NameProvider) { + if provider == nil { + return + } + + defaultOptionsMu.Lock() + defer defaultOptionsMu.Unlock() + + defaultOptions.provider = provider +} + +// UseGoNameProvider sets the [NameProvider] as a package-level default to the alternative provider +// [jsonname.GoNameProvider], that covers a few areas not supported by the default name provider. +// +// This implementation supports untagged exported fields and embedded types in go struct. +// It follows strictly the behavior of the JSON standard library regarding field naming conventions. +// +// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], [GetForToken] and +// [SetForToken]. +// The typical usage is to call it once at initialization time. +func UseGoNameProvider() { + SetDefaultNameProvider(jsonname.NewGoNameProvider()) +} + +// DefaultNameProvider returns the current package-level [NameProvider]. +func DefaultNameProvider() NameProvider { //nolint:ireturn // returning the interface is the point — callers pick their own implementation. + defaultOptionsMu.RLock() + defer defaultOptionsMu.RUnlock() + + return defaultOptions.provider +} + +// WithNameProvider injects a custom [NameProvider] to resolve json names from go struct types. +func WithNameProvider(provider NameProvider) Option { + return func(o *options) { + o.provider = provider + } +} + +type options struct { + provider NameProvider +} + +func optionsWithDefaults(opts []Option) options { + var o options + o.provider = DefaultNameProvider() + + for _, apply := range opts { + apply(&o) + } + + return o +} diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go index a08cd68a..05fc863e 100644 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go @@ -1,28 +1,7 @@ -// Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) -// -// 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. - -// author sigu-399 -// author-github https://github.com/sigu-399 -// author-mail sigu.399@gmail.com -// -// repository-name jsonpointer -// repository-desc An implementation of JSON Pointer - Go language -// -// description Main and unique file. -// -// created 25-02-2013 +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 +// Package jsonpointer provides a golang implementation for json pointers. package jsonpointer import ( @@ -32,8 +11,6 @@ import ( "reflect" "strconv" "strings" - - "github.com/go-openapi/swag" ) const ( @@ -41,70 +18,428 @@ const ( pointerSeparator = `/` ) -var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem() -var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem() - -// JSONPointable is an interface for structs to implement when they need to customize the -// json pointer process -type JSONPointable interface { - JSONLookup(string) (any, error) -} - -// JSONSetable is an interface for structs to implement when they need to customize the -// json pointer process -type JSONSetable interface { - JSONSet(string, any) error +// Pointer is a representation of a json pointer. +// +// Use [Pointer.Get] to retrieve a value or [Pointer.Set] to set a value. +// +// It works with any go type interpreted as a JSON document, which means: +// +// - if a type implements [JSONPointable], its [JSONPointable.JSONLookup] method is used to resolve [Pointer.Get] +// - if a type implements [JSONSetable], its [JSONSetable.JSONSet] method is used to resolve [Pointer.Set] +// - a go map[K]V is interpreted as an object, with type K assignable to a string +// - a go slice []T is interpreted as an array +// - a go struct is interpreted as an object, with exported fields interpreted as keys +// - promoted fields from an embedded struct are traversed +// - scalars (e.g. int, float64 ...), channels, functions and go arrays cannot be traversed +// +// For struct s resolved by reflection, key mappings honor the conventional struct tag `json`. +// +// Fields that do not specify a `json` tag, or specify an empty one, or are tagged as `json:"-"` are +// ignored. +// +// # Limitations +// +// - Unlike go standard marshaling, untagged fields do not default to the go field name and are ignored. +// - anonymous fields are not traversed if untagged +type Pointer struct { + referenceTokens []string } -// New creates a new json pointer for the given string +// New creates a new json pointer from its string representation. func New(jsonPointerString string) (Pointer, error) { - var p Pointer err := p.parse(jsonPointerString) + return p, err +} +// Get uses the pointer to retrieve a value from a JSON document. +// +// It returns the value with its type as a [reflect.Kind] or an error. +func (p *Pointer) Get(document any, opts ...Option) (any, reflect.Kind, error) { + o := optionsWithDefaults(opts) + + return p.get(document, o.provider) } -// Pointer the json pointer reprsentation -type Pointer struct { - referenceTokens []string +// Set uses the pointer to set a value from a data type that represent a JSON document. +// +// # Mutation contract +// +// Set mutates the provided document in place whenever Go's type system allows it: when document is +// a map, a pointer, or when the targeted value is reached through an addressable ancestor (e.g. a +// struct field traversed via a pointer, a slice element). +// +// Callers that rely on this in-place behavior may continue to ignore the returned document. +// +// The returned document is only load-bearing when Set cannot mutate in place. +// +// This happens in one specific case: appending to a top-level slice passed by value (e.g. document +// of type []T rather than *[]T) via the RFC 6901 "-" terminal token. reflect.Append produces a new +// slice header that the library cannot rebind into the caller's variable; the updated document is +// returned instead. +// +// Pass *[]T if you want in-place rebind for that case as well. +// +// See [ErrDashToken] for the semantics of the "-" token. +func (p *Pointer) Set(document any, value any, opts ...Option) (any, error) { + o := optionsWithDefaults(opts) + + return p.set(document, value, o.provider) +} + +// DecodedTokens returns the decoded (unescaped) tokens of this JSON pointer. +func (p *Pointer) DecodedTokens() []string { + result := make([]string, 0, len(p.referenceTokens)) + for _, token := range p.referenceTokens { + result = append(result, Unescape(token)) + } + + return result +} + +// IsEmpty returns true if this is an empty json pointer. +// +// This indicates that it points to the root document. +func (p *Pointer) IsEmpty() bool { + return len(p.referenceTokens) == 0 +} + +// String representation of a pointer. +func (p *Pointer) String() string { + if len(p.referenceTokens) == 0 { + return emptyPointer + } + + return pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator) +} + +// Offset returns the byte offset, in the raw JSON text of document, of the location referenced by +// this pointer's terminal token. +// +// Unlike [Pointer.Get] and [Pointer.Set], which operate on a decoded Go value, Offset operates +// directly on the textual JSON source. +// +// It drives an [encoding/json.Decoder] over the string and stops at the terminal token, returning +// the position at which the decoder was about to read that token. +// +// It is primarily intended for tooling that needs to map a pointer back to a region of the original +// source: reporting line/column for validation or parse diagnostics, extracting a sub-document by +// slicing the raw bytes, or highlighting the referenced span in an editor. +// +// # Offset semantics +// +// The meaning of the returned offset depends on whether the terminal token addresses an object +// property or an array element: +// +// - Object property: the offset points to the first byte of the key (its +// opening quote character), not to the associated value. For example, +// pointer "/foo/bar" against {"foo": {"bar": 21}} returns 9, the index of +// the opening quote of "bar". +// - Array element: the offset points to the first byte of the value at that +// index. For example, pointer "/0/1" against [[1,2], [3,4]] returns 4, +// the index of the digit 2. +// +// # Errors +// +// Offset returns an error in any of these cases: +// +// - document is not syntactically valid JSON; +// - the structure of document does not match the pointer (e.g. traversing +// into a scalar, or a token that is neither a valid key nor a valid +// numeric index); +// - a referenced key or index does not exist in document; +// - the pointer's terminal token is the RFC 6901 "-" array token, which +// designates a nonexistent element and therefore has no offset in the +// source. The returned error wraps [ErrDashToken]. +// +// All errors wrap [ErrPointer]. +func (p *Pointer) Offset(document string) (int64, error) { + dec := json.NewDecoder(strings.NewReader(document)) + var offset int64 + for _, ttk := range p.DecodedTokens() { + tk, err := dec.Token() + if err != nil { + return 0, err + } + switch tk := tk.(type) { + case json.Delim: + switch tk { + case '{': + offset, err = offsetSingleObject(dec, ttk) + if err != nil { + return 0, err + } + case '[': + offset, err = offsetSingleArray(dec, ttk) + if err != nil { + return 0, err + } + default: + return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) + } + default: + return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) + } + } + return skipJSONSeparator(document, offset), nil +} + +// skipJSONSeparator advances offset past trailing JSON whitespace and at most one value separator +// (comma) in document, so the result points at the first byte of the next JSON token. +// +// The streaming decoder's InputOffset sits right after the most recently consumed token, which +// between values is the comma (or whitespace) — not the following token. +// +// Normalizing here keeps Offset's contract uniform: for both object keys and array elements, and +// regardless of position within the parent container, the returned offset always points at the +// first byte of the addressed token. +func skipJSONSeparator(document string, offset int64) int64 { + n := int64(len(document)) + for offset < n && isJSONWhitespace(document[offset]) { + offset++ + } + if offset < n && document[offset] == ',' { + offset++ + } + for offset < n && isJSONWhitespace(document[offset]) { + offset++ + } + return offset +} + +func isJSONWhitespace(c byte) bool { + return c == ' ' || c == '\t' || c == '\n' || c == '\r' } -// "Constructor", parses the given string JSON pointer +// "Constructor", parses the given string JSON pointer. func (p *Pointer) parse(jsonPointerString string) error { + if jsonPointerString == emptyPointer { + return nil + } + + if !strings.HasPrefix(jsonPointerString, pointerSeparator) { + // non empty pointer must start with "/" + return errors.Join(ErrInvalidStart, ErrPointer) + } + + referenceTokens := strings.Split(jsonPointerString, pointerSeparator) + p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...) + + return nil +} + +func (p *Pointer) get(node any, nameProvider NameProvider) (any, reflect.Kind, error) { + if nameProvider == nil { + nameProvider = defaultOptions.provider + } - var err error + kind := reflect.Invalid - if jsonPointerString != emptyPointer { - if !strings.HasPrefix(jsonPointerString, pointerSeparator) { - err = errors.Join(ErrInvalidStart, ErrPointer) - } else { - referenceTokens := strings.Split(jsonPointerString, pointerSeparator) - p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...) + // full document when empty + if len(p.referenceTokens) == 0 { + return node, kind, nil + } + + for _, token := range p.referenceTokens { + decodedToken := Unescape(token) + + r, knd, err := getSingleImpl(node, decodedToken, nameProvider) + if err != nil { + return nil, knd, err } + node = r } - return err + rValue := reflect.ValueOf(node) + kind = rValue.Kind() + + return node, kind, nil } -// Get uses the pointer to retrieve a value from a JSON document -func (p *Pointer) Get(document any) (any, reflect.Kind, error) { - return p.get(document, swag.DefaultJSONNameProvider) +func (p *Pointer) set(node, data any, nameProvider NameProvider) (any, error) { + knd := reflect.ValueOf(node).Kind() + + if knd != reflect.Pointer && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { + return node, errors.Join( + fmt.Errorf("unexpected type: %T", node), //nolint:err113 // err wrapping is carried out by errors.Join, not fmt.Errorf. + ErrUnsupportedValueType, + ErrPointer, + ) + } + + // full document when empty + if len(p.referenceTokens) == 0 { + return node, nil + } + + if nameProvider == nil { + nameProvider = defaultOptions.provider + } + + return p.setAt(node, p.referenceTokens, data, nameProvider) } -// Set uses the pointer to set a value from a JSON document -func (p *Pointer) Set(document any, value any) (any, error) { - return document, p.set(document, value, swag.DefaultJSONNameProvider) +// setAt recursively walks the token list, setting the data at the terminal token and rebinding any +// new child reference (e.g. a slice header returned by an "-" append) into its parent on the way +// back up. +// +// Returning the (possibly new) node at each level is what makes append work at any depth without +// requiring the caller to pass a pointer to the containing slice: the new slice header propagates +// up and each parent rebinds it via the appropriate kind-specific setter. +func (p *Pointer) setAt(node any, tokens []string, data any, nameProvider NameProvider) (any, error) { + decodedToken := Unescape(tokens[0]) + + if len(tokens) == 1 { + return setSingleImpl(node, data, decodedToken, nameProvider) + } + + child, err := p.resolveNodeForToken(node, decodedToken, nameProvider) + if err != nil { + return node, err + } + + newChild, err := p.setAt(child, tokens[1:], data, nameProvider) + if err != nil { + return node, err + } + + return rebindChild(node, decodedToken, newChild, nameProvider) +} + +// rebindChild writes newChild back into node at decodedToken. +// +// For cases where the child was already mutated in place (pointer aliasing, addressable slice +// elements) the rebind is a safe no-op. +// +// For cases where the child was returned by value (map entries holding a slice, slices reached +// through a non-addressable ancestor), the rebind propagates the new value into the parent. +// +// Parents implementing [JSONPointable] are left alone: they took ownership of the child via +// JSONLookup and did not opt into a JSONSet-based rebind on intermediate tokens. +func rebindChild(node any, decodedToken string, newChild any, nameProvider NameProvider) (any, error) { + if _, ok := node.(JSONPointable); ok { + return node, nil + } + + rValue := reflect.Indirect(reflect.ValueOf(node)) + + switch rValue.Kind() { + case reflect.Struct: + nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) + if !ok { + return node, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) + } + fld := rValue.FieldByName(nm) + if !fld.CanSet() { + return node, nil + } + assignReflectValue(fld, newChild) + return node, nil + + case reflect.Map: + rValue.SetMapIndex(reflect.ValueOf(decodedToken), reflect.ValueOf(newChild)) + return node, nil + + case reflect.Slice: + if decodedToken == dashToken { + return node, errDashIntermediate() + } + idx, err := strconv.Atoi(decodedToken) + if err != nil { + return node, errors.Join(err, ErrPointer) + } + elem := rValue.Index(idx) + if !elem.CanSet() { + return node, nil + } + assignReflectValue(elem, newChild) + return node, nil + + default: + return node, errInvalidReference(decodedToken) + } } -// GetForToken gets a value for a json pointer token 1 level deep -func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) { - return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider) +// assignReflectValue assigns src into dst, unwrapping a pointer when dst expects the pointee type. +// +// This tolerates the pointer-wrapping performed by [typeFromValue] for addressable fields. +func assignReflectValue(dst reflect.Value, src any) { + nv := reflect.ValueOf(src) + if !nv.IsValid() { + return + } + if nv.Type().AssignableTo(dst.Type()) { + dst.Set(nv) + return + } + if nv.Kind() == reflect.Pointer && nv.Elem().Type().AssignableTo(dst.Type()) { + dst.Set(nv.Elem()) + } } -// SetForToken gets a value for a json pointer token 1 level deep -func SetForToken(document any, decodedToken string, value any) (any, error) { - return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider) +func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvider NameProvider) (next any, err error) { + // check for nil during traversal + if isNil(node) { + return nil, fmt.Errorf("cannot traverse through nil value at %q: %w", decodedToken, ErrPointer) + } + + pointable, ok := node.(JSONPointable) + if ok { + r, err := pointable.JSONLookup(decodedToken) + if err != nil { + return nil, err + } + + fld := reflect.ValueOf(r) + if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Pointer { + return fld.Addr().Interface(), nil + } + + return r, nil + } + + rValue := reflect.Indirect(reflect.ValueOf(node)) + kind := rValue.Kind() + + switch kind { + case reflect.Struct: + nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) + if !ok { + return nil, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) + } + + return typeFromValue(rValue.FieldByName(nm)), nil + + case reflect.Map: + kv := reflect.ValueOf(decodedToken) + mv := rValue.MapIndex(kv) + + if !mv.IsValid() { + return nil, errNoKey(decodedToken) + } + + return typeFromValue(mv), nil + + case reflect.Slice: + if decodedToken == dashToken { + return nil, errDashIntermediate() + } + tokenIndex, err := strconv.Atoi(decodedToken) + if err != nil { + return nil, errors.Join(err, ErrPointer) + } + + sLength := rValue.Len() + if tokenIndex < 0 || tokenIndex >= sLength { + return nil, errOutOfBounds(sLength, tokenIndex) + } + + return typeFromValue(rValue.Index(tokenIndex)), nil + + default: + return nil, errInvalidReference(decodedToken) + } } func isNil(input any) bool { @@ -113,15 +448,40 @@ func isNil(input any) bool { } kind := reflect.TypeOf(input).Kind() - switch kind { //nolint:exhaustive - case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan: + switch kind { + case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Chan: return reflect.ValueOf(input).IsNil() default: return false } } -func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { +func typeFromValue(v reflect.Value) any { + if v.CanAddr() && v.Kind() != reflect.Interface && v.Kind() != reflect.Map && v.Kind() != reflect.Slice && v.Kind() != reflect.Pointer { + return v.Addr().Interface() + } + + return v.Interface() +} + +// GetForToken gets a value for a json pointer token 1 level deep. +func GetForToken(document any, decodedToken string, opts ...Option) (any, reflect.Kind, error) { + o := optionsWithDefaults(opts) + + return getSingleImpl(document, decodedToken, o.provider) +} + +// SetForToken sets a value for a json pointer token 1 level deep. +// +// See [Pointer.Set] for the mutation contract, in particular the handling of the RFC 6901 "-" token +// on slices. +func SetForToken(document any, decodedToken string, value any, opts ...Option) (any, error) { + o := optionsWithDefaults(opts) + + return setSingleImpl(document, value, decodedToken, o.provider) +} + +func getSingleImpl(node any, decodedToken string, nameProvider NameProvider) (any, reflect.Kind, error) { rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() if isNil(node) { @@ -139,13 +499,15 @@ func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvide return getSingleImpl(*typed, decodedToken, nameProvider) } - switch kind { //nolint:exhaustive + switch kind { case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { return nil, kind, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) } + fld := rValue.FieldByName(nm) + return fld.Interface(), kind, nil case reflect.Map: @@ -155,297 +517,164 @@ func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvide if mv.IsValid() { return mv.Interface(), kind, nil } - return nil, kind, fmt.Errorf("object has no key %q: %w", decodedToken, ErrPointer) + + return nil, kind, errNoKey(decodedToken) case reflect.Slice: + if decodedToken == dashToken { + return nil, kind, errDashOnGet() + } tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { - return nil, kind, err + return nil, kind, errors.Join(err, ErrPointer) } sLength := rValue.Len() if tokenIndex < 0 || tokenIndex >= sLength { - return nil, kind, fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength-1, tokenIndex, ErrPointer) + return nil, kind, errOutOfBounds(sLength, tokenIndex) } elem := rValue.Index(tokenIndex) return elem.Interface(), kind, nil default: - return nil, kind, fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer) + return nil, kind, errInvalidReference(decodedToken) } - } -func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error { - rValue := reflect.Indirect(reflect.ValueOf(node)) - - if ns, ok := node.(JSONSetable); ok { // pointer impl - return ns.JSONSet(decodedToken, data) +func setSingleImpl(node, data any, decodedToken string, nameProvider NameProvider) (any, error) { + // check for nil to prevent panic when calling rValue.Type() + if isNil(node) { + return node, fmt.Errorf("cannot set field %q on nil value: %w", decodedToken, ErrPointer) } - if rValue.Type().Implements(jsonSetableType) { - return node.(JSONSetable).JSONSet(decodedToken, data) + if ns, ok := node.(JSONSetable); ok { + return node, ns.JSONSet(decodedToken, data) } - switch rValue.Kind() { //nolint:exhaustive + rValue := reflect.Indirect(reflect.ValueOf(node)) + + switch rValue.Kind() { case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { - return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) + return node, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) } + fld := rValue.FieldByName(nm) - if fld.IsValid() { - fld.Set(reflect.ValueOf(data)) + if !fld.CanSet() { + return node, fmt.Errorf("can't set struct field %s to %v: %w", nm, data, ErrPointer) } - return nil + + value := reflect.ValueOf(data) + valueType := value.Type() + assignedType := fld.Type() + + if !valueType.AssignableTo(assignedType) { + return node, fmt.Errorf("can't set value with type %T to field %s with type %v: %w", data, nm, assignedType, ErrPointer) + } + + fld.Set(value) + + return node, nil case reflect.Map: kv := reflect.ValueOf(decodedToken) rValue.SetMapIndex(kv, reflect.ValueOf(data)) - return nil + + return node, nil case reflect.Slice: + if decodedToken == dashToken { + // RFC 6901 §4 / RFC 6902 append semantics: terminal "-" appends the value to the slice. + // + // We rebind in place when the slice is reachable via an addressable ancestor; otherwise we + // return the new slice header for the parent (or the public Set) to rebind. + value := reflect.ValueOf(data) + elemType := rValue.Type().Elem() + if !value.Type().AssignableTo(elemType) { + return node, fmt.Errorf("can't append value of type %T to slice of %v: %w", data, elemType, ErrPointer) + } + newSlice := reflect.Append(rValue, value) + if rValue.CanSet() { + rValue.Set(newSlice) + return node, nil + } + return newSlice.Interface(), nil + } + tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { - return err + return node, errors.Join(err, ErrPointer) } + sLength := rValue.Len() if tokenIndex < 0 || tokenIndex >= sLength { - return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength, tokenIndex, ErrPointer) + return node, errOutOfBounds(sLength, tokenIndex) } elem := rValue.Index(tokenIndex) if !elem.CanSet() { - return fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer) - } - elem.Set(reflect.ValueOf(data)) - return nil - - default: - return fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer) - } - -} - -func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) { - - if nameProvider == nil { - nameProvider = swag.DefaultJSONNameProvider - } - - kind := reflect.Invalid - - // Full document when empty - if len(p.referenceTokens) == 0 { - return node, kind, nil - } - - for _, token := range p.referenceTokens { - decodedToken := Unescape(token) - - r, knd, err := getSingleImpl(node, decodedToken, nameProvider) - if err != nil { - return nil, knd, err - } - node = r - } - - rValue := reflect.ValueOf(node) - kind = rValue.Kind() - - return node, kind, nil -} - -func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error { - knd := reflect.ValueOf(node).Kind() - - if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { - return errors.Join( - ErrUnsupportedValueType, - ErrPointer, - ) - } - - if nameProvider == nil { - nameProvider = swag.DefaultJSONNameProvider - } - - // Full document when empty - if len(p.referenceTokens) == 0 { - return nil - } - - lastI := len(p.referenceTokens) - 1 - for i, token := range p.referenceTokens { - isLastToken := i == lastI - decodedToken := Unescape(token) - - if isLastToken { - - return setSingleImpl(node, data, decodedToken, nameProvider) + return node, fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer) } - rValue := reflect.Indirect(reflect.ValueOf(node)) - kind := rValue.Kind() + value := reflect.ValueOf(data) + valueType := value.Type() + assignedType := elem.Type() - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) - if err != nil { - return err - } - fld := reflect.ValueOf(r) - if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { - node = fld.Addr().Interface() - continue - } - node = r - continue + if !valueType.AssignableTo(assignedType) { + return node, fmt.Errorf("can't set value with type %T to slice element %d with type %v: %w", data, tokenIndex, assignedType, ErrPointer) } - switch kind { //nolint:exhaustive - case reflect.Struct: - nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) - if !ok { - return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) - } - fld := rValue.FieldByName(nm) - if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { - node = fld.Addr().Interface() - continue - } - node = fld.Interface() - - case reflect.Map: - kv := reflect.ValueOf(decodedToken) - mv := rValue.MapIndex(kv) + elem.Set(value) - if !mv.IsValid() { - return fmt.Errorf("object has no key %q: %w", decodedToken, ErrPointer) - } - if mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Ptr { - node = mv.Addr().Interface() - continue - } - node = mv.Interface() - - case reflect.Slice: - tokenIndex, err := strconv.Atoi(decodedToken) - if err != nil { - return err - } - sLength := rValue.Len() - if tokenIndex < 0 || tokenIndex >= sLength { - return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength, tokenIndex, ErrPointer) - } - - elem := rValue.Index(tokenIndex) - if elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Ptr { - node = elem.Addr().Interface() - continue - } - node = elem.Interface() + return node, nil - default: - return fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer) - } - - } - - return nil -} - -// DecodedTokens returns the decoded tokens -func (p *Pointer) DecodedTokens() []string { - result := make([]string, 0, len(p.referenceTokens)) - for _, t := range p.referenceTokens { - result = append(result, Unescape(t)) - } - return result -} - -// IsEmpty returns true if this is an empty json pointer -// this indicates that it points to the root document -func (p *Pointer) IsEmpty() bool { - return len(p.referenceTokens) == 0 -} - -// Pointer to string representation function -func (p *Pointer) String() string { - - if len(p.referenceTokens) == 0 { - return emptyPointer + default: + return node, errInvalidReference(decodedToken) } - - pointerString := pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator) - - return pointerString } -func (p *Pointer) Offset(document string) (int64, error) { - dec := json.NewDecoder(strings.NewReader(document)) - var offset int64 - for _, ttk := range p.DecodedTokens() { +func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { + for dec.More() { + offset := dec.InputOffset() tk, err := dec.Token() if err != nil { return 0, err } - switch tk := tk.(type) { - case json.Delim: - switch tk { - case '{': - offset, err = offsetSingleObject(dec, ttk) - if err != nil { - return 0, err - } - case '[': - offset, err = offsetSingleArray(dec, ttk) - if err != nil { - return 0, err - } - default: - return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) - } - default: - return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) + key, ok := tk.(string) + if !ok { + return 0, fmt.Errorf("invalid key token %#v: %w", tk, ErrPointer) + } + if key == decodedToken { + return offset, nil } - } - return offset, nil -} -func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { - for dec.More() { - offset := dec.InputOffset() - tk, err := dec.Token() + // Consume the associated value. + // Scalars are fully read by a single Token() call; composite values must be drained. + tk, err = dec.Token() if err != nil { return 0, err } - switch tk := tk.(type) { - case json.Delim: - switch tk { - case '{': - if err = drainSingle(dec); err != nil { - return 0, err - } - case '[': + if delim, isDelim := tk.(json.Delim); isDelim { + switch delim { + case '{', '[': if err = drainSingle(dec); err != nil { return 0, err } } - case string: - if tk == decodedToken { - return offset, nil - } - default: - return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) } } + return 0, fmt.Errorf("token reference %q not found: %w", decodedToken, ErrPointer) } func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) { + if decodedToken == dashToken { + return 0, errDashOnOffset() + } idx, err := strconv.Atoi(decodedToken) if err != nil { - return 0, fmt.Errorf("token reference %q is not a number: %v: %w", decodedToken, err, ErrPointer) + return 0, fmt.Errorf("token reference %q is not a number: %w: %w", decodedToken, err, ErrPointer) } var i int for i = 0; i < idx && dec.More(); i++ { @@ -471,10 +700,12 @@ func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) { if !dec.More() { return 0, fmt.Errorf("token reference %q not found: %w", decodedToken, ErrPointer) } + return dec.InputOffset(), nil } // drainSingle drains a single level of object or array. +// // The decoder has to guarantee the beginning delim (i.e. '{' or '[') has been consumed. func drainSingle(dec *json.Decoder) error { for dec.More() { @@ -496,17 +727,15 @@ func drainSingle(dec *json.Decoder) error { } } - // Consumes the ending delim + // consumes the ending delim if _, err := dec.Token(); err != nil { return err } + return nil } -// Specific JSON pointer encoding here -// ~0 => ~ -// ~1 => / -// ... and vice versa +// JSON pointer encoding: ~0 => ~ ~1 => / ... and vice versa. const ( encRefTok0 = `~0` @@ -515,16 +744,24 @@ const ( decRefTok1 = `/` ) -// Unescape unescapes a json pointer reference token string to the original representation +var ( + encRefTokReplacer = strings.NewReplacer(encRefTok1, decRefTok1, encRefTok0, decRefTok0) //nolint:gochecknoglobals // it's okay to declare a replacer as a private global + decRefTokReplacer = strings.NewReplacer(decRefTok1, encRefTok1, decRefTok0, encRefTok0) //nolint:gochecknoglobals // it's okay to declare a replacer as a private global +) + +// Unescape unescapes a json pointer reference token string to the original representation. func Unescape(token string) string { - step1 := strings.ReplaceAll(token, encRefTok1, decRefTok1) - step2 := strings.ReplaceAll(step1, encRefTok0, decRefTok0) - return step2 + return encRefTokReplacer.Replace(token) } -// Escape escapes a pointer reference token string +// Escape escapes a pointer reference token string. +// +// The JSONPointer specification defines "/" as a separator and "~" as an escape prefix. +// +// Keys containing such characters are escaped with the following rules: +// +// - "~" is escaped as "~0" +// - "/" is escaped as "~1" func Escape(token string) string { - step1 := strings.ReplaceAll(token, decRefTok0, encRefTok0) - step2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1) - return step2 + return decRefTokReplacer.Replace(token) } diff --git a/vendor/github.com/go-openapi/jsonreference/.editorconfig b/vendor/github.com/go-openapi/jsonreference/.editorconfig new file mode 100644 index 00000000..3152da69 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonreference/.editorconfig @@ -0,0 +1,26 @@ +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +# Set default charset +[*.{js,py,go,scala,rb,java,html,css,less,sass,md}] +charset = utf-8 + +# Tab indentation (no size specified) +[*.go] +indent_style = tab + +[*.md] +trim_trailing_whitespace = false + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 diff --git a/vendor/github.com/go-openapi/jsonreference/.gitignore b/vendor/github.com/go-openapi/jsonreference/.gitignore index 769c2440..d8f4186f 100644 --- a/vendor/github.com/go-openapi/jsonreference/.gitignore +++ b/vendor/github.com/go-openapi/jsonreference/.gitignore @@ -1 +1,5 @@ -secrets.yml +*.out +*.cov +.idea +.env +.mcp.json diff --git a/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/vendor/github.com/go-openapi/jsonreference/.golangci.yml index 22f8d21c..dc7c9605 100644 --- a/vendor/github.com/go-openapi/jsonreference/.golangci.yml +++ b/vendor/github.com/go-openapi/jsonreference/.golangci.yml @@ -1,61 +1,67 @@ -linters-settings: - govet: - check-shadowing: true - golint: - min-confidence: 0 - gocyclo: - min-complexity: 45 - maligned: - suggest-new: true - dupl: - threshold: 200 - goconst: - min-len: 2 - min-occurrences: 3 - +version: "2" linters: - enable-all: true + default: all disable: - - maligned - - unparam - - lll - - gochecknoinits - - gochecknoglobals + - depguard - funlen - godox - - gocognit - - whitespace - - wsl - - wrapcheck - - testpackage + - exhaustruct - nlreturn - - gomnd - - exhaustivestruct - - goerr113 - - errorlint - - nestif - - godot - - gofumpt + - nonamedreturns + - noinlineerr - paralleltest - - tparallel + - recvcheck + - testpackage - thelper - - ifshort - - exhaustruct + - tparallel - varnamelen - - gci - - depguard - - errchkjson - - inamedparam - - nonamedreturns - - musttag - - ireturn - - forcetypeassert - - cyclop - # deprecated linters - - deadcode - - interfacer - - scopelint - - varcheck - - structcheck - - golint - - nosnakecase + - whitespace + - wrapcheck + - wsl + - wsl_v5 + settings: + dupl: + threshold: 200 + goconst: + min-len: 2 + min-occurrences: 3 + cyclop: + max-complexity: 20 + gocyclo: + min-complexity: 20 + exhaustive: + default-signifies-exhaustive: true + default-case-required: true + lll: + line-length: 180 + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + - goimports + - gofumpt + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ +issues: + # Maximum issues count per one linter. + # Set to 0 to disable. + # Default: 50 + max-issues-per-linter: 0 + # Maximum count of issues with the same text. + # Set to 0 to disable. + # Default: 3 + max-same-issues: 0 diff --git a/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md b/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md index 9322b065..bac878f2 100644 --- a/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md +++ b/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md @@ -23,7 +23,9 @@ include: Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or + advances + * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic @@ -55,7 +57,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at ivan+abuse@flanders.co.nz. All +reported by contacting the project team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. @@ -68,7 +70,7 @@ members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] +available at [][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md b/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md new file mode 100644 index 00000000..d20737c9 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md @@ -0,0 +1,21 @@ +# Contributors + +- Repository: ['go-openapi/jsonreference'] + +| Total Contributors | Total Contributions | +| --- | --- | +| 9 | 83 | + +| Username | All Time Contribution Count | All Commits | +| --- | --- | --- | +| @fredbi | 46 | | +| @casualjim | 25 | | +| @youyuanwu | 5 | | +| @olivierlemasle | 2 | | +| @apelisse | 1 | | +| @gbjk | 1 | | +| @honza | 1 | | +| @Neo2308 | 1 | | +| @erraggy | 1 | | + + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/jsonreference/NOTICE b/vendor/github.com/go-openapi/jsonreference/NOTICE new file mode 100644 index 00000000..814e87ef --- /dev/null +++ b/vendor/github.com/go-openapi/jsonreference/NOTICE @@ -0,0 +1,39 @@ +Copyright 2015-2025 go-swagger maintainers + +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +This software library, github.com/go-openapi/jsonreference, includes software developed +by the go-swagger and go-openapi maintainers ("go-swagger maintainers"). + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this software except in compliance with the License. + +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0. + +This software is copied from, derived from, and inspired by other original software products. +It ships with copies of other software which license terms are recalled below. + +The original software was authored on 25-02-2013 by sigu-399 (https://github.com/sigu-399, sigu.399@gmail.com). + +github.com/sigh-399/jsonreference +=========================== + +// SPDX-FileCopyrightText: Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) +// SPDX-License-Identifier: Apache-2.0 + +Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) + +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-openapi/jsonreference/README.md b/vendor/github.com/go-openapi/jsonreference/README.md index c7fc2049..fbd16cf8 100644 --- a/vendor/github.com/go-openapi/jsonreference/README.md +++ b/vendor/github.com/go-openapi/jsonreference/README.md @@ -1,19 +1,123 @@ -# gojsonreference [![Build Status](https://github.com/go-openapi/jsonreference/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonreference/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference) +# jsonreference -[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE) -[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonreference.svg)](https://pkg.go.dev/github.com/go-openapi/jsonreference) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonreference)](https://goreportcard.com/report/github.com/go-openapi/jsonreference) + +[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vuln scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url] + + + +[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] + + +[![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] -An implementation of JSON Reference - Go language +--- + +An implementation of JSON Reference for golang. + +## Announcements + +* **2026-07-07** : landing v1.0.0 + * stable API pledge ## Status -Feature complete. Stable API + +API is stable. + +## Import this library in your project + +```cmd +go get github.com/go-openapi/jsonreference +``` ## Dependencies -* https://github.com/go-openapi/jsonpointer + +* + +## Basic usage + +```go +// Creating a new reference +ref, err := jsonreference.New("http://example.com/doc.json#/definitions/Pet") + +// Fragment-only reference +fragRef := jsonreference.MustCreateRef("#/definitions/Pet") + +// Resolving references +parent, _ := jsonreference.New("http://example.com/base.json") +child, _ := jsonreference.New("#/definitions/Pet") +resolved, _ := parent.Inherits(child) +// Result: "http://example.com/base.json#/definitions/Pet" +``` + + +## Change log + +See ## References -* http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 -* http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 +* +* + +## Licensing + +This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE). + +See the license [NOTICE](./NOTICE), which recalls the licensing terms of all the pieces of software +on top of which it has been built. + +## Other documentation + +* [All-time contributors](./CONTRIBUTORS.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] + +## Cutting a new release + +Maintainers can cut a new release by either: + +* running [this workflow](https://github.com/go-openapi/jsonreference/actions/workflows/bump-release.yml) +* or pushing a semver tag + * signed tags are preferred + * The tag message is prepended to release notes + + +[test-badge]: https://github.com/go-openapi/jsonreference/actions/workflows/go-test.yml/badge.svg +[test-url]: https://github.com/go-openapi/jsonreference/actions/workflows/go-test.yml +[cov-badge]: https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg +[cov-url]: https://codecov.io/gh/go-openapi/jsonreference +[vuln-scan-badge]: https://github.com/go-openapi/jsonreference/actions/workflows/scanner.yml/badge.svg +[vuln-scan-url]: https://github.com/go-openapi/jsonreference/actions/workflows/scanner.yml +[codeql-badge]: https://github.com/go-openapi/jsonreference/actions/workflows/codeql.yml/badge.svg +[codeql-url]: https://github.com/go-openapi/jsonreference/actions/workflows/codeql.yml + +[release-badge]: https://badge.fury.io/gh/go-openapi%2Fjsonreference.svg +[release-url]: https://badge.fury.io/gh/go-openapi%2Fjsonreference +[gomod-badge]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fjsonreference.svg +[gomod-url]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fjsonreference + +[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/jsonreference +[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/jsonreference +[codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/jsonreference +[codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/jsonreference + +[doc-badge]: https://img.shields.io/badge/doc-site-blue?link=https%3A%2F%2Fgoswagger.io%2Fgo-openapi%2F +[doc-url]: https://goswagger.io/go-openapi +[godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/jsonreference +[godoc-url]: http://pkg.go.dev/github.com/go-openapi/jsonreference +[discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue +[discord-url]: https://discord.gg/FfnFYaC3k5 + + +[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg +[license-url]: https://github.com/go-openapi/jsonreference/?tab=Apache-2.0-1-ov-file#readme + +[goversion-badge]: https://img.shields.io/github/go-mod/go-version/go-openapi/jsonreference +[goversion-url]: https://github.com/go-openapi/jsonreference/blob/master/go.mod +[top-badge]: https://img.shields.io/github/languages/top/go-openapi/jsonreference +[commits-badge]: https://img.shields.io/github/commits-since/go-openapi/jsonreference/latest + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/jsonreference/SECURITY.md b/vendor/github.com/go-openapi/jsonreference/SECURITY.md new file mode 100644 index 00000000..1fea2c57 --- /dev/null +++ b/vendor/github.com/go-openapi/jsonreference/SECURITY.md @@ -0,0 +1,37 @@ +# Security Policy + +This policy outlines the commitment and practices of the go-openapi maintainers regarding security. + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| O.x | :white_check_mark: | + +## Vulnerability checks in place + +This repository uses automated vulnerability scans, at every merged commit and at least once a week. + +We use: + +* [`GitHub CodeQL`][codeql-url] +* [`trivy`][trivy-url] +* [`govulncheck`][govulncheck-url] + +Reports are centralized in github security reports and visible only to the maintainers. + +## Reporting a vulnerability + +If you become aware of a security vulnerability that affects the current repository, +**please report it privately to the maintainers** +rather than opening a publicly visible GitHub issue. + +Please follow the instructions provided by github to [Privately report a security vulnerability][github-guidance-url]. + +> [!NOTE] +> On Github, navigate to the project's "Security" tab then click on "Report a vulnerability". + +[codeql-url]: https://github.com/github/codeql +[trivy-url]: https://trivy.dev/docs/latest/getting-started +[govulncheck-url]: https://go.dev/blog/govulncheck +[github-guidance-url]: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability diff --git a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go index f0610cf1..a08b4732 100644 --- a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go +++ b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package internal import ( @@ -11,9 +14,11 @@ const ( defaultHTTPSPort = ":443" ) -// Regular expressions used by the normalizations -var rxPort = regexp.MustCompile(`(:\d+)/?$`) -var rxDupSlashes = regexp.MustCompile(`/{2,}`) +// Regular expressions used by the normalizations. +var ( + rxPort = regexp.MustCompile(`(:\d+)/?$`) + rxDupSlashes = regexp.MustCompile(`/{2,}`) +) // NormalizeURL will normalize the specified URL // This was added to replace a previous call to the no longer maintained purell library: diff --git a/vendor/github.com/go-openapi/jsonreference/reference.go b/vendor/github.com/go-openapi/jsonreference/reference.go index cfdef03e..003ba7a8 100644 --- a/vendor/github.com/go-openapi/jsonreference/reference.go +++ b/vendor/github.com/go-openapi/jsonreference/reference.go @@ -1,27 +1,5 @@ -// Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) -// -// 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. - -// author sigu-399 -// author-github https://github.com/sigu-399 -// author-mail sigu.399@gmail.com -// -// repository-name jsonreference -// repository-desc An implementation of JSON Reference - Go language -// -// description Main and unique file. -// -// created 26-02-2013 +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 package jsonreference @@ -38,50 +16,51 @@ const ( fragmentRune = `#` ) -// New creates a new reference for the given string -func New(jsonReferenceString string) (Ref, error) { +// ErrChildURL is raised when there is no child. +var ErrChildURL = errors.New("child url is nil") + +// Ref represents a json reference object. +type Ref struct { + referenceURL *url.URL + referencePointer jsonpointer.Pointer + + HasFullURL bool + HasURLPathOnly bool + HasFragmentOnly bool + HasFileScheme bool + HasFullFilePath bool +} +// New creates a new reference for the given string. +func New(jsonReferenceString string) (Ref, error) { var r Ref err := r.parse(jsonReferenceString) return r, err - } // MustCreateRef parses the ref string and panics when it's invalid. -// Use the New method for a version that returns an error +// Use the New method for a version that returns an error. func MustCreateRef(ref string) Ref { r, err := New(ref) if err != nil { panic(err) } - return r -} -// Ref represents a json reference object -type Ref struct { - referenceURL *url.URL - referencePointer jsonpointer.Pointer - - HasFullURL bool - HasURLPathOnly bool - HasFragmentOnly bool - HasFileScheme bool - HasFullFilePath bool + return r } -// GetURL gets the URL for this reference +// GetURL gets the URL for this reference. func (r *Ref) GetURL() *url.URL { return r.referenceURL } -// GetPointer gets the json pointer for this reference +// GetPointer gets the json pointer for this reference. func (r *Ref) GetPointer() *jsonpointer.Pointer { return &r.referencePointer } -// String returns the best version of the url for this reference +// String returns the best version of the url for this reference. func (r *Ref) String() string { - if r.referenceURL != nil { return r.referenceURL.String() } @@ -93,7 +72,7 @@ func (r *Ref) String() string { return r.referencePointer.String() } -// IsRoot returns true if this reference is a root document +// IsRoot returns true if this reference is a root document. func (r *Ref) IsRoot() bool { return r.referenceURL != nil && !r.IsCanonical() && @@ -101,14 +80,32 @@ func (r *Ref) IsRoot() bool { r.referenceURL.Fragment == "" } -// IsCanonical returns true when this pointer starts with http(s):// or file:// +// IsCanonical returns true when this pointer starts with http(s):// or file://. func (r *Ref) IsCanonical() bool { return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullURL) } -// "Constructor", parses the given string JSON reference -func (r *Ref) parse(jsonReferenceString string) error { +// Inherits creates a new reference from a parent and a child +// If the child cannot inherit from the parent, an error is returned. +func (r *Ref) Inherits(child Ref) (*Ref, error) { + childURL := child.GetURL() + parentURL := r.GetURL() + if childURL == nil { + return nil, ErrChildURL + } + if parentURL == nil { + return &child, nil + } + + ref, err := New(parentURL.ResolveReference(childURL).String()) + if err != nil { + return nil, err + } + return &ref, nil +} +// "Constructor", parses the given string JSON reference. +func (r *Ref) parse(jsonReferenceString string) error { parsed, err := url.Parse(jsonReferenceString) if err != nil { return err @@ -137,22 +134,3 @@ func (r *Ref) parse(jsonReferenceString string) error { return nil } - -// Inherits creates a new reference from a parent and a child -// If the child cannot inherit from the parent, an error is returned -func (r *Ref) Inherits(child Ref) (*Ref, error) { - childURL := child.GetURL() - parentURL := r.GetURL() - if childURL == nil { - return nil, errors.New("child url is nil") - } - if parentURL == nil { - return &child, nil - } - - ref, err := New(parentURL.ResolveReference(childURL).String()) - if err != nil { - return nil, err - } - return &ref, nil -} diff --git a/vendor/github.com/go-openapi/swag/.codecov.yml b/vendor/github.com/go-openapi/swag/.codecov.yml new file mode 100644 index 00000000..3354f44b --- /dev/null +++ b/vendor/github.com/go-openapi/swag/.codecov.yml @@ -0,0 +1,4 @@ +ignore: + - jsonutils/fixtures_test + - jsonutils/adapters/ifaces/mocks + - jsonutils/adapters/testintegration/benchmarks diff --git a/vendor/github.com/go-openapi/swag/.gitignore b/vendor/github.com/go-openapi/swag/.gitignore index c4b1b64f..3ceb596f 100644 --- a/vendor/github.com/go-openapi/swag/.gitignore +++ b/vendor/github.com/go-openapi/swag/.gitignore @@ -3,3 +3,5 @@ vendor Godeps .idea *.out +.mcp.json +.worktrees diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml index d2fafb8a..099c0a78 100644 --- a/vendor/github.com/go-openapi/swag/.golangci.yml +++ b/vendor/github.com/go-openapi/swag/.golangci.yml @@ -1,56 +1,81 @@ -linters-settings: - gocyclo: - min-complexity: 45 - dupl: - threshold: 200 - goconst: - min-len: 2 - min-occurrences: 3 - +version: "2" linters: - enable-all: true + default: all disable: - - recvcheck - - unparam - - lll - - gochecknoinits - - gochecknoglobals + - cyclop + - depguard + - errchkjson + - errorlint + - exhaustruct + - forcetypeassert - funlen - - godox + - gochecknoglobals + - gochecknoinits - gocognit - - whitespace - - wsl - - wrapcheck - - testpackage - - nlreturn - - errorlint - - nestif - godot - - gofumpt + - godox + - goconst + - gomoddirectives + - gomodguard + - gomodguard_v2 + - gosmopolitan + - inamedparam + - intrange + - ireturn + - lll + - musttag + - modernize + - nestif + - nlreturn + - nonamedreturns + - noinlineerr - paralleltest - - tparallel + - recvcheck + - testpackage - thelper - - exhaustruct + - tagliatelle + - tparallel + - unparam - varnamelen - - gci - - depguard - - errchkjson - - inamedparam - - nonamedreturns - - musttag - - ireturn - - forcetypeassert - - cyclop - # deprecated linters - #- deadcode - #- interfacer - #- scopelint - #- varcheck - #- structcheck - #- golint - #- nosnakecase - #- maligned - #- goerr113 - #- ifshort - #- gomnd - #- exhaustivestruct + - whitespace + - wrapcheck + - wsl + - wsl_v5 + settings: + dupl: + threshold: 200 + goconst: + min-len: 2 + min-occurrences: 3 + gocyclo: + min-complexity: 45 + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + - goimports + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ +issues: + # Maximum issues count per one linter. + # Set to 0 to disable. + # Default: 50 + max-issues-per-linter: 0 + # Maximum count of issues with the same text. + # Set to 0 to disable. + # Default: 3 + max-same-issues: 0 diff --git a/vendor/github.com/go-openapi/swag/.mockery.yml b/vendor/github.com/go-openapi/swag/.mockery.yml new file mode 100644 index 00000000..8557cb58 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/.mockery.yml @@ -0,0 +1,30 @@ +all: false +dir: '{{.InterfaceDir}}' +filename: mocks_test.go +force-file-write: true +formatter: goimports +include-auto-generated: false +log-level: info +structname: '{{.Mock}}{{.InterfaceName}}' +pkgname: '{{.SrcPackageName}}' +recursive: false +require-template-schema-exists: true +template: matryer +template-schema: '{{.Template}}.schema.json' +packages: + github.com/go-openapi/swag/jsonutils/adapters/ifaces: + config: + dir: jsonutils/adapters/ifaces/mocks + filename: mocks.go + pkgname: 'mocks' + force-file-write: true + all: true + github.com/go-openapi/swag/jsonutils/adapters/testintegration: + config: + inpackage: true + dir: jsonutils/adapters/testintegration + force-file-write: true + all: true + interfaces: + EJMarshaler: + EJUnmarshaler: diff --git a/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md b/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md index 9322b065..bac878f2 100644 --- a/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md +++ b/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md @@ -23,7 +23,9 @@ include: Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or + advances + * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic @@ -55,7 +57,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at ivan+abuse@flanders.co.nz. All +reported by contacting the project team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. @@ -68,7 +70,7 @@ members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] +available at [][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/go-openapi/swag/CONTRIBUTORS.md b/vendor/github.com/go-openapi/swag/CONTRIBUTORS.md new file mode 100644 index 00000000..0f0711cd --- /dev/null +++ b/vendor/github.com/go-openapi/swag/CONTRIBUTORS.md @@ -0,0 +1,36 @@ +# Contributors + +- Repository: ['go-openapi/swag'] + +| Total Contributors | Total Contributions | +| --- | --- | +| 24 | 251 | + +| Username | All Time Contribution Count | All Commits | +| --- | --- | --- | +| @fredbi | 121 | | +| @casualjim | 98 | | +| @alexandear | 4 | | +| @orisano | 3 | | +| @reinerRubin | 2 | | +| @n-inja | 2 | | +| @nitinmohan87 | 2 | | +| @Neo2308 | 2 | | +| @michaelbowler-form3 | 2 | | +| @ujjwalsh | 1 | | +| @griffin-stewie | 1 | | +| @POD666 | 1 | | +| @pytlesk4 | 1 | | +| @shirou | 1 | | +| @seanprince | 1 | | +| @petrkotas | 1 | | +| @mszczygiel | 1 | | +| @sosiska | 1 | | +| @kzys | 1 | | +| @faguirre1 | 1 | | +| @posener | 1 | | +| @diego-fu-hs | 1 | | +| @davidalpert | 1 | | +| @Xe | 1 | | + + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/swag/README.md b/vendor/github.com/go-openapi/swag/README.md index a7292229..c6c2d21e 100644 --- a/vendor/github.com/go-openapi/swag/README.md +++ b/vendor/github.com/go-openapi/swag/README.md @@ -1,23 +1,223 @@ -# Swag [![Build Status](https://github.com/go-openapi/swag/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) +# Swag -[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE) -[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/swag.svg)](https://pkg.go.dev/github.com/go-openapi/swag) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag) + +[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vuln scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url] + + + +[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] + + +[![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] -Contains a bunch of helper functions for go-openapi and go-swagger projects. +--- + +A bunch of helper functions for go-openapi and go-swagger projects. You may also use it standalone for your projects. -* convert between value and pointers for builtin types -* convert from string to builtin types (wraps strconv) -* fast json concatenation -* search in path -* load from file or http -* name mangling +> **NOTE** +> `swag` is one of the foundational building blocks of the go-openapi initiative. +> +> Most repositories in `github.com/go-openapi/...` depend on it in some way. +> And so does our CLI tool `github.com/go-swagger/go-swagger`, +> as well as the code generated by this tool. + +* [Contents](#contents) +* [Dependencies](#dependencies) +* [Change log](#change-log) +* [Licensing](#licensing) +* [Note to contributors](#note-to-contributors) +* [Roadmap](#roadmap) + +## Announcements + +* **2025-12-19** : new community chat on discord + * a new discord community channel is available to be notified of changes and support users + +You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] + +## Status + +API is stable. + +## Import this library in your project + +```cmd +go get github.com/go-openapi/swag/{module} +``` + +Or for backward compatibility: + +```cmd +go get github.com/go-openapi/swag +``` + +## Contents + +`go-openapi/swag` exposes a collection of relatively independent modules. + +Moving forward, no additional feature will be added to the `swag` API directly at the root package level, +which remains there for backward-compatibility purposes. All exported top-level features are now deprecated. + +Child modules will continue to evolve and some new ones may be added in the future. + +| Module | Content | Main features | +|---------------|---------|---------------| +| `cmdutils` | utilities to work with CLIs || +| `conv` | type conversion utilities | convert between values and pointers for any types
convert from string to builtin types (wraps `strconv`)
require `./typeutils` (test dependency)
| +| `fileutils` | file utilities | | +| `jsonname` | JSON utilities (deprecated) | infer JSON names from `go` properties
use `github.com/go-openapi/jsonpointer/jsonname` instead | +| `jsonutils` | JSON utilities | fast json concatenation
read and write JSON from and to dynamic `go` data structures
~require `github.com/mailru/easyjson`~
| +| `loading` | file loading | load from file or http
require `./yamlutils`
| +| `mangling` | safe name generation | name mangling for `go`
| +| `netutils` | networking utilities | host, port from address
| +| `pools` | utilities to work with sync.Pools | | +| `stringutils` | `string` utilities | search in slice (with case-insensitive)
split/join query parameters as arrays
| +| `typeutils` | `go` types utilities | check the zero value for any type
safe check for a nil value
| +| `yamlutils` | YAML utilities | converting YAML to JSON
loading YAML into a dynamic YAML document
maintaining the original order of keys in YAML objects
require `./jsonutils`
~require `github.com/mailru/easyjson`~
require `go.yaml.in/yaml/v3`
| + +--- + +## Dependencies + +The root module `github.com/go-openapi/swag` at the repo level maintains a few +dependencies outside of the standard library. + +* YAML utilities depend on `go.yaml.in/yaml/v3` +* JSON utilities depend on their registered adapter module: + * by default, only the standard library is used + * `github.com/mailru/easyjson` is now only a dependency for module + `github.com/go-openapi/swag/jsonutils/adapters/easyjson/json`, + for users willing to import that module. + * integration tests and benchmarks use all the dependencies are published as their own module +* other dependencies are test dependencies drawn from `github.com/stretchr/testify` + +## Usage + +**How to explicitly register a dependency at runtime**? + +The following would maintain how JSON utilities proposed by `swag` used work, up to `v0.24.1`. + + ```go + import ( + "github.com/go-openapi/swag/jsonutils/adapters" + easyjson "github.com/go-openapi/swag/jsonutils/adapters/easyjson/json" + ) + + func init() { + easyjson.Register(adapters.Registry) + } + ``` + +Subsequent calls to `jsonutils.ReadJSON()` or `jsonutils.WriteJSON()` will switch to `easyjson` +whenever the passed data structures implement the `easyjson.Unmarshaler` or `easyjson.Marshaler` respectively, +or fallback to the standard library. + +For more details, you may also look at our +[integration tests](jsonutils/adapters/testintegration/integration_suite_test.go#29). + +--- + +## Note to contributors + +All kinds of contributions are welcome. + +This repo is a go mono-repo. See [docs](docs/MAINTAINERS.md). + +More general guidelines are available [here](.github/CONTRIBUTING.md). + +## Roadmap + +See the current [TODO list](docs/TODOS.md) + +## Change log + +See + +For pre-v0.26.0 releases, see [release notes](./docs/NOTES.md). + +**What coming next?** + +Moving forward, we want to : + +* provide an implementation of the JSON adapter based on `encoding/json/v2`, for `go1.25` builds. +* provide similar implementations for `goccy/go-json` and `jsoniterator/go`, and perhaps some other + similar libraries may be interesting too. + + + +## Licensing + +This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE). + + + + + +## Other documentation + +* [All-time contributors](./CONTRIBUTORS.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] + +## Cutting a new release + +Maintainers can cut a new release by either: +* running [this workflow](https://github.com/go-openapi/swag/actions/workflows/bump-release.yml) +* or pushing a semver tag + * signed tags are preferred + * The tag message is prepended to release notes -This repo has only few dependencies outside of the standard library: + +[test-badge]: https://github.com/go-openapi/swag/actions/workflows/go-test.yml/badge.svg +[test-url]: https://github.com/go-openapi/swag/actions/workflows/go-test.yml +[cov-badge]: https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg +[cov-url]: https://codecov.io/gh/go-openapi/swag +[vuln-scan-badge]: https://github.com/go-openapi/swag/actions/workflows/scanner.yml/badge.svg +[vuln-scan-url]: https://github.com/go-openapi/swag/actions/workflows/scanner.yml +[codeql-badge]: https://github.com/go-openapi/swag/actions/workflows/codeql.yml/badge.svg +[codeql-url]: https://github.com/go-openapi/swag/actions/workflows/codeql.yml + +[release-badge]: https://badge.fury.io/gh/go-openapi%2Fswag.svg +[release-url]: https://badge.fury.io/gh/go-openapi%2Fswag +[gomod-badge]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fswag.svg +[gomod-url]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fswag + +[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/swag +[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/swag +[codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/swag +[codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/swag + +[doc-badge]: https://img.shields.io/badge/doc-site-blue?link=https%3A%2F%2Fgoswagger.io%2Fgo-openapi%2F +[doc-url]: https://goswagger.io/go-openapi +[godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/swag +[godoc-url]: http://pkg.go.dev/github.com/go-openapi/swag +[discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue +[discord-url]: https://discord.gg/FfnFYaC3k5 -* YAML utilities depend on `gopkg.in/yaml.v3` -* `github.com/mailru/easyjson v0.7.7` + +[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg +[license-url]: https://github.com/go-openapi/swag/?tab=Apache-2.0-1-ov-file#readme + +[goversion-badge]: https://img.shields.io/github/go-mod/go-version/go-openapi/swag +[goversion-url]: https://github.com/go-openapi/swag/blob/master/go.mod +[top-badge]: https://img.shields.io/github/languages/top/go-openapi/swag +[commits-badge]: https://img.shields.io/github/commits-since/go-openapi/swag/latest + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/swag/SECURITY.md b/vendor/github.com/go-openapi/swag/SECURITY.md new file mode 100644 index 00000000..1fea2c57 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/SECURITY.md @@ -0,0 +1,37 @@ +# Security Policy + +This policy outlines the commitment and practices of the go-openapi maintainers regarding security. + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| O.x | :white_check_mark: | + +## Vulnerability checks in place + +This repository uses automated vulnerability scans, at every merged commit and at least once a week. + +We use: + +* [`GitHub CodeQL`][codeql-url] +* [`trivy`][trivy-url] +* [`govulncheck`][govulncheck-url] + +Reports are centralized in github security reports and visible only to the maintainers. + +## Reporting a vulnerability + +If you become aware of a security vulnerability that affects the current repository, +**please report it privately to the maintainers** +rather than opening a publicly visible GitHub issue. + +Please follow the instructions provided by github to [Privately report a security vulnerability][github-guidance-url]. + +> [!NOTE] +> On Github, navigate to the project's "Security" tab then click on "Report a vulnerability". + +[codeql-url]: https://github.com/github/codeql +[trivy-url]: https://trivy.dev/docs/latest/getting-started +[govulncheck-url]: https://go.dev/blog/govulncheck +[github-guidance-url]: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability diff --git a/vendor/github.com/go-openapi/swag/cmdutils/LICENSE b/vendor/github.com/go-openapi/swag/cmdutils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/cmdutils/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/cmdutils/cmd_utils.go b/vendor/github.com/go-openapi/swag/cmdutils/cmd_utils.go new file mode 100644 index 00000000..6c7bbb26 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/cmdutils/cmd_utils.go @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package cmdutils + +// CommandLineOptionsGroup represents a group of user-defined command line options. +// +// This is for instance used to configure command line arguments in API servers generated by go-swagger. +type CommandLineOptionsGroup struct { + ShortDescription string + LongDescription string + Options any +} diff --git a/vendor/github.com/go-openapi/swag/cmdutils/doc.go b/vendor/github.com/go-openapi/swag/cmdutils/doc.go new file mode 100644 index 00000000..31f2c375 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/cmdutils/doc.go @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package cmdutils brings helpers for CLIs produced by go-openapi +package cmdutils diff --git a/vendor/github.com/go-openapi/swag/cmdutils_iface.go b/vendor/github.com/go-openapi/swag/cmdutils_iface.go new file mode 100644 index 00000000..bd0c1fc1 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/cmdutils_iface.go @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import "github.com/go-openapi/swag/cmdutils" + +// CommandLineOptionsGroup represents a group of user-defined command line options. +// +// Deprecated: use [cmdutils.CommandLineOptionsGroup] instead. +type CommandLineOptionsGroup = cmdutils.CommandLineOptionsGroup diff --git a/vendor/github.com/go-openapi/swag/conv/LICENSE b/vendor/github.com/go-openapi/swag/conv/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/conv/convert.go b/vendor/github.com/go-openapi/swag/conv/convert.go new file mode 100644 index 00000000..f205c391 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv/convert.go @@ -0,0 +1,161 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package conv + +import ( + "math" + "strconv" + "strings" +) + +// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER +const ( + maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1 + minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1 + epsilon float64 = 1e-9 +) + +// IsFloat64AJSONInteger allows for integers [-2^53, 2^53-1] inclusive. +func IsFloat64AJSONInteger(f float64) bool { + if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat { + return false + } + rounded := math.Round(f) + if f == rounded { + return true + } + if rounded == 0 { // f = 0.0 exited above + return false + } + + diff := math.Abs(f - rounded) + if diff == 0 { + return true + } + + // relative error Abs{f - Round(f)) / Round(f)} < ε ; Round(f) + return diff < epsilon*math.Abs(rounded) +} + +// ConvertFloat turns a string into a float numerical value. +func ConvertFloat[T Float](str string) (T, error) { + var v T + f, err := strconv.ParseFloat(str, bitsize(v)) + if err != nil { + return 0, err + } + + return T(f), nil +} + +// ConvertInteger turns a string into a signed integer. +func ConvertInteger[T Signed](str string) (T, error) { + var v T + f, err := strconv.ParseInt(str, 10, bitsize(v)) + if err != nil { + return 0, err + } + + return T(f), nil +} + +// ConvertUinteger turns a string into an unsigned integer. +func ConvertUinteger[T Unsigned](str string) (T, error) { + var v T + f, err := strconv.ParseUint(str, 10, bitsize(v)) + if err != nil { + return 0, err + } + + return T(f), nil +} + +// ConvertBool turns a string into a boolean. +// +// It supports a few more "true" strings than [strconv.ParseBool]: +// +// - it is not case sensitive ("trUe" or "FalsE" work) +// - "ok", "yes", "y", "on", "selected", "checked", "enabled" are all true +// - everything that is not true is false: there is never an actual error returned +func ConvertBool(str string) (bool, error) { + switch strings.ToLower(str) { + case "true", + "1", + "yes", + "ok", + "y", + "on", + "selected", + "checked", + "t", + "enabled": + return true, nil + default: + return false, nil + } +} + +// ConvertFloat32 turns a string into a float32. +func ConvertFloat32(str string) (float32, error) { return ConvertFloat[float32](str) } + +// ConvertFloat64 turns a string into a float64 +func ConvertFloat64(str string) (float64, error) { return ConvertFloat[float64](str) } + +// ConvertInt8 turns a string into an int8 +func ConvertInt8(str string) (int8, error) { return ConvertInteger[int8](str) } + +// ConvertInt16 turns a string into an int16 +func ConvertInt16(str string) (int16, error) { + i, err := strconv.ParseInt(str, 10, 16) + if err != nil { + return 0, err + } + return int16(i), nil +} + +// ConvertInt32 turns a string into an int32 +func ConvertInt32(str string) (int32, error) { + i, err := strconv.ParseInt(str, 10, 32) + if err != nil { + return 0, err + } + return int32(i), nil +} + +// ConvertInt64 turns a string into an int64 +func ConvertInt64(str string) (int64, error) { + return strconv.ParseInt(str, 10, 64) +} + +// ConvertUint8 turns a string into an uint8 +func ConvertUint8(str string) (uint8, error) { + i, err := strconv.ParseUint(str, 10, 8) + if err != nil { + return 0, err + } + return uint8(i), nil +} + +// ConvertUint16 turns a string into an uint16 +func ConvertUint16(str string) (uint16, error) { + i, err := strconv.ParseUint(str, 10, 16) + if err != nil { + return 0, err + } + return uint16(i), nil +} + +// ConvertUint32 turns a string into an uint32 +func ConvertUint32(str string) (uint32, error) { + i, err := strconv.ParseUint(str, 10, 32) + if err != nil { + return 0, err + } + return uint32(i), nil +} + +// ConvertUint64 turns a string into an uint64 +func ConvertUint64(str string) (uint64, error) { + return strconv.ParseUint(str, 10, 64) +} diff --git a/vendor/github.com/go-openapi/swag/conv/convert_types.go b/vendor/github.com/go-openapi/swag/conv/convert_types.go new file mode 100644 index 00000000..cf4c6495 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv/convert_types.go @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package conv + +// Unlicensed credits (idea, concept) +// +// The idea to convert values to pointers and the other way around, was inspired, eons ago, by the aws go sdk. +// +// Nowadays, all sensible API sdk's expose a similar functionality. + +// Pointer returns a pointer to the value passed in. +func Pointer[T any](v T) *T { + return &v +} + +// Value returns a shallow copy of the value of the pointer passed in. +// +// If the pointer is nil, the returned value is the zero value. +func Value[T any](v *T) T { + if v != nil { + return *v + } + + var zero T + return zero +} + +// PointerSlice converts a slice of values into a slice of pointers. +func PointerSlice[T any](src []T) []*T { + dst := make([]*T, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// ValueSlice converts a slice of pointers into a slice of values. +// +// nil elements are zero values. +func ValueSlice[T any](src []*T) []T { + dst := make([]T, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// PointerMap converts a map of values into a map of pointers. +func PointerMap[K comparable, T any](src map[K]T) map[K]*T { + dst := make(map[K]*T) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// ValueMap converts a map of pointers into a map of values. +// +// nil elements are skipped. +func ValueMap[K comparable, T any](src map[K]*T) map[K]T { + dst := make(map[K]T) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} diff --git a/vendor/github.com/go-openapi/swag/conv/doc.go b/vendor/github.com/go-openapi/swag/conv/doc.go new file mode 100644 index 00000000..1bd6ead6 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv/doc.go @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package conv exposes utilities to convert types. +// +// The Convert and Format families of functions are essentially a shorthand to [strconv] functions, +// using the decimal representation of numbers. +// +// Features: +// +// - from string representation to value ("Convert*") and reciprocally ("Format*") +// - from pointer to value ([Value]) and reciprocally ([Pointer]) +// - from slice of values to slice of pointers ([PointerSlice]) and reciprocally ([ValueSlice]) +// - from map of values to map of pointers ([PointerMap]) and reciprocally ([ValueMap]) +package conv diff --git a/vendor/github.com/go-openapi/swag/conv/format.go b/vendor/github.com/go-openapi/swag/conv/format.go new file mode 100644 index 00000000..5b87b8e1 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv/format.go @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package conv + +import ( + "strconv" +) + +// FormatInteger turns an integer type into a string. +func FormatInteger[T Signed](value T) string { + return strconv.FormatInt(int64(value), 10) +} + +// FormatUinteger turns an unsigned integer type into a string. +func FormatUinteger[T Unsigned](value T) string { + return strconv.FormatUint(uint64(value), 10) +} + +// FormatFloat turns a floating point numerical value into a string. +func FormatFloat[T Float](value T) string { + return strconv.FormatFloat(float64(value), 'f', -1, bitsize(value)) +} + +// FormatBool turns a boolean into a string. +func FormatBool(value bool) string { + return strconv.FormatBool(value) +} diff --git a/vendor/github.com/go-openapi/swag/conv/sizeof.go b/vendor/github.com/go-openapi/swag/conv/sizeof.go new file mode 100644 index 00000000..49434655 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv/sizeof.go @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package conv + +import "unsafe" + +// bitsize returns the size in bits of a type. +// +// NOTE: [unsafe.SizeOf] simply returns the size in bytes of the value. +// For primitive types T, the generic stencil is precompiled and this value +// is resolved at compile time, resulting in an immediate call to [strconv.ParseFloat]. +// +// We may leave up to the go compiler to simplify this function into a +// constant value, which happens in practice at least for primitive types +// (e.g. numerical types). +func bitsize[T Numerical](value T) int { + const bitsPerByte = 8 + return int(unsafe.Sizeof(value)) * bitsPerByte +} diff --git a/vendor/github.com/go-openapi/swag/conv/type_constraints.go b/vendor/github.com/go-openapi/swag/conv/type_constraints.go new file mode 100644 index 00000000..81135e82 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv/type_constraints.go @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package conv + +type ( + // these type constraints are redefined after golang.org/x/exp/constraints, + // because importing that package causes an undesired go upgrade. + + // Signed integer types, cf. [golang.org/x/exp/constraints.Signed] + Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 + } + + // Unsigned integer types, cf. [golang.org/x/exp/constraints.Unsigned] + Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr + } + + // Float numerical types, cf. [golang.org/x/exp/constraints.Float] + Float interface { + ~float32 | ~float64 + } + + // Numerical types + Numerical interface { + Signed | Unsigned | Float + } +) diff --git a/vendor/github.com/go-openapi/swag/conv_iface.go b/vendor/github.com/go-openapi/swag/conv_iface.go new file mode 100644 index 00000000..eea7b2e5 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/conv_iface.go @@ -0,0 +1,486 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import ( + "time" + + "github.com/go-openapi/swag/conv" +) + +// IsFloat64AJSONInteger allows for integers [-2^53, 2^53-1] inclusive. +// +// Deprecated: use [conv.IsFloat64AJSONInteger] instead. +func IsFloat64AJSONInteger(f float64) bool { return conv.IsFloat64AJSONInteger(f) } + +// ConvertBool turns a string into a boolean. +// +// Deprecated: use [conv.ConvertBool] instead. +func ConvertBool(str string) (bool, error) { return conv.ConvertBool(str) } + +// ConvertFloat32 turns a string into a float32. +// +// Deprecated: use [conv.ConvertFloat32] instead. Alternatively, you may use the generic version [conv.ConvertFloat]. +func ConvertFloat32(str string) (float32, error) { return conv.ConvertFloat[float32](str) } + +// ConvertFloat64 turns a string into a float64. +// +// Deprecated: use [conv.ConvertFloat64] instead. Alternatively, you may use the generic version [conv.ConvertFloat]. +func ConvertFloat64(str string) (float64, error) { return conv.ConvertFloat[float64](str) } + +// ConvertInt8 turns a string into an int8. +// +// Deprecated: use [conv.ConvertInt8] instead. Alternatively, you may use the generic version [conv.ConvertInteger]. +func ConvertInt8(str string) (int8, error) { return conv.ConvertInteger[int8](str) } + +// ConvertInt16 turns a string into an int16. +// +// Deprecated: use [conv.ConvertInt16] instead. Alternatively, you may use the generic version [conv.ConvertInteger]. +func ConvertInt16(str string) (int16, error) { return conv.ConvertInteger[int16](str) } + +// ConvertInt32 turns a string into an int32. +// +// Deprecated: use [conv.ConvertInt32] instead. Alternatively, you may use the generic version [conv.ConvertInteger]. +func ConvertInt32(str string) (int32, error) { return conv.ConvertInteger[int32](str) } + +// ConvertInt64 turns a string into an int64. +// +// Deprecated: use [conv.ConvertInt64] instead. Alternatively, you may use the generic version [conv.ConvertInteger]. +func ConvertInt64(str string) (int64, error) { return conv.ConvertInteger[int64](str) } + +// ConvertUint8 turns a string into an uint8. +// +// Deprecated: use [conv.ConvertUint8] instead. Alternatively, you may use the generic version [conv.ConvertUinteger]. +func ConvertUint8(str string) (uint8, error) { return conv.ConvertUinteger[uint8](str) } + +// ConvertUint16 turns a string into an uint16. +// +// Deprecated: use [conv.ConvertUint16] instead. Alternatively, you may use the generic version [conv.ConvertUinteger]. +func ConvertUint16(str string) (uint16, error) { return conv.ConvertUinteger[uint16](str) } + +// ConvertUint32 turns a string into an uint32. +// +// Deprecated: use [conv.ConvertUint32] instead. Alternatively, you may use the generic version [conv.ConvertUinteger]. +func ConvertUint32(str string) (uint32, error) { return conv.ConvertUinteger[uint32](str) } + +// ConvertUint64 turns a string into an uint64. +// +// Deprecated: use [conv.ConvertUint64] instead. Alternatively, you may use the generic version [conv.ConvertUinteger]. +func ConvertUint64(str string) (uint64, error) { return conv.ConvertUinteger[uint64](str) } + +// FormatBool turns a boolean into a string. +// +// Deprecated: use [conv.FormatBool] instead. +func FormatBool(value bool) string { return conv.FormatBool(value) } + +// FormatFloat32 turns a float32 into a string. +// +// Deprecated: use [conv.FormatFloat] instead. +func FormatFloat32(value float32) string { return conv.FormatFloat(value) } + +// FormatFloat64 turns a float64 into a string. +// +// Deprecated: use [conv.FormatFloat] instead. +func FormatFloat64(value float64) string { return conv.FormatFloat(value) } + +// FormatInt8 turns an int8 into a string. +// +// Deprecated: use [conv.FormatInteger] instead. +func FormatInt8(value int8) string { return conv.FormatInteger(value) } + +// FormatInt16 turns an int16 into a string. +// +// Deprecated: use [conv.FormatInteger] instead. +func FormatInt16(value int16) string { return conv.FormatInteger(value) } + +// FormatInt32 turns an int32 into a string +// +// Deprecated: use [conv.FormatInteger] instead. +func FormatInt32(value int32) string { return conv.FormatInteger(value) } + +// FormatInt64 turns an int64 into a string. +// +// Deprecated: use [conv.FormatInteger] instead. +func FormatInt64(value int64) string { return conv.FormatInteger(value) } + +// FormatUint8 turns an uint8 into a string. +// +// Deprecated: use [conv.FormatUinteger] instead. +func FormatUint8(value uint8) string { return conv.FormatUinteger(value) } + +// FormatUint16 turns an uint16 into a string. +// +// Deprecated: use [conv.FormatUinteger] instead. +func FormatUint16(value uint16) string { return conv.FormatUinteger(value) } + +// FormatUint32 turns an uint32 into a string. +// +// Deprecated: use [conv.FormatUinteger] instead. +func FormatUint32(value uint32) string { return conv.FormatUinteger(value) } + +// FormatUint64 turns an uint64 into a string. +// +// Deprecated: use [conv.FormatUinteger] instead. +func FormatUint64(value uint64) string { return conv.FormatUinteger(value) } + +// String turn a pointer to of the string value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func String(v string) *string { return conv.Pointer(v) } + +// StringValue turn the value of the string pointer passed in or +// "" if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func StringValue(v *string) string { return conv.Value(v) } + +// StringSlice converts a slice of string values into a slice of string pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func StringSlice(src []string) []*string { return conv.PointerSlice(src) } + +// StringValueSlice converts a slice of string pointers into a slice of string values. +// +// Deprecated: use [conv.ValueSlice] instead. +func StringValueSlice(src []*string) []string { return conv.ValueSlice(src) } + +// StringMap converts a string map of string values into a string map of string pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func StringMap(src map[string]string) map[string]*string { return conv.PointerMap(src) } + +// StringValueMap converts a string map of string pointers into a string map of string values. +// +// Deprecated: use [conv.ValueMap] instead. +func StringValueMap(src map[string]*string) map[string]string { return conv.ValueMap(src) } + +// Bool turn a pointer to of the bool value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Bool(v bool) *bool { return conv.Pointer(v) } + +// BoolValue turn the value of the bool pointer passed in or false if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func BoolValue(v *bool) bool { return conv.Value(v) } + +// BoolSlice converts a slice of bool values into a slice of bool pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func BoolSlice(src []bool) []*bool { return conv.PointerSlice(src) } + +// BoolValueSlice converts a slice of bool pointers into a slice of bool values. +// +// Deprecated: use [conv.ValueSlice] instead. +func BoolValueSlice(src []*bool) []bool { return conv.ValueSlice(src) } + +// BoolMap converts a string map of bool values into a string map of bool pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func BoolMap(src map[string]bool) map[string]*bool { return conv.PointerMap(src) } + +// BoolValueMap converts a string map of bool pointers into a string map of bool values. +// +// Deprecated: use [conv.ValueMap] instead. +func BoolValueMap(src map[string]*bool) map[string]bool { return conv.ValueMap(src) } + +// Int turn a pointer to of the int value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Int(v int) *int { return conv.Pointer(v) } + +// IntValue turn the value of the int pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func IntValue(v *int) int { return conv.Value(v) } + +// IntSlice converts a slice of int values into a slice of int pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func IntSlice(src []int) []*int { return conv.PointerSlice(src) } + +// IntValueSlice converts a slice of int pointers into a slice of int values. +// +// Deprecated: use [conv.ValueSlice] instead. +func IntValueSlice(src []*int) []int { return conv.ValueSlice(src) } + +// IntMap converts a string map of int values into a string map of int pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func IntMap(src map[string]int) map[string]*int { return conv.PointerMap(src) } + +// IntValueMap converts a string map of int pointers into a string map of int values. +// +// Deprecated: use [conv.ValueMap] instead. +func IntValueMap(src map[string]*int) map[string]int { return conv.ValueMap(src) } + +// Int32 turn a pointer to of the int32 value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Int32(v int32) *int32 { return conv.Pointer(v) } + +// Int32Value turn the value of the int32 pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func Int32Value(v *int32) int32 { return conv.Value(v) } + +// Int32Slice converts a slice of int32 values into a slice of int32 pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func Int32Slice(src []int32) []*int32 { return conv.PointerSlice(src) } + +// Int32ValueSlice converts a slice of int32 pointers into a slice of int32 values. +// +// Deprecated: use [conv.ValueSlice] instead. +func Int32ValueSlice(src []*int32) []int32 { return conv.ValueSlice(src) } + +// Int32Map converts a string map of int32 values into a string map of int32 pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func Int32Map(src map[string]int32) map[string]*int32 { return conv.PointerMap(src) } + +// Int32ValueMap converts a string map of int32 pointers into a string map of int32 values. +// +// Deprecated: use [conv.ValueMap] instead. +func Int32ValueMap(src map[string]*int32) map[string]int32 { return conv.ValueMap(src) } + +// Int64 turn a pointer to of the int64 value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Int64(v int64) *int64 { return conv.Pointer(v) } + +// Int64Value turn the value of the int64 pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func Int64Value(v *int64) int64 { return conv.Value(v) } + +// Int64Slice converts a slice of int64 values into a slice of int64 pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func Int64Slice(src []int64) []*int64 { return conv.PointerSlice(src) } + +// Int64ValueSlice converts a slice of int64 pointers into a slice of int64 values. +// +// Deprecated: use [conv.ValueSlice] instead. +func Int64ValueSlice(src []*int64) []int64 { return conv.ValueSlice(src) } + +// Int64Map converts a string map of int64 values into a string map of int64 pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func Int64Map(src map[string]int64) map[string]*int64 { return conv.PointerMap(src) } + +// Int64ValueMap converts a string map of int64 pointers into a string map of int64 values. +// +// Deprecated: use [conv.ValueMap] instead. +func Int64ValueMap(src map[string]*int64) map[string]int64 { return conv.ValueMap(src) } + +// Uint16 turn a pointer to of the uint16 value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Uint16(v uint16) *uint16 { return conv.Pointer(v) } + +// Uint16Value turn the value of the uint16 pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func Uint16Value(v *uint16) uint16 { return conv.Value(v) } + +// Uint16Slice converts a slice of uint16 values into a slice of uint16 pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func Uint16Slice(src []uint16) []*uint16 { return conv.PointerSlice(src) } + +// Uint16ValueSlice converts a slice of uint16 pointers into a slice of uint16 values. +// +// Deprecated: use [conv.ValueSlice] instead. +func Uint16ValueSlice(src []*uint16) []uint16 { return conv.ValueSlice(src) } + +// Uint16Map converts a string map of uint16 values into a string map of uint16 pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func Uint16Map(src map[string]uint16) map[string]*uint16 { return conv.PointerMap(src) } + +// Uint16ValueMap converts a string map of uint16 pointers into a string map of uint16 values. +// +// Deprecated: use [conv.ValueMap] instead. +func Uint16ValueMap(src map[string]*uint16) map[string]uint16 { return conv.ValueMap(src) } + +// Uint turn a pointer to of the uint value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Uint(v uint) *uint { return conv.Pointer(v) } + +// UintValue turn the value of the uint pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func UintValue(v *uint) uint { return conv.Value(v) } + +// UintSlice converts a slice of uint values into a slice of uint pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func UintSlice(src []uint) []*uint { return conv.PointerSlice(src) } + +// UintValueSlice converts a slice of uint pointers into a slice of uint values. +// +// Deprecated: use [conv.ValueSlice] instead. +func UintValueSlice(src []*uint) []uint { return conv.ValueSlice(src) } + +// UintMap converts a string map of uint values into a string map of uint pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func UintMap(src map[string]uint) map[string]*uint { return conv.PointerMap(src) } + +// UintValueMap converts a string map of uint pointers into a string map of uint values. +// +// Deprecated: use [conv.ValueMap] instead. +func UintValueMap(src map[string]*uint) map[string]uint { return conv.ValueMap(src) } + +// Uint32 turn a pointer to of the uint32 value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Uint32(v uint32) *uint32 { return conv.Pointer(v) } + +// Uint32Value turn the value of the uint32 pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func Uint32Value(v *uint32) uint32 { return conv.Value(v) } + +// Uint32Slice converts a slice of uint32 values into a slice of uint32 pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func Uint32Slice(src []uint32) []*uint32 { return conv.PointerSlice(src) } + +// Uint32ValueSlice converts a slice of uint32 pointers into a slice of uint32 values. +// +// Deprecated: use [conv.ValueSlice] instead. +func Uint32ValueSlice(src []*uint32) []uint32 { return conv.ValueSlice(src) } + +// Uint32Map converts a string map of uint32 values into a string map of uint32 pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func Uint32Map(src map[string]uint32) map[string]*uint32 { return conv.PointerMap(src) } + +// Uint32ValueMap converts a string map of uint32 pointers into a string map of uint32 values. +// +// Deprecated: use [conv.ValueMap] instead. +func Uint32ValueMap(src map[string]*uint32) map[string]uint32 { return conv.ValueMap(src) } + +// Uint64 turn a pointer to of the uint64 value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Uint64(v uint64) *uint64 { return conv.Pointer(v) } + +// Uint64Value turn the value of the uint64 pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func Uint64Value(v *uint64) uint64 { return conv.Value(v) } + +// Uint64Slice converts a slice of uint64 values into a slice of uint64 pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func Uint64Slice(src []uint64) []*uint64 { return conv.PointerSlice(src) } + +// Uint64ValueSlice converts a slice of uint64 pointers into a slice of uint64 values. +// +// Deprecated: use [conv.ValueSlice] instead. +func Uint64ValueSlice(src []*uint64) []uint64 { return conv.ValueSlice(src) } + +// Uint64Map converts a string map of uint64 values into a string map of uint64 pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func Uint64Map(src map[string]uint64) map[string]*uint64 { return conv.PointerMap(src) } + +// Uint64ValueMap converts a string map of uint64 pointers into a string map of uint64 values. +// +// Deprecated: use [conv.ValueMap] instead. +func Uint64ValueMap(src map[string]*uint64) map[string]uint64 { return conv.ValueMap(src) } + +// Float32 turn a pointer to of the float32 value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Float32(v float32) *float32 { return conv.Pointer(v) } + +// Float32Value turn the value of the float32 pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func Float32Value(v *float32) float32 { return conv.Value(v) } + +// Float32Slice converts a slice of float32 values into a slice of float32 pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func Float32Slice(src []float32) []*float32 { return conv.PointerSlice(src) } + +// Float32ValueSlice converts a slice of float32 pointers into a slice of float32 values. +// +// Deprecated: use [conv.ValueSlice] instead. +func Float32ValueSlice(src []*float32) []float32 { return conv.ValueSlice(src) } + +// Float32Map converts a string map of float32 values into a string map of float32 pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func Float32Map(src map[string]float32) map[string]*float32 { return conv.PointerMap(src) } + +// Float32ValueMap converts a string map of float32 pointers into a string map of float32 values. +// +// Deprecated: use [conv.ValueMap] instead. +func Float32ValueMap(src map[string]*float32) map[string]float32 { return conv.ValueMap(src) } + +// Float64 turn a pointer to of the float64 value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Float64(v float64) *float64 { return conv.Pointer(v) } + +// Float64Value turn the value of the float64 pointer passed in or 0 if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func Float64Value(v *float64) float64 { return conv.Value(v) } + +// Float64Slice converts a slice of float64 values into a slice of float64 pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func Float64Slice(src []float64) []*float64 { return conv.PointerSlice(src) } + +// Float64ValueSlice converts a slice of float64 pointers into a slice of float64 values. +// +// Deprecated: use [conv.ValueSlice] instead. +func Float64ValueSlice(src []*float64) []float64 { return conv.ValueSlice(src) } + +// Float64Map converts a string map of float64 values into a string map of float64 pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func Float64Map(src map[string]float64) map[string]*float64 { return conv.PointerMap(src) } + +// Float64ValueMap converts a string map of float64 pointers into a string map of float64 values. +// +// Deprecated: use [conv.ValueMap] instead. +func Float64ValueMap(src map[string]*float64) map[string]float64 { return conv.ValueMap(src) } + +// Time turn a pointer to of the time.Time value passed in. +// +// Deprecated: use [conv.Pointer] instead. +func Time(v time.Time) *time.Time { return conv.Pointer(v) } + +// TimeValue turn the value of the time.Time pointer passed in or time.Time{} if the pointer is nil. +// +// Deprecated: use [conv.Value] instead. +func TimeValue(v *time.Time) time.Time { return conv.Value(v) } + +// TimeSlice converts a slice of time.Time values into a slice of time.Time pointers. +// +// Deprecated: use [conv.PointerSlice] instead. +func TimeSlice(src []time.Time) []*time.Time { return conv.PointerSlice(src) } + +// TimeValueSlice converts a slice of time.Time pointers into a slice of time.Time values +// +// Deprecated: use [conv.ValueSlice] instead. +func TimeValueSlice(src []*time.Time) []time.Time { return conv.ValueSlice(src) } + +// TimeMap converts a string map of time.Time values into a string map of time.Time pointers. +// +// Deprecated: use [conv.PointerMap] instead. +func TimeMap(src map[string]time.Time) map[string]*time.Time { return conv.PointerMap(src) } + +// TimeValueMap converts a string map of time.Time pointers into a string map of time.Time values. +// +// Deprecated: use [conv.ValueMap] instead. +func TimeValueMap(src map[string]*time.Time) map[string]time.Time { return conv.ValueMap(src) } diff --git a/vendor/github.com/go-openapi/swag/convert.go b/vendor/github.com/go-openapi/swag/convert.go deleted file mode 100644 index fc085aeb..00000000 --- a/vendor/github.com/go-openapi/swag/convert.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "math" - "strconv" - "strings" -) - -// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER -const ( - maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1 - minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1 - epsilon float64 = 1e-9 -) - -// IsFloat64AJSONInteger allow for integers [-2^53, 2^53-1] inclusive -func IsFloat64AJSONInteger(f float64) bool { - if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat { - return false - } - fa := math.Abs(f) - g := float64(uint64(f)) - ga := math.Abs(g) - - diff := math.Abs(f - g) - - // more info: https://floating-point-gui.de/errors/comparison/#look-out-for-edge-cases - switch { - case f == g: // best case - return true - case f == float64(int64(f)) || f == float64(uint64(f)): // optimistic case - return true - case f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64: // very close to 0 values - return diff < (epsilon * math.SmallestNonzeroFloat64) - } - // check the relative error - return diff/math.Min(fa+ga, math.MaxFloat64) < epsilon -} - -var evaluatesAsTrue map[string]struct{} - -func init() { - evaluatesAsTrue = map[string]struct{}{ - "true": {}, - "1": {}, - "yes": {}, - "ok": {}, - "y": {}, - "on": {}, - "selected": {}, - "checked": {}, - "t": {}, - "enabled": {}, - } -} - -// ConvertBool turn a string into a boolean -func ConvertBool(str string) (bool, error) { - _, ok := evaluatesAsTrue[strings.ToLower(str)] - return ok, nil -} - -// ConvertFloat32 turn a string into a float32 -func ConvertFloat32(str string) (float32, error) { - f, err := strconv.ParseFloat(str, 32) - if err != nil { - return 0, err - } - return float32(f), nil -} - -// ConvertFloat64 turn a string into a float64 -func ConvertFloat64(str string) (float64, error) { - return strconv.ParseFloat(str, 64) -} - -// ConvertInt8 turn a string into an int8 -func ConvertInt8(str string) (int8, error) { - i, err := strconv.ParseInt(str, 10, 8) - if err != nil { - return 0, err - } - return int8(i), nil -} - -// ConvertInt16 turn a string into an int16 -func ConvertInt16(str string) (int16, error) { - i, err := strconv.ParseInt(str, 10, 16) - if err != nil { - return 0, err - } - return int16(i), nil -} - -// ConvertInt32 turn a string into an int32 -func ConvertInt32(str string) (int32, error) { - i, err := strconv.ParseInt(str, 10, 32) - if err != nil { - return 0, err - } - return int32(i), nil -} - -// ConvertInt64 turn a string into an int64 -func ConvertInt64(str string) (int64, error) { - return strconv.ParseInt(str, 10, 64) -} - -// ConvertUint8 turn a string into an uint8 -func ConvertUint8(str string) (uint8, error) { - i, err := strconv.ParseUint(str, 10, 8) - if err != nil { - return 0, err - } - return uint8(i), nil -} - -// ConvertUint16 turn a string into an uint16 -func ConvertUint16(str string) (uint16, error) { - i, err := strconv.ParseUint(str, 10, 16) - if err != nil { - return 0, err - } - return uint16(i), nil -} - -// ConvertUint32 turn a string into an uint32 -func ConvertUint32(str string) (uint32, error) { - i, err := strconv.ParseUint(str, 10, 32) - if err != nil { - return 0, err - } - return uint32(i), nil -} - -// ConvertUint64 turn a string into an uint64 -func ConvertUint64(str string) (uint64, error) { - return strconv.ParseUint(str, 10, 64) -} - -// FormatBool turns a boolean into a string -func FormatBool(value bool) string { - return strconv.FormatBool(value) -} - -// FormatFloat32 turns a float32 into a string -func FormatFloat32(value float32) string { - return strconv.FormatFloat(float64(value), 'f', -1, 32) -} - -// FormatFloat64 turns a float64 into a string -func FormatFloat64(value float64) string { - return strconv.FormatFloat(value, 'f', -1, 64) -} - -// FormatInt8 turns an int8 into a string -func FormatInt8(value int8) string { - return strconv.FormatInt(int64(value), 10) -} - -// FormatInt16 turns an int16 into a string -func FormatInt16(value int16) string { - return strconv.FormatInt(int64(value), 10) -} - -// FormatInt32 turns an int32 into a string -func FormatInt32(value int32) string { - return strconv.Itoa(int(value)) -} - -// FormatInt64 turns an int64 into a string -func FormatInt64(value int64) string { - return strconv.FormatInt(value, 10) -} - -// FormatUint8 turns an uint8 into a string -func FormatUint8(value uint8) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint16 turns an uint16 into a string -func FormatUint16(value uint16) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint32 turns an uint32 into a string -func FormatUint32(value uint32) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint64 turns an uint64 into a string -func FormatUint64(value uint64) string { - return strconv.FormatUint(value, 10) -} diff --git a/vendor/github.com/go-openapi/swag/convert_types.go b/vendor/github.com/go-openapi/swag/convert_types.go deleted file mode 100644 index c49cc473..00000000 --- a/vendor/github.com/go-openapi/swag/convert_types.go +++ /dev/null @@ -1,730 +0,0 @@ -package swag - -import "time" - -// This file was taken from the aws go sdk - -// String returns a pointer to of the string value passed in. -func String(v string) *string { - return &v -} - -// StringValue returns the value of the string pointer passed in or -// "" if the pointer is nil. -func StringValue(v *string) string { - if v != nil { - return *v - } - return "" -} - -// StringSlice converts a slice of string values into a slice of -// string pointers -func StringSlice(src []string) []*string { - dst := make([]*string, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// StringValueSlice converts a slice of string pointers into a slice of -// string values -func StringValueSlice(src []*string) []string { - dst := make([]string, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// StringMap converts a string map of string values into a string -// map of string pointers -func StringMap(src map[string]string) map[string]*string { - dst := make(map[string]*string) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// StringValueMap converts a string map of string pointers into a string -// map of string values -func StringValueMap(src map[string]*string) map[string]string { - dst := make(map[string]string) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Bool returns a pointer to of the bool value passed in. -func Bool(v bool) *bool { - return &v -} - -// BoolValue returns the value of the bool pointer passed in or -// false if the pointer is nil. -func BoolValue(v *bool) bool { - if v != nil { - return *v - } - return false -} - -// BoolSlice converts a slice of bool values into a slice of -// bool pointers -func BoolSlice(src []bool) []*bool { - dst := make([]*bool, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// BoolValueSlice converts a slice of bool pointers into a slice of -// bool values -func BoolValueSlice(src []*bool) []bool { - dst := make([]bool, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// BoolMap converts a string map of bool values into a string -// map of bool pointers -func BoolMap(src map[string]bool) map[string]*bool { - dst := make(map[string]*bool) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// BoolValueMap converts a string map of bool pointers into a string -// map of bool values -func BoolValueMap(src map[string]*bool) map[string]bool { - dst := make(map[string]bool) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int returns a pointer to of the int value passed in. -func Int(v int) *int { - return &v -} - -// IntValue returns the value of the int pointer passed in or -// 0 if the pointer is nil. -func IntValue(v *int) int { - if v != nil { - return *v - } - return 0 -} - -// IntSlice converts a slice of int values into a slice of -// int pointers -func IntSlice(src []int) []*int { - dst := make([]*int, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// IntValueSlice converts a slice of int pointers into a slice of -// int values -func IntValueSlice(src []*int) []int { - dst := make([]int, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// IntMap converts a string map of int values into a string -// map of int pointers -func IntMap(src map[string]int) map[string]*int { - dst := make(map[string]*int) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// IntValueMap converts a string map of int pointers into a string -// map of int values -func IntValueMap(src map[string]*int) map[string]int { - dst := make(map[string]int) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int32 returns a pointer to of the int32 value passed in. -func Int32(v int32) *int32 { - return &v -} - -// Int32Value returns the value of the int32 pointer passed in or -// 0 if the pointer is nil. -func Int32Value(v *int32) int32 { - if v != nil { - return *v - } - return 0 -} - -// Int32Slice converts a slice of int32 values into a slice of -// int32 pointers -func Int32Slice(src []int32) []*int32 { - dst := make([]*int32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int32ValueSlice converts a slice of int32 pointers into a slice of -// int32 values -func Int32ValueSlice(src []*int32) []int32 { - dst := make([]int32, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Int32Map converts a string map of int32 values into a string -// map of int32 pointers -func Int32Map(src map[string]int32) map[string]*int32 { - dst := make(map[string]*int32) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Int32ValueMap converts a string map of int32 pointers into a string -// map of int32 values -func Int32ValueMap(src map[string]*int32) map[string]int32 { - dst := make(map[string]int32) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int64 returns a pointer to of the int64 value passed in. -func Int64(v int64) *int64 { - return &v -} - -// Int64Value returns the value of the int64 pointer passed in or -// 0 if the pointer is nil. -func Int64Value(v *int64) int64 { - if v != nil { - return *v - } - return 0 -} - -// Int64Slice converts a slice of int64 values into a slice of -// int64 pointers -func Int64Slice(src []int64) []*int64 { - dst := make([]*int64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int64ValueSlice converts a slice of int64 pointers into a slice of -// int64 values -func Int64ValueSlice(src []*int64) []int64 { - dst := make([]int64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Int64Map converts a string map of int64 values into a string -// map of int64 pointers -func Int64Map(src map[string]int64) map[string]*int64 { - dst := make(map[string]*int64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Int64ValueMap converts a string map of int64 pointers into a string -// map of int64 values -func Int64ValueMap(src map[string]*int64) map[string]int64 { - dst := make(map[string]int64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint16 returns a pointer to of the uint16 value passed in. -func Uint16(v uint16) *uint16 { - return &v -} - -// Uint16Value returns the value of the uint16 pointer passed in or -// 0 if the pointer is nil. -func Uint16Value(v *uint16) uint16 { - if v != nil { - return *v - } - - return 0 -} - -// Uint16Slice converts a slice of uint16 values into a slice of -// uint16 pointers -func Uint16Slice(src []uint16) []*uint16 { - dst := make([]*uint16, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - - return dst -} - -// Uint16ValueSlice converts a slice of uint16 pointers into a slice of -// uint16 values -func Uint16ValueSlice(src []*uint16) []uint16 { - dst := make([]uint16, len(src)) - - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - - return dst -} - -// Uint16Map converts a string map of uint16 values into a string -// map of uint16 pointers -func Uint16Map(src map[string]uint16) map[string]*uint16 { - dst := make(map[string]*uint16) - - for k, val := range src { - v := val - dst[k] = &v - } - - return dst -} - -// Uint16ValueMap converts a string map of uint16 pointers into a string -// map of uint16 values -func Uint16ValueMap(src map[string]*uint16) map[string]uint16 { - dst := make(map[string]uint16) - - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - - return dst -} - -// Uint returns a pointer to of the uint value passed in. -func Uint(v uint) *uint { - return &v -} - -// UintValue returns the value of the uint pointer passed in or -// 0 if the pointer is nil. -func UintValue(v *uint) uint { - if v != nil { - return *v - } - return 0 -} - -// UintSlice converts a slice of uint values into a slice of -// uint pointers -func UintSlice(src []uint) []*uint { - dst := make([]*uint, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// UintValueSlice converts a slice of uint pointers into a slice of -// uint values -func UintValueSlice(src []*uint) []uint { - dst := make([]uint, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// UintMap converts a string map of uint values into a string -// map of uint pointers -func UintMap(src map[string]uint) map[string]*uint { - dst := make(map[string]*uint) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// UintValueMap converts a string map of uint pointers into a string -// map of uint values -func UintValueMap(src map[string]*uint) map[string]uint { - dst := make(map[string]uint) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint32 returns a pointer to of the uint32 value passed in. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint32Value returns the value of the uint32 pointer passed in or -// 0 if the pointer is nil. -func Uint32Value(v *uint32) uint32 { - if v != nil { - return *v - } - return 0 -} - -// Uint32Slice converts a slice of uint32 values into a slice of -// uint32 pointers -func Uint32Slice(src []uint32) []*uint32 { - dst := make([]*uint32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint32ValueSlice converts a slice of uint32 pointers into a slice of -// uint32 values -func Uint32ValueSlice(src []*uint32) []uint32 { - dst := make([]uint32, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Uint32Map converts a string map of uint32 values into a string -// map of uint32 pointers -func Uint32Map(src map[string]uint32) map[string]*uint32 { - dst := make(map[string]*uint32) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Uint32ValueMap converts a string map of uint32 pointers into a string -// map of uint32 values -func Uint32ValueMap(src map[string]*uint32) map[string]uint32 { - dst := make(map[string]uint32) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint64 returns a pointer to of the uint64 value passed in. -func Uint64(v uint64) *uint64 { - return &v -} - -// Uint64Value returns the value of the uint64 pointer passed in or -// 0 if the pointer is nil. -func Uint64Value(v *uint64) uint64 { - if v != nil { - return *v - } - return 0 -} - -// Uint64Slice converts a slice of uint64 values into a slice of -// uint64 pointers -func Uint64Slice(src []uint64) []*uint64 { - dst := make([]*uint64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint64ValueSlice converts a slice of uint64 pointers into a slice of -// uint64 values -func Uint64ValueSlice(src []*uint64) []uint64 { - dst := make([]uint64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Uint64Map converts a string map of uint64 values into a string -// map of uint64 pointers -func Uint64Map(src map[string]uint64) map[string]*uint64 { - dst := make(map[string]*uint64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Uint64ValueMap converts a string map of uint64 pointers into a string -// map of uint64 values -func Uint64ValueMap(src map[string]*uint64) map[string]uint64 { - dst := make(map[string]uint64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Float32 returns a pointer to of the float32 value passed in. -func Float32(v float32) *float32 { - return &v -} - -// Float32Value returns the value of the float32 pointer passed in or -// 0 if the pointer is nil. -func Float32Value(v *float32) float32 { - if v != nil { - return *v - } - - return 0 -} - -// Float32Slice converts a slice of float32 values into a slice of -// float32 pointers -func Float32Slice(src []float32) []*float32 { - dst := make([]*float32, len(src)) - - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - - return dst -} - -// Float32ValueSlice converts a slice of float32 pointers into a slice of -// float32 values -func Float32ValueSlice(src []*float32) []float32 { - dst := make([]float32, len(src)) - - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - - return dst -} - -// Float32Map converts a string map of float32 values into a string -// map of float32 pointers -func Float32Map(src map[string]float32) map[string]*float32 { - dst := make(map[string]*float32) - - for k, val := range src { - v := val - dst[k] = &v - } - - return dst -} - -// Float32ValueMap converts a string map of float32 pointers into a string -// map of float32 values -func Float32ValueMap(src map[string]*float32) map[string]float32 { - dst := make(map[string]float32) - - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - - return dst -} - -// Float64 returns a pointer to of the float64 value passed in. -func Float64(v float64) *float64 { - return &v -} - -// Float64Value returns the value of the float64 pointer passed in or -// 0 if the pointer is nil. -func Float64Value(v *float64) float64 { - if v != nil { - return *v - } - return 0 -} - -// Float64Slice converts a slice of float64 values into a slice of -// float64 pointers -func Float64Slice(src []float64) []*float64 { - dst := make([]*float64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Float64ValueSlice converts a slice of float64 pointers into a slice of -// float64 values -func Float64ValueSlice(src []*float64) []float64 { - dst := make([]float64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Float64Map converts a string map of float64 values into a string -// map of float64 pointers -func Float64Map(src map[string]float64) map[string]*float64 { - dst := make(map[string]*float64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Float64ValueMap converts a string map of float64 pointers into a string -// map of float64 values -func Float64ValueMap(src map[string]*float64) map[string]float64 { - dst := make(map[string]float64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Time returns a pointer to of the time.Time value passed in. -func Time(v time.Time) *time.Time { - return &v -} - -// TimeValue returns the value of the time.Time pointer passed in or -// time.Time{} if the pointer is nil. -func TimeValue(v *time.Time) time.Time { - if v != nil { - return *v - } - return time.Time{} -} - -// TimeSlice converts a slice of time.Time values into a slice of -// time.Time pointers -func TimeSlice(src []time.Time) []*time.Time { - dst := make([]*time.Time, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// TimeValueSlice converts a slice of time.Time pointers into a slice of -// time.Time values -func TimeValueSlice(src []*time.Time) []time.Time { - dst := make([]time.Time, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// TimeMap converts a string map of time.Time values into a string -// map of time.Time pointers -func TimeMap(src map[string]time.Time) map[string]*time.Time { - dst := make(map[string]*time.Time) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// TimeValueMap converts a string map of time.Time pointers into a string -// map of time.Time values -func TimeValueMap(src map[string]*time.Time) map[string]time.Time { - dst := make(map[string]time.Time) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} diff --git a/vendor/github.com/go-openapi/swag/doc.go b/vendor/github.com/go-openapi/swag/doc.go index 55094cb7..b54b5747 100644 --- a/vendor/github.com/go-openapi/swag/doc.go +++ b/vendor/github.com/go-openapi/swag/doc.go @@ -1,31 +1,47 @@ -// Copyright 2015 go-swagger maintainers +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package swag contains a bunch of helper functions for go-openapi and go-swagger projects. // -// 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 +// You may also use it standalone for your projects. // -// http://www.apache.org/licenses/LICENSE-2.0 +// NOTE: all features that used to be exposed as package-level members (constants, variables, +// functions and types) are now deprecated and are superseded by equivalent features in +// more specialized sub-packages. +// Moving forward, no additional feature will be added to the [swag] API directly at the root package level, +// which remains there for backward-compatibility purposes. // -// 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 swag contains a bunch of helper functions for go-openapi and go-swagger projects. - -You may also use it standalone for your projects. - - - convert between value and pointers for builtin types - - convert from string to builtin types (wraps strconv) - - fast json concatenation - - search in path - - load from file or http - - name mangling - -This repo has only few dependencies outside of the standard library: - - - YAML utilities depend on gopkg.in/yaml.v2 -*/ +// Child modules will continue to evolve or some new ones may be added in the future. +// +// # Modules +// +// - [cmdutils] utilities to work with CLIs +// +// - [conv] type conversion utilities +// +// - [fileutils] file utilities +// +// - [jsonname] JSON utilities +// +// - [jsonutils] JSON utilities +// +// - [loading] file loading +// +// - [mangling] safe name generation +// +// - [netutils] networking utilities +// +// - [stringutils] `string` utilities +// +// - [typeutils] `go` types utilities +// +// - [yamlutils] YAML utilities +// +// # Dependencies +// +// This repo has a few dependencies outside of the standard library: +// +// - YAML utilities depend on [go.yaml.in/yaml/v3] package swag + +//go:generate mockery diff --git a/vendor/github.com/go-openapi/swag/errors.go b/vendor/github.com/go-openapi/swag/errors.go deleted file mode 100644 index 6c67fbf9..00000000 --- a/vendor/github.com/go-openapi/swag/errors.go +++ /dev/null @@ -1,15 +0,0 @@ -package swag - -type swagError string - -const ( - // ErrYAML is an error raised by YAML utilities - ErrYAML swagError = "yaml error" - - // ErrLoader is an error raised by the file loader utility - ErrLoader swagError = "loader error" -) - -func (e swagError) Error() string { - return string(e) -} diff --git a/vendor/github.com/go-openapi/swag/file.go b/vendor/github.com/go-openapi/swag/file.go deleted file mode 100644 index 16accc55..00000000 --- a/vendor/github.com/go-openapi/swag/file.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import "mime/multipart" - -// File represents an uploaded file. -type File struct { - Data multipart.File - Header *multipart.FileHeader -} - -// Read bytes from the file -func (f *File) Read(p []byte) (n int, err error) { - return f.Data.Read(p) -} - -// Close the file -func (f *File) Close() error { - return f.Data.Close() -} diff --git a/vendor/github.com/go-openapi/swag/fileutils/LICENSE b/vendor/github.com/go-openapi/swag/fileutils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/fileutils/doc.go b/vendor/github.com/go-openapi/swag/fileutils/doc.go new file mode 100644 index 00000000..859a200d --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils/doc.go @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package fileutils exposes utilities to deal with files and paths. +// +// Currently, there is: +// - [File] to represent an abstraction of an uploaded file. +// For instance, this is used by [github.com/go-openapi/runtime.File]. +// - path search utilities (e.g. finding packages in the GO search path) +package fileutils diff --git a/vendor/github.com/go-openapi/swag/fileutils/file.go b/vendor/github.com/go-openapi/swag/fileutils/file.go new file mode 100644 index 00000000..5ad4cfae --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils/file.go @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package fileutils + +import "mime/multipart" + +// File represents an uploaded file. +type File struct { + Data multipart.File + Header *multipart.FileHeader +} + +// Read bytes from the file +func (f *File) Read(p []byte) (n int, err error) { + return f.Data.Read(p) +} + +// Close the file +func (f *File) Close() error { + return f.Data.Close() +} diff --git a/vendor/github.com/go-openapi/swag/path.go b/vendor/github.com/go-openapi/swag/fileutils/path.go similarity index 58% rename from vendor/github.com/go-openapi/swag/path.go rename to vendor/github.com/go-openapi/swag/fileutils/path.go index 941bd017..dd09f690 100644 --- a/vendor/github.com/go-openapi/swag/path.go +++ b/vendor/github.com/go-openapi/swag/fileutils/path.go @@ -1,18 +1,7 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 -package swag +package fileutils import ( "os" @@ -21,10 +10,8 @@ import ( "strings" ) -const ( - // GOPATHKey represents the env key for gopath - GOPATHKey = "GOPATH" -) +// GOPATHKey represents the env key for gopath +const GOPATHKey = "GOPATH" // FindInSearchPath finds a package in a provided lists of paths func FindInSearchPath(searchPath, pkg string) string { @@ -40,11 +27,17 @@ func FindInSearchPath(searchPath, pkg string) string { } // FindInGoSearchPath finds a package in the $GOPATH:$GOROOT +// +// Deprecated: this function is no longer relevant with modern go. +// It uses [runtime.GOROOT] under the hood, which is deprecated as of go1.24. func FindInGoSearchPath(pkg string) string { return FindInSearchPath(FullGoSearchPath(), pkg) } // FullGoSearchPath gets the search paths for finding packages +// +// Deprecated: this function is no longer relevant with modern go. +// It uses [runtime.GOROOT] under the hood, which is deprecated as of go1.24. func FullGoSearchPath() string { allPaths := os.Getenv(GOPATHKey) if allPaths == "" { diff --git a/vendor/github.com/go-openapi/swag/fileutils_iface.go b/vendor/github.com/go-openapi/swag/fileutils_iface.go new file mode 100644 index 00000000..f3e79a0e --- /dev/null +++ b/vendor/github.com/go-openapi/swag/fileutils_iface.go @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import "github.com/go-openapi/swag/fileutils" + +// GOPATHKey represents the env key for gopath +// +// Deprecated: use [fileutils.GOPATHKey] instead. +const GOPATHKey = fileutils.GOPATHKey + +// File represents an uploaded file. +// +// Deprecated: use [fileutils.File] instead. +type File = fileutils.File + +// FindInSearchPath finds a package in a provided lists of paths. +// +// Deprecated: use [fileutils.FindInSearchPath] instead. +func FindInSearchPath(searchPath, pkg string) string { + return fileutils.FindInSearchPath(searchPath, pkg) +} + +// FindInGoSearchPath finds a package in the $GOPATH:$GOROOT +// +// Deprecated: use [fileutils.FindInGoSearchPath] instead. +func FindInGoSearchPath(pkg string) string { return fileutils.FindInGoSearchPath(pkg) } + +// FullGoSearchPath gets the search paths for finding packages +// +// Deprecated: use [fileutils.FullGoSearchPath] instead. +func FullGoSearchPath() string { return fileutils.FullGoSearchPath() } diff --git a/vendor/github.com/go-openapi/swag/go.work b/vendor/github.com/go-openapi/swag/go.work new file mode 100644 index 00000000..f1dddc43 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/go.work @@ -0,0 +1,21 @@ +use ( + . + ./cmdutils + ./conv + ./fileutils + ./jsonname + ./jsonutils + ./jsonutils/adapters/easyjson + ./jsonutils/adapters/testintegration + ./jsonutils/adapters/testintegration/benchmarks + ./jsonutils/fixtures_test + ./loading + ./mangling + ./netutils + ./pools + ./stringutils + ./typeutils + ./yamlutils +) + +go 1.25.0 diff --git a/vendor/github.com/go-openapi/swag/go.work.sum b/vendor/github.com/go-openapi/swag/go.work.sum new file mode 100644 index 00000000..c1308caf --- /dev/null +++ b/vendor/github.com/go-openapi/swag/go.work.sum @@ -0,0 +1,7 @@ +github.com/go-openapi/testify/v2 v2.0.1/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= diff --git a/vendor/github.com/go-openapi/swag/initialism_index.go b/vendor/github.com/go-openapi/swag/initialism_index.go deleted file mode 100644 index 20a359bb..00000000 --- a/vendor/github.com/go-openapi/swag/initialism_index.go +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "sort" - "strings" - "sync" -) - -var ( - // commonInitialisms are common acronyms that are kept as whole uppercased words. - commonInitialisms *indexOfInitialisms - - // initialisms is a slice of sorted initialisms - initialisms []string - - // a copy of initialisms pre-baked as []rune - initialismsRunes [][]rune - initialismsUpperCased [][]rune - - isInitialism func(string) bool - - maxAllocMatches int -) - -func init() { - // Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769 - configuredInitialisms := map[string]bool{ - "ACL": true, - "API": true, - "ASCII": true, - "CPU": true, - "CSS": true, - "DNS": true, - "EOF": true, - "GUID": true, - "HTML": true, - "HTTPS": true, - "HTTP": true, - "ID": true, - "IP": true, - "IPv4": true, - "IPv6": true, - "JSON": true, - "LHS": true, - "OAI": true, - "QPS": true, - "RAM": true, - "RHS": true, - "RPC": true, - "SLA": true, - "SMTP": true, - "SQL": true, - "SSH": true, - "TCP": true, - "TLS": true, - "TTL": true, - "UDP": true, - "UI": true, - "UID": true, - "UUID": true, - "URI": true, - "URL": true, - "UTF8": true, - "VM": true, - "XML": true, - "XMPP": true, - "XSRF": true, - "XSS": true, - } - - // a thread-safe index of initialisms - commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms) - initialisms = commonInitialisms.sorted() - initialismsRunes = asRunes(initialisms) - initialismsUpperCased = asUpperCased(initialisms) - maxAllocMatches = maxAllocHeuristic(initialismsRunes) - - // a test function - isInitialism = commonInitialisms.isInitialism -} - -func asRunes(in []string) [][]rune { - out := make([][]rune, len(in)) - for i, initialism := range in { - out[i] = []rune(initialism) - } - - return out -} - -func asUpperCased(in []string) [][]rune { - out := make([][]rune, len(in)) - - for i, initialism := range in { - out[i] = []rune(upper(trim(initialism))) - } - - return out -} - -func maxAllocHeuristic(in [][]rune) int { - heuristic := make(map[rune]int) - for _, initialism := range in { - heuristic[initialism[0]]++ - } - - var maxAlloc int - for _, val := range heuristic { - if val > maxAlloc { - maxAlloc = val - } - } - - return maxAlloc -} - -// AddInitialisms add additional initialisms -func AddInitialisms(words ...string) { - for _, word := range words { - // commonInitialisms[upper(word)] = true - commonInitialisms.add(upper(word)) - } - // sort again - initialisms = commonInitialisms.sorted() - initialismsRunes = asRunes(initialisms) - initialismsUpperCased = asUpperCased(initialisms) -} - -// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms. -// Since go1.9, this may be implemented with sync.Map. -type indexOfInitialisms struct { - sortMutex *sync.Mutex - index *sync.Map -} - -func newIndexOfInitialisms() *indexOfInitialisms { - return &indexOfInitialisms{ - sortMutex: new(sync.Mutex), - index: new(sync.Map), - } -} - -func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms { - m.sortMutex.Lock() - defer m.sortMutex.Unlock() - for k, v := range initial { - m.index.Store(k, v) - } - return m -} - -func (m *indexOfInitialisms) isInitialism(key string) bool { - _, ok := m.index.Load(key) - return ok -} - -func (m *indexOfInitialisms) add(key string) *indexOfInitialisms { - m.index.Store(key, true) - return m -} - -func (m *indexOfInitialisms) sorted() (result []string) { - m.sortMutex.Lock() - defer m.sortMutex.Unlock() - m.index.Range(func(key, _ interface{}) bool { - k := key.(string) - result = append(result, k) - return true - }) - sort.Sort(sort.Reverse(byInitialism(result))) - return -} - -type byInitialism []string - -func (s byInitialism) Len() int { - return len(s) -} -func (s byInitialism) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} -func (s byInitialism) Less(i, j int) bool { - if len(s[i]) != len(s[j]) { - return len(s[i]) < len(s[j]) - } - - return strings.Compare(s[i], s[j]) > 0 -} diff --git a/vendor/github.com/go-openapi/swag/json.go b/vendor/github.com/go-openapi/swag/json.go deleted file mode 100644 index c7caa990..00000000 --- a/vendor/github.com/go-openapi/swag/json.go +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "bytes" - "encoding/json" - "log" - "reflect" - "strings" - "sync" - - "github.com/mailru/easyjson/jlexer" - "github.com/mailru/easyjson/jwriter" -) - -// nullJSON represents a JSON object with null type -var nullJSON = []byte("null") - -// DefaultJSONNameProvider the default cache for types -var DefaultJSONNameProvider = NewNameProvider() - -const comma = byte(',') - -var closers map[byte]byte - -func init() { - closers = map[byte]byte{ - '{': '}', - '[': ']', - } -} - -type ejMarshaler interface { - MarshalEasyJSON(w *jwriter.Writer) -} - -type ejUnmarshaler interface { - UnmarshalEasyJSON(w *jlexer.Lexer) -} - -// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler -// so it takes the fastest option available. -func WriteJSON(data interface{}) ([]byte, error) { - if d, ok := data.(ejMarshaler); ok { - jw := new(jwriter.Writer) - d.MarshalEasyJSON(jw) - return jw.BuildBytes() - } - if d, ok := data.(json.Marshaler); ok { - return d.MarshalJSON() - } - return json.Marshal(data) -} - -// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler -// so it takes the fastest option available -func ReadJSON(data []byte, value interface{}) error { - trimmedData := bytes.Trim(data, "\x00") - if d, ok := value.(ejUnmarshaler); ok { - jl := &jlexer.Lexer{Data: trimmedData} - d.UnmarshalEasyJSON(jl) - return jl.Error() - } - if d, ok := value.(json.Unmarshaler); ok { - return d.UnmarshalJSON(trimmedData) - } - return json.Unmarshal(trimmedData, value) -} - -// DynamicJSONToStruct converts an untyped json structure into a struct -func DynamicJSONToStruct(data interface{}, target interface{}) error { - // TODO: convert straight to a json typed map (mergo + iterate?) - b, err := WriteJSON(data) - if err != nil { - return err - } - return ReadJSON(b, target) -} - -// ConcatJSON concatenates multiple json objects efficiently -func ConcatJSON(blobs ...[]byte) []byte { - if len(blobs) == 0 { - return nil - } - - last := len(blobs) - 1 - for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) { - // strips trailing null objects - last-- - if last < 0 { - // there was nothing but "null"s or nil... - return nil - } - } - if last == 0 { - return blobs[0] - } - - var opening, closing byte - var idx, a int - buf := bytes.NewBuffer(nil) - - for i, b := range blobs[:last+1] { - if b == nil || bytes.Equal(b, nullJSON) { - // a null object is in the list: skip it - continue - } - if len(b) > 0 && opening == 0 { // is this an array or an object? - opening, closing = b[0], closers[b[0]] - } - - if opening != '{' && opening != '[' { - continue // don't know how to concatenate non container objects - } - - const minLengthIfNotEmpty = 3 - if len(b) < minLengthIfNotEmpty { // yep empty but also the last one, so closing this thing - if i == last && a > 0 { - if err := buf.WriteByte(closing); err != nil { - log.Println(err) - } - } - continue - } - - idx = 0 - if a > 0 { // we need to join with a comma for everything beyond the first non-empty item - if err := buf.WriteByte(comma); err != nil { - log.Println(err) - } - idx = 1 // this is not the first or the last so we want to drop the leading bracket - } - - if i != last { // not the last one, strip brackets - if _, err := buf.Write(b[idx : len(b)-1]); err != nil { - log.Println(err) - } - } else { // last one, strip only the leading bracket - if _, err := buf.Write(b[idx:]); err != nil { - log.Println(err) - } - } - a++ - } - // somehow it ended up being empty, so provide a default value - if buf.Len() == 0 { - if err := buf.WriteByte(opening); err != nil { - log.Println(err) - } - if err := buf.WriteByte(closing); err != nil { - log.Println(err) - } - } - return buf.Bytes() -} - -// ToDynamicJSON turns an object into a properly JSON typed structure -func ToDynamicJSON(data interface{}) interface{} { - // TODO: convert straight to a json typed map (mergo + iterate?) - b, err := json.Marshal(data) - if err != nil { - log.Println(err) - } - var res interface{} - if err := json.Unmarshal(b, &res); err != nil { - log.Println(err) - } - return res -} - -// FromDynamicJSON turns an object into a properly JSON typed structure -func FromDynamicJSON(data, target interface{}) error { - b, err := json.Marshal(data) - if err != nil { - log.Println(err) - } - return json.Unmarshal(b, target) -} - -// NameProvider represents an object capable of translating from go property names -// to json property names -// This type is thread-safe. -type NameProvider struct { - lock *sync.Mutex - index map[reflect.Type]nameIndex -} - -type nameIndex struct { - jsonNames map[string]string - goNames map[string]string -} - -// NewNameProvider creates a new name provider -func NewNameProvider() *NameProvider { - return &NameProvider{ - lock: &sync.Mutex{}, - index: make(map[reflect.Type]nameIndex), - } -} - -func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) { - for i := 0; i < tpe.NumField(); i++ { - targetDes := tpe.Field(i) - - if targetDes.PkgPath != "" { // unexported - continue - } - - if targetDes.Anonymous { // walk embedded structures tree down first - buildnameIndex(targetDes.Type, idx, reverseIdx) - continue - } - - if tag := targetDes.Tag.Get("json"); tag != "" { - - parts := strings.Split(tag, ",") - if len(parts) == 0 { - continue - } - - nm := parts[0] - if nm == "-" { - continue - } - if nm == "" { // empty string means we want to use the Go name - nm = targetDes.Name - } - - idx[nm] = targetDes.Name - reverseIdx[targetDes.Name] = nm - } - } -} - -func newNameIndex(tpe reflect.Type) nameIndex { - var idx = make(map[string]string, tpe.NumField()) - var reverseIdx = make(map[string]string, tpe.NumField()) - - buildnameIndex(tpe, idx, reverseIdx) - return nameIndex{jsonNames: idx, goNames: reverseIdx} -} - -// GetJSONNames gets all the json property names for a type -func (n *NameProvider) GetJSONNames(subject interface{}) []string { - n.lock.Lock() - defer n.lock.Unlock() - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - - res := make([]string, 0, len(names.jsonNames)) - for k := range names.jsonNames { - res = append(res, k) - } - return res -} - -// GetJSONName gets the json name for a go property name -func (n *NameProvider) GetJSONName(subject interface{}, name string) (string, bool) { - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - return n.GetJSONNameForType(tpe, name) -} - -// GetJSONNameForType gets the json name for a go property name on a given type -func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) { - n.lock.Lock() - defer n.lock.Unlock() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - nme, ok := names.goNames[name] - return nme, ok -} - -func (n *NameProvider) makeNameIndex(tpe reflect.Type) nameIndex { - names := newNameIndex(tpe) - n.index[tpe] = names - return names -} - -// GetGoName gets the go name for a json property name -func (n *NameProvider) GetGoName(subject interface{}, name string) (string, bool) { - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - return n.GetGoNameForType(tpe, name) -} - -// GetGoNameForType gets the go name for a given type for a json property name -func (n *NameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) { - n.lock.Lock() - defer n.lock.Unlock() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - nme, ok := names.jsonNames[name] - return nme, ok -} diff --git a/vendor/github.com/go-openapi/swag/jsonname_iface.go b/vendor/github.com/go-openapi/swag/jsonname_iface.go new file mode 100644 index 00000000..443560ca --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonname_iface.go @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import ( + "github.com/go-openapi/jsonpointer/jsonname" +) + +// DefaultJSONNameProvider is the default cache for types +// +// Deprecated: use [github.com/go-openapi/jsonpointer/jsonname.DefaultJSONNameProvider] instead. +var DefaultJSONNameProvider = jsonname.DefaultJSONNameProvider + +// NameProvider represents an object capable of translating from go property names +// to json property names. +// +// Deprecated: use [github.com/go-openapi/jsonpointer/jsonname.NameProvider] instead. +type NameProvider = jsonname.NameProvider + +// NewNameProvider creates a new name provider +// +// Deprecated: use [github.com/go-openapi/jsonpointer/jsonname.NewNameProvider] instead. +func NewNameProvider() *NameProvider { return jsonname.NewNameProvider() } diff --git a/vendor/github.com/go-openapi/swag/jsonutils/LICENSE b/vendor/github.com/go-openapi/swag/jsonutils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/jsonutils/README.md b/vendor/github.com/go-openapi/swag/jsonutils/README.md new file mode 100644 index 00000000..07a2ca1d --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/README.md @@ -0,0 +1,109 @@ +# jsonutils + +`jsonutils` exposes a few tools to work with JSON: + +- a fast, simple `Concat` to concatenate (not merge) JSON objects and arrays +- `FromDynamicJSON` to convert a data structure into a "dynamic JSON" data structure +- `ReadJSON` and `WriteJSON` behave like `json.Unmarshal` and `json.Marshal`, + with the ability to use another underlying serialization library through an `Adapter` + configured at runtime +- a `JSONMapSlice` structure that may be used to store JSON objects with the order of keys maintained + +## Dynamic JSON + +We call "dynamic JSON" the go data structure that results from unmarshaling JSON like this: + +```go + var value any + jsonBytes := `{"a": 1, ... }` + _ = json.Unmarshal(jsonBytes, &value) +``` + +In this configuration, the standard library mappings are as follows: + +| JSON | go | +|-----------|------------------| +| `number` | `float64` | +| `string` | `string` | +| `boolean` | `bool` | +| `null` | `nil` | +| `object` | `map[string]any` | +| `array` | `[]any` | + +## Map slices + +When using `JSONMapSlice`, the ordering of keys is ensured by replacing +mappings to `map[string]any` by a `JSONMapSlice` which is an (ordered) +slice of `JSONMapItem`s. + +Notice that a similar feature is available for YAML (see [`yamlutils`](../yamlutils)), +with a `YAMLMapSlice` type based on the `JSONMapSlice`. + +`JSONMapSlice` is similar to an ordered map, but the keys are not retrieved +in constant time. + +Another difference with the the above standard mappings is that numbers don't always map +to a `float64`: if the value is a JSON integer, it unmarshals to `int64`. + +See also [some examples](https://pkg.go.dev/github.com/go-openapi/swag/jsonutils#pkg-examples) + +## Adapters + +`ReadJSON`, `WriteJSON` and `FromDynamicJSON` (which is a combination of the latter two) +are wrappers on top of `json.Unmarshal` and `json.Marshal`. + +By default, the adapter merely wraps the standard library. + +The adapter may be used to register other JSON serialization libraries, +possibly several ones at the same time. + +If the value passed is identified as an "ordered map" (i.e. implements `ifaces.Ordered` +or `ifaces.SetOrdered`, the adapter favors the "ordered" JSON behavior and tries to +find a registered implementation that support ordered keys in objects. + +Our standard library implementation supports this. + +As of `v0.25.0`, we support through such an adapter the popular `mailru/easyjson` +library, which kicks in when the passed values support the `easyjson.Unmarshaler` +or `easyjson.Marshaler` interfaces. + +In the future, we plan to add more similar libraries that compete on the go JSON +serializers scene. + +## Registering an adapter + +In package `github.com/go-openapi/swag/easyjson/adapters`, several adapters are available. + +Each adapter is an independent go module. Hence you'll pick its dependencies only if you import it. + +At this moment we provide: + +- `stdlib`: JSON adapter based on the standard library +- `easyjson`: JSON adapter based on the `github.com/mailru/easyjson` + +The adapters provide the basic `Marshal` and `Unmarshal` capabilities, plus an implementation +of the `MapSlice` pattern. + +You may also build your own adapter based on your specific use-case. An adapter is not required to implement +all capabilities. + +Every adapter comes with a `Register` function, possibly with some options, to register the adapter +to a global registry. + +For example, to enable `easyjson` to be used in `ReadJSON` and `WriteJSON`, you would write something like: + +```go + import ( + "github.com/go-openapi/swag/jsonutils/adapters" + easyjson "github.com/go-openapi/swag/jsonutils/adapters/easyjson/json" + ) + + func init() { + easyjson.Register(adapters.Registry) + } +``` + +You may register several adapters. In this case, capability matching is evaluated from the last registered +adapters (LIFO). + +## [Benchmarks](./adapters/testintegration/benchmarks/README.md) diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/doc.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/doc.go new file mode 100644 index 00000000..76d3898f --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/doc.go @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package adapters exposes a registry of adapters to multiple +// JSON serialization libraries. +// +// All interfaces are defined in package [ifaces.Adapter]. +package adapters diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/doc.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/doc.go new file mode 100644 index 00000000..1fd43a1f --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/doc.go @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package ifaces exposes all interfaces to work with adapters. +package ifaces diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/ifaces.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/ifaces.go new file mode 100644 index 00000000..7805e5e5 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/ifaces.go @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package ifaces + +import ( + _ "encoding/json" // for documentation purpose + "iter" +) + +// Ordered knows how to iterate over the (key,value) pairs of a JSON object. +type Ordered interface { + OrderedItems() iter.Seq2[string, any] +} + +// SetOrdered knows how to append or update the keys of a JSON object, +// given an iterator over (key,value) pairs. +// +// If the provided iterator is nil then the receiver should be set to nil. +type SetOrdered interface { + SetOrderedItems(iter.Seq2[string, any]) +} + +// OrderedMap represent a JSON object (i.e. like a map[string,any]), +// and knows how to serialize and deserialize JSON with the order of keys maintained. +type OrderedMap interface { + Ordered + SetOrdered + + OrderedMarshalJSON() ([]byte, error) + OrderedUnmarshalJSON([]byte) error +} + +// MarshalAdapter behaves likes the standard library [json.Marshal]. +type MarshalAdapter interface { + Poolable + + Marshal(any) ([]byte, error) +} + +// OrderedMarshalAdapter behaves likes the standard library [json.Marshal], preserving the order of keys in objects. +type OrderedMarshalAdapter interface { + Poolable + + OrderedMarshal(Ordered) ([]byte, error) +} + +// UnmarshalAdapter behaves likes the standard library [json.Unmarshal]. +type UnmarshalAdapter interface { + Poolable + + Unmarshal([]byte, any) error +} + +// OrderedUnmarshalAdapter behaves likes the standard library [json.Unmarshal], preserving the order of keys in objects. +type OrderedUnmarshalAdapter interface { + Poolable + + OrderedUnmarshal([]byte, SetOrdered) error +} + +// Adapter exposes an interface like the standard [json] library. +type Adapter interface { + MarshalAdapter + UnmarshalAdapter + + OrderedAdapter +} + +// OrderedAdapter exposes interfaces to process JSON and keep the order of object keys. +type OrderedAdapter interface { + OrderedMarshalAdapter + OrderedUnmarshalAdapter + NewOrderedMap(capacity int) OrderedMap +} + +type Poolable interface { + // Self-redeem: for [Adapter] s that are allocated from a pool. + // The [Adapter] must not be used after calling [Redeem]. + Redeem() + + // Reset the state of the [Adapter], if any. + Reset() +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/registry_iface.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/registry_iface.go new file mode 100644 index 00000000..2d6c69f4 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/registry_iface.go @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package ifaces + +import ( + "strings" +) + +// Capability indicates what a JSON adapter is capable of. +type Capability uint8 + +const ( + CapabilityMarshalJSON Capability = 1 << iota + CapabilityUnmarshalJSON + CapabilityOrderedMarshalJSON + CapabilityOrderedUnmarshalJSON + CapabilityOrderedMap +) + +func (c Capability) String() string { + switch c { + case CapabilityMarshalJSON: + return "MarshalJSON" + case CapabilityUnmarshalJSON: + return "UnmarshalJSON" + case CapabilityOrderedMarshalJSON: + return "OrderedMarshalJSON" + case CapabilityOrderedUnmarshalJSON: + return "OrderedUnmarshalJSON" + case CapabilityOrderedMap: + return "OrderedMap" + default: + return "" + } +} + +// Capabilities holds several unitary capability flags +type Capabilities uint8 + +// Has some capability flag enabled. +func (c Capabilities) Has(capability Capability) bool { + return Capability(c)&capability > 0 +} + +func (c Capabilities) String() string { + var w strings.Builder + + first := true + for _, capability := range []Capability{ + CapabilityMarshalJSON, + CapabilityUnmarshalJSON, + CapabilityOrderedMarshalJSON, + CapabilityOrderedUnmarshalJSON, + CapabilityOrderedMap, + } { + if c.Has(capability) { + if !first { + w.WriteByte('|') + } else { + first = false + } + w.WriteString(capability.String()) + } + } + + return w.String() +} + +const ( + AllCapabilities Capabilities = Capabilities(uint8(CapabilityMarshalJSON) | + uint8(CapabilityUnmarshalJSON) | + uint8(CapabilityOrderedMarshalJSON) | + uint8(CapabilityOrderedUnmarshalJSON) | + uint8(CapabilityOrderedMap)) + + AllUnorderedCapabilities Capabilities = Capabilities(uint8(CapabilityMarshalJSON) | uint8(CapabilityUnmarshalJSON)) +) + +// RegistryEntry describes how any given adapter registers its capabilities to the [Registrar]. +type RegistryEntry struct { + Who string + What Capabilities + Constructor func() Adapter + Support func(what Capability, value any) bool +} + +// Registrar is a type that knows how to keep registration calls from adapters. +type Registrar interface { + RegisterFor(RegistryEntry) +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/registry.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/registry.go new file mode 100644 index 00000000..3062acaf --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/registry.go @@ -0,0 +1,229 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package adapters + +import ( + "fmt" + "reflect" + "slices" + "sync" + + "github.com/go-openapi/swag/jsonutils/adapters/ifaces" + stdlib "github.com/go-openapi/swag/jsonutils/adapters/stdlib/json" +) + +// Registry holds the global registry for registered adapters. +var Registry = NewRegistrar() + +var ( + defaultRegistered = stdlib.Register + + _ ifaces.Registrar = &Registrar{} +) + +type registryError string + +func (e registryError) Error() string { + return string(e) +} + +// ErrRegistry indicates an error returned by the [Registrar]. +var ErrRegistry registryError = "JSON adapters registry error" + +type registry []*ifaces.RegistryEntry + +// Registrar holds registered [ifaces.Adapters] for different serialization capabilities. +// +// Internally, it maintains a cache for data types that favor a given adapter. +type Registrar struct { + marshalerRegistry registry + unmarshalerRegistry registry + orderedMarshalerRegistry registry + orderedUnmarshalerRegistry registry + orderedMapRegistry registry + + gmx sync.RWMutex + + // cache indexed by value type, so we don't have to lookup + marshalerCache map[reflect.Type]*ifaces.RegistryEntry + unmarshalerCache map[reflect.Type]*ifaces.RegistryEntry + orderedMarshalerCache map[reflect.Type]*ifaces.RegistryEntry + orderedUnmarshalerCache map[reflect.Type]*ifaces.RegistryEntry + orderedMapCache map[reflect.Type]*ifaces.RegistryEntry +} + +func NewRegistrar() *Registrar { + r := &Registrar{} + + r.marshalerRegistry = make(registry, 0, 1) + r.unmarshalerRegistry = make(registry, 0, 1) + r.orderedMarshalerRegistry = make(registry, 0, 1) + r.orderedUnmarshalerRegistry = make(registry, 0, 1) + r.orderedMapRegistry = make(registry, 0, 1) + + r.marshalerCache = make(map[reflect.Type]*ifaces.RegistryEntry) + r.unmarshalerCache = make(map[reflect.Type]*ifaces.RegistryEntry) + r.orderedMarshalerCache = make(map[reflect.Type]*ifaces.RegistryEntry) + r.orderedUnmarshalerCache = make(map[reflect.Type]*ifaces.RegistryEntry) + r.orderedMapCache = make(map[reflect.Type]*ifaces.RegistryEntry) + + defaultRegistered(r) + + return r +} + +// ClearCache resets the internal type cache. +func (r *Registrar) ClearCache() { + r.gmx.Lock() + r.clearCache() + r.gmx.Unlock() +} + +// Reset the [Registrar] to its defaults. +func (r *Registrar) Reset() { + r.gmx.Lock() + r.clearCache() + r.marshalerRegistry = r.marshalerRegistry[:0] + r.unmarshalerRegistry = r.unmarshalerRegistry[:0] + r.orderedMarshalerRegistry = r.orderedMarshalerRegistry[:0] + r.orderedUnmarshalerRegistry = r.orderedUnmarshalerRegistry[:0] + r.orderedMapRegistry = r.orderedMapRegistry[:0] + r.gmx.Unlock() + + defaultRegistered(r) +} + +// RegisterFor registers an adapter for some JSON capabilities. +func (r *Registrar) RegisterFor(entry ifaces.RegistryEntry) { + r.gmx.Lock() + if entry.What.Has(ifaces.CapabilityMarshalJSON) { + e := entry + e.What &= ifaces.Capabilities(ifaces.CapabilityMarshalJSON) + r.marshalerRegistry = slices.Insert(r.marshalerRegistry, 0, &e) + } + if entry.What.Has(ifaces.CapabilityUnmarshalJSON) { + e := entry + e.What &= ifaces.Capabilities(ifaces.CapabilityUnmarshalJSON) + r.unmarshalerRegistry = slices.Insert(r.unmarshalerRegistry, 0, &e) + } + if entry.What.Has(ifaces.CapabilityOrderedMarshalJSON) { + e := entry + e.What &= ifaces.Capabilities(ifaces.CapabilityOrderedMarshalJSON) + r.orderedMarshalerRegistry = slices.Insert(r.orderedMarshalerRegistry, 0, &e) + } + if entry.What.Has(ifaces.CapabilityOrderedUnmarshalJSON) { + e := entry + e.What &= ifaces.Capabilities(ifaces.CapabilityOrderedUnmarshalJSON) + r.orderedUnmarshalerRegistry = slices.Insert(r.orderedUnmarshalerRegistry, 0, &e) + } + if entry.What.Has(ifaces.CapabilityOrderedMap) { + e := entry + e.What &= ifaces.Capabilities(ifaces.CapabilityOrderedMap) + r.orderedMapRegistry = slices.Insert(r.orderedMapRegistry, 0, &e) + } + r.gmx.Unlock() +} + +// AdapterFor returns an [ifaces.Adapter] that supports this capability for this type of value. +// +// The [ifaces.Adapter] may be redeemed to its pool using its Redeem() method, for adapters that support global +// pooling. When this is not the case, the redeem function is just a no-operation. +func (r *Registrar) AdapterFor(capability ifaces.Capability, value any) ifaces.Adapter { + entry := r.findFirstFor(capability, value) + if entry == nil { + return nil + } + + return entry.Constructor() +} + +func (r *Registrar) clearCache() { + clear(r.marshalerCache) + clear(r.unmarshalerCache) + clear(r.orderedMarshalerCache) + clear(r.orderedUnmarshalerCache) + clear(r.orderedMapCache) +} + +func (r *Registrar) findFirstFor(capability ifaces.Capability, value any) *ifaces.RegistryEntry { + switch capability { + case ifaces.CapabilityMarshalJSON: + return r.findFirstInRegistryFor(r.marshalerRegistry, r.marshalerCache, capability, value) + case ifaces.CapabilityUnmarshalJSON: + return r.findFirstInRegistryFor(r.unmarshalerRegistry, r.unmarshalerCache, capability, value) + case ifaces.CapabilityOrderedMarshalJSON: + return r.findFirstInRegistryFor(r.orderedMarshalerRegistry, r.orderedMarshalerCache, capability, value) + case ifaces.CapabilityOrderedUnmarshalJSON: + return r.findFirstInRegistryFor(r.orderedUnmarshalerRegistry, r.orderedUnmarshalerCache, capability, value) + case ifaces.CapabilityOrderedMap: + return r.findFirstInRegistryFor(r.orderedMapRegistry, r.orderedMapCache, capability, value) + default: + panic(fmt.Errorf("unsupported capability %d: %w", capability, ErrRegistry)) + } +} + +func (r *Registrar) findFirstInRegistryFor(reg registry, cache map[reflect.Type]*ifaces.RegistryEntry, capability ifaces.Capability, value any) *ifaces.RegistryEntry { + r.gmx.RLock() + if len(reg) > 1 { + if entry, ok := cache[reflect.TypeOf(value)]; ok { + // cache hit + r.gmx.RUnlock() + return entry + } + } + + for _, entry := range reg { + if !entry.Support(capability, value) { + continue + } + + r.gmx.RUnlock() + + // update the internal cache + r.gmx.Lock() + cache[reflect.TypeOf(value)] = entry + r.gmx.Unlock() + + return entry + } + + // no adapter found + r.gmx.RUnlock() + + return nil +} + +// MarshalAdapterFor returns the first adapter that knows how to Marshal this type of value. +func MarshalAdapterFor(value any) ifaces.MarshalAdapter { + return Registry.AdapterFor(ifaces.CapabilityMarshalJSON, value) +} + +// OrderedMarshalAdapterFor returns the first adapter that knows how to OrderedMarshal this type of value. +func OrderedMarshalAdapterFor(value ifaces.Ordered) ifaces.OrderedMarshalAdapter { + return Registry.AdapterFor(ifaces.CapabilityOrderedMarshalJSON, value) +} + +// UnmarshalAdapterFor returns the first adapter that knows how to Unmarshal this type of value. +func UnmarshalAdapterFor(value any) ifaces.UnmarshalAdapter { + return Registry.AdapterFor(ifaces.CapabilityUnmarshalJSON, value) +} + +// OrderedUnmarshalAdapterFor provides the first adapter that knows how to OrderedUnmarshal this type of value. +func OrderedUnmarshalAdapterFor(value ifaces.SetOrdered) ifaces.OrderedUnmarshalAdapter { + return Registry.AdapterFor(ifaces.CapabilityOrderedUnmarshalJSON, value) +} + +// NewOrderedMap provides the "ordered map" implementation provided by the registry. +func NewOrderedMap(capacity int) ifaces.OrderedMap { + var v any + adapter := Registry.AdapterFor(ifaces.CapabilityOrderedUnmarshalJSON, v) + if adapter == nil { + return nil + } + + defer adapter.Redeem() + return adapter.NewOrderedMap(capacity) +} + +func noopRedeemer() {} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go new file mode 100644 index 00000000..94185f79 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go @@ -0,0 +1,133 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +import ( + stdjson "encoding/json" + "fmt" + + "github.com/go-openapi/swag/jsonutils/adapters/ifaces" + "github.com/go-openapi/swag/typeutils" +) + +const sensibleBufferSize = 8192 + +type jsonError string + +func (e jsonError) Error() string { + return string(e) +} + +// ErrStdlib indicates that an error comes from the stdlib JSON adapter +var ErrStdlib jsonError = "error from the JSON adapter stdlib" + +var _ ifaces.Adapter = &Adapter{} + +type Adapter struct { + options +} + +// NewAdapter yields an [ifaces.Adapter] using the standard library. +func NewAdapter(opts ...Option) *Adapter { + var o options + + return &Adapter{ + options: buildOptions(o, opts), + } +} + +func (a *Adapter) Marshal(value any) ([]byte, error) { + return stdjson.Marshal(value) +} + +func (a *Adapter) Unmarshal(data []byte, value any) error { + return stdjson.Unmarshal(data, value) +} + +func (a *Adapter) OrderedMarshal(value ifaces.Ordered) ([]byte, error) { + w, redeem := poolOfWriters.BorrowWithRedeem() + defer redeem() + w.setBuf() + + a.orderedMarshal(w, value, 1) + + return w.BuildBytes() +} + +func (a *Adapter) OrderedUnmarshal(data []byte, value ifaces.SetOrdered) error { + var m MapSlice + if err := m.orderedUnmarshalJSON(data, a.maxDepth()); err != nil { + return err + } + + if typeutils.IsNil(m) { + // force input value to nil + value.SetOrderedItems(nil) + + return nil + } + + value.SetOrderedItems(m.OrderedItems()) + + return nil +} + +func (a *Adapter) NewOrderedMap(capacity int) ifaces.OrderedMap { + m := make(MapSlice, 0, capacity) + + return &m +} + +// Redeem the [Adapter] when it comes from a pool. +// +// The adapter becomes immediately unusable once redeemed. +func (a *Adapter) Redeem() { + if a == nil { + return + } + + RedeemAdapter(a) +} + +func (a *Adapter) Reset() { + a.options = options{} +} + +// orderedMarshal writes value to w, tracking the container nesting depth to guard +// against stack overflow on deeply nested structures. +func (a *Adapter) orderedMarshal(w *jwriter, value ifaces.Ordered, depth int) { + if typeutils.IsNil(value) { + w.RawString("null") + + return + } + + if maxDepth := a.maxDepth(); depth > maxDepth { + w.SetErr(fmt.Errorf("maximum nesting depth of %d exceeded: %w", maxDepth, ErrStdlib)) + + return + } + + w.RawByte('{') + first := true + for k, v := range value.OrderedItems() { + if first { + first = false + } else { + w.RawByte(',') + } + + w.String(k) + w.RawByte(':') + + switch val := v.(type) { + case ifaces.Ordered: + a.orderedMarshal(w, val, depth+1) + default: + w.Raw(stdjson.Marshal(v)) + } + } + + w.RawByte('}') +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/doc.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/doc.go new file mode 100644 index 00000000..5ea1b440 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/doc.go @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package json implements an [ifaces.Adapter] using the standard library. +package json diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go new file mode 100644 index 00000000..ac81cbc7 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go @@ -0,0 +1,356 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +import ( + stdjson "encoding/json" + "errors" + "fmt" + "io" + "math" + "strconv" + + "github.com/go-openapi/swag/conv" +) + +type token struct { + stdjson.Token +} + +func (t token) String() string { + if t == invalidToken { + return "invalid token" + } + if t == eofToken { + return "EOF" + } + + return fmt.Sprintf("%v", t.Token) +} + +func (t token) Kind() tokenKind { + switch t.Token.(type) { + case nil: + return tokenNull + case stdjson.Delim: + return tokenDelim + case bool: + return tokenBool + case float64: + return tokenFloat + case stdjson.Number: + return tokenNumber + case string: + return tokenString + default: + return tokenUndef + } +} + +func (t token) Delim() byte { + r, ok := t.Token.(stdjson.Delim) + if !ok { + return 0 + } + + return byte(r) //nolint:gosec // delimiter runes are single byte +} + +type tokenKind uint8 + +const ( + tokenUndef tokenKind = iota + tokenString + tokenNumber + tokenFloat + tokenBool + tokenNull + tokenDelim +) + +var ( + invalidToken = token{ + Token: stdjson.Token(struct{}{}), + } + + eofToken = token{ + Token: stdjson.Token(&struct{}{}), + } + + undefToken = token{ + Token: stdjson.Token(uint8(0)), + } +) + +// jlexer apes easyjson's jlexer, but uses the standard library decoder under the hood. +type jlexer struct { + buf *bytesReader + dec *stdjson.Decoder + err error + // current token + next token + // started bool + + // depth tracks the current JSON container nesting level, and maxDepth caps it + // to guard against stack-overflow on adversarially deep documents. The standard + // library's streaming [encoding/json.Decoder.Token] API (used here) does not + // enforce the max-depth guard that [encoding/json.Unmarshal] provides, so we do. + depth int + maxDepth int +} + +type bytesReader struct { + buf []byte + offset int +} + +func (b *bytesReader) Reset() { + b.buf = nil + b.offset = 0 +} + +func (b *bytesReader) Read(p []byte) (int, error) { + if b.offset >= len(b.buf) { + return 0, io.EOF + } + + n := len(p) + buf := b.buf[b.offset:] + m := len(buf) + + if n >= m { + copy(p, buf) + b.offset += m + + return m, nil + } + + copy(p, buf[:n]) + b.offset += n + + return n, nil +} + +var _ io.Reader = &bytesReader{} + +func newLexer(data []byte) *jlexer { + l := &jlexer{ + // current: undefToken, + next: undefToken, + maxDepth: defaultMaxNestingDepth, + } + l.buf = &bytesReader{ + buf: data, + } + l.dec = stdjson.NewDecoder(l.buf) // unfortunately, cannot pool this + + return l +} + +func (l *jlexer) Reset() { + l.err = nil + l.next = undefToken + l.depth = 0 + l.maxDepth = defaultMaxNestingDepth + l.dec = nil + // leave l.buf alone, since they are replaced at every Borrow + l.buf = nil +} + +func (l *jlexer) Error() error { + return l.err +} + +func (l *jlexer) SetErr(err error) { + l.err = err +} + +func (l *jlexer) Ok() bool { + return l.err == nil +} + +// NextToken consumes a token +func (l *jlexer) NextToken() token { + if !l.Ok() { + return invalidToken + } + + if l.next != undefToken { + next := l.next + l.next = undefToken + + return next + } + + return l.fetchToken() +} + +// PeekToken returns the next token without consuming it +func (l *jlexer) PeekToken() token { + if l.next == undefToken { + l.next = l.fetchToken() + } + + return l.next +} + +func (l *jlexer) Skip() { + _ = l.NextToken() +} + +func (l *jlexer) IsDelim(c byte) bool { + if !l.Ok() { + return false + } + + next := l.PeekToken() + if next.Kind() != tokenDelim { + return false + } + + if next.Delim() != c { + return false + } + + return true +} + +func (l *jlexer) IsNull() bool { + if !l.Ok() { + return false + } + + next := l.PeekToken() + + return next.Kind() == tokenNull +} + +func (l *jlexer) Delim(c byte) { + if !l.Ok() { + return + } + + tok := l.NextToken() + if tok.Kind() != tokenDelim { + l.err = fmt.Errorf("expected a delimiter token but got '%v': %w", tok, ErrStdlib) + + return + } + + if tok.Delim() != c { + l.err = fmt.Errorf("expected delimiter '%q' but got '%q': %w", c, tok.Delim(), ErrStdlib) + + return + } + + // Track container nesting depth centrally: every '{' or '[' opens a level and + // every '}' or ']' closes one. This guards the mutually-recursive unmarshal + // routines (unmarshalObject/unmarshalArray/asInterface) against stack overflow. + switch c { + case '{', '[': + l.depth++ + if l.maxDepth > 0 && l.depth > l.maxDepth { + l.err = fmt.Errorf("maximum nesting depth of %d exceeded: %w", l.maxDepth, ErrStdlib) + } + case '}', ']': + l.depth-- + } +} + +func (l *jlexer) Null() { + if !l.Ok() { + return + } + + tok := l.NextToken() + if tok.Kind() != tokenNull { + l.err = fmt.Errorf("expected a null token but got '%v': %w", tok, ErrStdlib) + } +} + +func (l *jlexer) Number() any { + if !l.Ok() { + return 0 + } + + tok := l.NextToken() + + switch tok.Kind() { //nolint:exhaustive + case tokenNumber: + n := tok.Token.(stdjson.Number).String() + f, _ := strconv.ParseFloat(n, 64) + if conv.IsFloat64AJSONInteger(f) { + return int64(math.Trunc(f)) + } + + return f + + case tokenFloat: + f := tok.Token.(float64) + if conv.IsFloat64AJSONInteger(f) { + return int64(math.Trunc(f)) + } + + return f + + default: + l.err = fmt.Errorf("expected a number token but got '%v': %w", tok, ErrStdlib) + + return 0 + } +} + +func (l *jlexer) Bool() bool { + if !l.Ok() { + return false + } + + tok := l.NextToken() + if tok.Kind() != tokenBool { + l.err = fmt.Errorf("expected a bool token but got '%v': %w", tok, ErrStdlib) + + return false + } + + return tok.Token.(bool) +} + +func (l *jlexer) String() string { + if !l.Ok() { + return "" + } + + tok := l.NextToken() + if tok.Kind() != tokenString { + l.err = fmt.Errorf("expected a string token but got '%v': %w", tok, ErrStdlib) + + return "" + } + + return tok.Token.(string) +} + +// Commas and colons are elided. +func (l *jlexer) fetchToken() token { + jtok, err := l.dec.Token() + if err != nil { + if errors.Is(err, io.EOF) { + return eofToken + } + + l.err = errors.Join(err, ErrStdlib) + return invalidToken + } + + return token{Token: jtok} +} + +func (l *jlexer) setBuf(data []byte) func() { + rdr, redeemBuf := poolOfReaders.BorrowWithRedeem() + l.buf = rdr + l.buf.buf = data + l.dec = stdjson.NewDecoder(l.buf) // cannot pool, not exposed by the encoding/json API + + return redeemBuf +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go new file mode 100644 index 00000000..f114f1f1 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +// defaultMaxNestingDepth is the default maximum number of nested JSON containers +// ('{' or '[') that the ordered-JSON marshaler and unmarshaler will process before +// returning an error. +// +// It mirrors the limit enforced by the standard library's [encoding/json] decoder +// (see encoding/json's internal maxNestingDepth), which this adapter would otherwise +// not benefit from since it drives [encoding/json.Decoder.Token] directly. +const defaultMaxNestingDepth = 10000 + +// Option selects options for the stdlib adapter. +type Option func(o options) options + +type options struct { + maxNestingDepth int +} + +func buildOptions(o options, opts []Option) options { + for _, apply := range opts { + o = apply(o) + } + + return o +} + +// maxDepth returns the configured maximum nesting depth, or the default when unset. +func (o options) maxDepth() int { + if o.maxNestingDepth <= 0 { + return defaultMaxNestingDepth + } + + return o.maxNestingDepth +} + +// WithMaxNestingDepth sets the maximum number of nested JSON containers accepted +// when marshaling or unmarshaling ordered JSON. +// +// A value <= 0 selects the default (10,000). +// +// This guards against stack-overflow crashes on deeply nested (possibly adversarial) +// JSON documents or in-memory structures. +func WithMaxNestingDepth(depth int) Option { + return func(o options) options { + o.maxNestingDepth = depth + + return o + } +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go new file mode 100644 index 00000000..a5a8f4b6 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go @@ -0,0 +1,289 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +import ( + stdjson "encoding/json" + "fmt" + "iter" + + "github.com/go-openapi/swag/jsonutils/adapters/ifaces" +) + +var _ ifaces.OrderedMap = &MapSlice{} + +// MapSlice represents a JSON object, with the order of keys maintained. +type MapSlice []MapItem + +func (s MapSlice) OrderedItems() iter.Seq2[string, any] { + return func(yield func(string, any) bool) { + for _, item := range s { + if !yield(item.Key, item.Value) { + return + } + } + } +} + +func (s *MapSlice) SetOrderedItems(items iter.Seq2[string, any]) { + if items == nil { + *s = nil + + return + } + + m := *s + if len(m) > 0 { + // update mode + idx := make(map[string]int, len(m)) + + for i, item := range m { + idx[item.Key] = i + } + + for k, v := range items { + idx, ok := idx[k] + if ok { + m[idx].Value = v + + continue + } + m = append(m, MapItem{Key: k, Value: v}) + } + + *s = m + + return + } + + for k, v := range items { + m = append(m, MapItem{Key: k, Value: v}) + } + + *s = m +} + +// MarshalJSON renders a [MapSlice] as JSON bytes, preserving the order of keys. +func (s MapSlice) MarshalJSON() ([]byte, error) { + return s.OrderedMarshalJSON() +} + +func (s MapSlice) OrderedMarshalJSON() ([]byte, error) { + w, redeem := poolOfWriters.BorrowWithRedeem() + defer redeem() + w.setBuf() + + s.marshalObject(w, 1) + + return w.BuildBytes() // this clones data, so it's okay to redeem the writer and its buffer +} + +// UnmarshalJSON builds a [MapSlice] from JSON bytes, preserving the order of keys. +// +// Inner objects are unmarshaled as [MapSlice] slices and not map[string]any. +func (s *MapSlice) UnmarshalJSON(data []byte) error { + return s.OrderedUnmarshalJSON(data) +} + +func (s *MapSlice) OrderedUnmarshalJSON(data []byte) error { + return s.orderedUnmarshalJSON(data, defaultMaxNestingDepth) +} + +func (s *MapSlice) orderedUnmarshalJSON(data []byte, maxDepth int) error { + l, redeem := poolOfLexers.BorrowWithRedeem() + defer redeem() + + redeemBuf := l.setBuf(data) + defer redeemBuf() + + if maxDepth > 0 { + l.maxDepth = maxDepth + } + + s.unmarshalObject(l) + + return l.Error() +} + +func (s MapSlice) marshalObject(w *jwriter, depth int) { + if s == nil { + w.RawString("null") + + return + } + + if depth > defaultMaxNestingDepth { + w.SetErr(fmt.Errorf("maximum nesting depth of %d exceeded: %w", defaultMaxNestingDepth, ErrStdlib)) + + return + } + + w.RawByte('{') + + if len(s) == 0 { + w.RawByte('}') + + return + } + + s[0].marshalJSON(w, depth) + + for i := 1; i < len(s); i++ { + w.RawByte(',') + s[i].marshalJSON(w, depth) + } + + w.RawByte('}') +} + +func (s *MapSlice) unmarshalObject(in *jlexer) { + if in.IsNull() { + in.Skip() + + return + } + + in.Delim('{') // consume token + if !in.Ok() { + return + } + + result := make(MapSlice, 0) + + for in.Ok() && !in.IsDelim('}') { + var mi MapItem + + mi.unmarshalKeyValue(in) + result = append(result, mi) + } + + in.Delim('}') + + if !in.Ok() { + return + } + + *s = result +} + +// MapItem represents the value of a key in a JSON object held by [MapSlice]. +// +// Notice that [MapItem] should not be marshaled to or unmarshaled from JSON directly, +// use this type as part of a [MapSlice] when dealing with JSON bytes. +type MapItem struct { + Key string + Value any +} + +func (s MapItem) marshalJSON(w *jwriter, depth int) { + w.String(s.Key) + w.RawByte(':') + + // Recurse internally for nested ordered maps so the depth guard is not lost across + // the stdjson.Marshal boundary (which would reset it and re-enable stack overflow). + if nested, ok := s.Value.(MapSlice); ok { + nested.marshalObject(w, depth+1) + + return + } + + w.Raw(stdjson.Marshal(s.Value)) +} + +func (s *MapItem) unmarshalKeyValue(in *jlexer) { + key := in.String() // consume string + value := s.asInterface(in) // consume any value, including termination tokens '}' or ']' + + if !in.Ok() { + return + } + + s.Key = key + s.Value = value +} + +func (s *MapItem) unmarshalArray(in *jlexer) []any { + if in.IsNull() { + in.Skip() + + return nil + } + + in.Delim('[') // consume token + if !in.Ok() { + return nil + } + + ret := make([]any, 0) + + for in.Ok() && !in.IsDelim(']') { + ret = append(ret, s.asInterface(in)) + } + + in.Delim(']') + if !in.Ok() { + return nil + } + + return ret +} + +// asInterface is very much like [jlexer.Lexer.Interface], but unmarshals an object +// into a [MapSlice], not a map[string]any. +// +// We have to force parsing errors somehow, since [jlexer.Lexer] doesn't let us +// set a parsing error directly. +func (s *MapItem) asInterface(in *jlexer) any { + if !in.Ok() { + return nil + } + + tok := in.PeekToken() // look-ahead what the next token looks like + kind := tok.Kind() + + switch kind { + case tokenString: + return in.String() // consume string + + case tokenNumber, tokenFloat: + return in.Number() + + case tokenBool: + return in.Bool() + + case tokenNull: + in.Null() + + return nil + + case tokenDelim: + switch tok.Delim() { + case '{': // not consumed yet + ret := make(MapSlice, 0) + ret.unmarshalObject(in) // consumes the terminating '}' + + if in.Ok() { + return ret + } + + // lexer is in an error state: will exhaust + return nil + + case '[': // not consumed yet + return s.unmarshalArray(in) // consumes the terminating ']' + default: + in.SetErr(fmt.Errorf("unexpected delimiter: %v: %w", tok, ErrStdlib)) // force error + return nil + } + + case tokenUndef: + fallthrough + default: + if in.Ok() { + in.SetErr(fmt.Errorf("unexpected token: %v: %w", tok, ErrStdlib)) // force error + } + + return nil + } +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go new file mode 100644 index 00000000..2f06b88e --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +import ( + "github.com/go-openapi/swag/jsonutils/adapters/ifaces" + "github.com/go-openapi/swag/pools" +) + +var ( + poolOfAdapters = pools.New[Adapter]() + poolOfWriters = pools.NewRedeemable[jwriter]() + poolOfLexers = pools.NewRedeemable[jlexer]() + poolOfReaders = pools.NewRedeemable[bytesReader]() +) + +// BorrowAdapter borrows an [Adapter] from the pool, recycling already allocated instances. +func BorrowAdapter() *Adapter { + return poolOfAdapters.Borrow() +} + +// BorrowAdapterIface borrows a stdlib [Adapter] and converts it directly +// to [ifaces.Adapter]. +// +// This is useful to avoid further allocations when translating the concrete type into +// an interface. +func BorrowAdapterIface() ifaces.Adapter { + return poolOfAdapters.Borrow() +} + +// RedeemAdapter redeems an [Adapter] to the pool, so it may be recycled. +func RedeemAdapter(a *Adapter) { + poolOfAdapters.Redeem(a) +} + +func RedeemAdapterIface(a ifaces.Adapter) { + concrete, ok := a.(*Adapter) + if ok { + poolOfAdapters.Redeem(concrete) + } +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go new file mode 100644 index 00000000..0dec8542 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +import ( + "fmt" + "reflect" + + "github.com/go-openapi/swag/jsonutils/adapters/ifaces" +) + +func Register(dispatcher ifaces.Registrar, opts ...Option) { + t := reflect.TypeOf(Adapter{}) + var o options + o = buildOptions(o, opts) + + dispatcher.RegisterFor( + ifaces.RegistryEntry{ + Who: fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()), + What: ifaces.AllCapabilities, + Constructor: func() ifaces.Adapter { + a := BorrowAdapter() + a.options = o + + return a + }, + Support: support, + }) +} + +func support(_ ifaces.Capability, _ any) bool { + return true +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go new file mode 100644 index 00000000..c84e02cd --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go @@ -0,0 +1,88 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +import ( + "bytes" + "encoding/json" + "strings" +) + +type jwriter struct { + buf *bytes.Buffer + err error +} + +func (w *jwriter) Reset() { + if w.buf != nil { + w.buf.Reset() + } + w.err = nil +} + +// SetErr records the first error encountered while building the JSON output. +func (w *jwriter) SetErr(err error) { + if w.err != nil { + return + } + w.err = err +} + +func (w *jwriter) RawString(s string) { + if w.err != nil { + return + } + w.buf.WriteString(s) +} + +func (w *jwriter) Raw(b []byte, err error) { + if w.err != nil { + return + } + if err != nil { + w.err = err + return + } + + _, _ = w.buf.Write(b) +} + +func (w *jwriter) RawByte(c byte) { + if w.err != nil { + return + } + w.buf.WriteByte(c) +} + +var quoteReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`) + +func (w *jwriter) String(s string) { + if w.err != nil { + return + } + // escape quotes and \ + s = quoteReplacer.Replace(s) + + _ = w.buf.WriteByte('"') + json.HTMLEscape(w.buf, []byte(s)) + _ = w.buf.WriteByte('"') +} + +// BuildBytes returns a clone of the internal buffer. +func (w *jwriter) BuildBytes() ([]byte, error) { + if w.err != nil { + return nil, w.err + } + + return bytes.Clone(w.buf.Bytes()), nil +} + +func (w *jwriter) setBuf() { + if w.buf != nil { + return + } + + buf := make([]byte, 0, sensibleBufferSize) + w.buf = bytes.NewBuffer(buf) +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/concat.go b/vendor/github.com/go-openapi/swag/jsonutils/concat.go new file mode 100644 index 00000000..2068503a --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/concat.go @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonutils + +import ( + "bytes" +) + +// nullJSON represents a JSON object with null type +var nullJSON = []byte("null") + +const comma = byte(',') + +var closers map[byte]byte + +func init() { + closers = map[byte]byte{ + '{': '}', + '[': ']', + } +} + +// ConcatJSON concatenates multiple json objects or arrays efficiently. +// +// Note that [ConcatJSON] performs a very simple (and fast) concatenation +// operation: it does not attempt to merge objects. +func ConcatJSON(blobs ...[]byte) []byte { + if len(blobs) == 0 { + return nil + } + + last := len(blobs) - 1 + for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) { + // strips trailing null objects + last-- + if last < 0 { + // there was nothing but "null"s or nil... + return nil + } + } + if last == 0 { + return blobs[0] + } + + var opening, closing byte + var idx, a int + buf := bytes.NewBuffer(nil) + + for i, b := range blobs[:last+1] { + if b == nil || bytes.Equal(b, nullJSON) { + // a null object is in the list: skip it + continue + } + if len(b) > 0 && opening == 0 { // is this an array or an object? + opening, closing = b[0], closers[b[0]] + } + + if opening != '{' && opening != '[' { + continue // don't know how to concatenate non container objects + } + + const minLengthIfNotEmpty = 3 + if len(b) < minLengthIfNotEmpty { // yep empty but also the last one, so closing this thing + if i == last && a > 0 { + _ = buf.WriteByte(closing) // never returns err != nil + } + continue + } + + idx = 0 + if a > 0 { // we need to join with a comma for everything beyond the first non-empty item + _ = buf.WriteByte(comma) // never returns err != nil + idx = 1 // this is not the first or the last so we want to drop the leading bracket + } + + if i != last { // not the last one, strip brackets + _, _ = buf.Write(b[idx : len(b)-1]) // never returns err != nil + } else { // last one, strip only the leading bracket + _, _ = buf.Write(b[idx:]) + } + a++ + } + + // somehow it ended up being empty, so provide a default value + if buf.Len() == 0 && (opening == '{' || opening == '[') { + _ = buf.WriteByte(opening) // never returns err != nil + _ = buf.WriteByte(closing) + } + + return buf.Bytes() +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/doc.go b/vendor/github.com/go-openapi/swag/jsonutils/doc.go new file mode 100644 index 00000000..3926cc58 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/doc.go @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package jsonutils provides helpers to work with JSON. +// +// These utilities work with dynamic go structures to and from JSON. +package jsonutils diff --git a/vendor/github.com/go-openapi/swag/jsonutils/json.go b/vendor/github.com/go-openapi/swag/jsonutils/json.go new file mode 100644 index 00000000..40753ce0 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/json.go @@ -0,0 +1,116 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonutils + +import ( + "bytes" + "encoding/json" + + "github.com/go-openapi/swag/jsonutils/adapters" + "github.com/go-openapi/swag/jsonutils/adapters/ifaces" +) + +// WriteJSON marshals a data structure as JSON. +// +// The difference with [json.Marshal] is that it may check among several alternatives +// to do so. +// +// See [adapters.Registrar] for more details about how to configure +// multiple serialization alternatives. +// +// NOTE: to allow types that are [easyjson.Marshaler] s to use that route to process JSON, +// you now need to register the adapter for easyjson at runtime. +func WriteJSON(value any) ([]byte, error) { + if orderedMap, isOrdered := value.(ifaces.Ordered); isOrdered { + orderedMarshaler := adapters.OrderedMarshalAdapterFor(orderedMap) + + if orderedMarshaler != nil { + defer orderedMarshaler.Redeem() + + return orderedMarshaler.OrderedMarshal(orderedMap) + } + + // no support found in registered adapters, fallback to the default (unordered) case + } + + marshaler := adapters.MarshalAdapterFor(value) + if marshaler != nil { + defer marshaler.Redeem() + + return marshaler.Marshal(value) + } + + // no support found in registered adapters, fallback to the default standard library. + // + // This only happens when tinkering with the global registry of adapters, since the default handles all the above cases. + return json.Marshal(value) // Codecov ignore // this is a safeguard not easily simulated in tests +} + +// ReadJSON unmarshals JSON data into a data structure. +// +// The difference with [json.Unmarshal] is that it may check among several alternatives +// to do so. +// +// See [adapters.Registrar] for more details about how to configure +// multiple serialization alternatives. +// +// NOTE: value must be a pointer. +// +// If the provided value implements [ifaces.SetOrdered], it is a considered an "ordered map" and [ReadJSON] +// will favor an adapter that supports the [ifaces.OrderedUnmarshal] feature, or fallback to +// an unordered behavior if none is found. +// +// NOTE: to allow types that are [easyjson.Unmarshaler] s to use that route to process JSON, +// you now need to register the adapter for easyjson at runtime. +func ReadJSON(data []byte, value any) error { + trimmedData := bytes.Trim(data, "\x00") + + if orderedMap, isOrdered := value.(ifaces.SetOrdered); isOrdered { + // if the value is an ordered map, favors support for OrderedUnmarshal. + + orderedUnmarshaler := adapters.OrderedUnmarshalAdapterFor(orderedMap) + + if orderedUnmarshaler != nil { + defer orderedUnmarshaler.Redeem() + + return orderedUnmarshaler.OrderedUnmarshal(trimmedData, orderedMap) + } + + // no support found in registered adapters, fallback to the default (unordered) case + } + + unmarshaler := adapters.UnmarshalAdapterFor(value) + if unmarshaler != nil { + defer unmarshaler.Redeem() + + return unmarshaler.Unmarshal(trimmedData, value) + } + + // no support found in registered adapters, fallback to the default standard library. + // + // This only happens when tinkering with the global registry of adapters, since the default handles all the above cases. + return json.Unmarshal(trimmedData, value) // Codecov ignore // this is a safeguard not easily simulated in tests +} + +// FromDynamicJSON turns a go value into a properly JSON typed structure. +// +// "Dynamic JSON" refers to what you get when unmarshaling JSON into an untyped any, +// i.e. objects are represented by map[string]any, arrays by []any, and +// all numbers are represented as float64. +// +// NOTE: target must be a pointer. +// +// # Maintaining the order of keys in objects +// +// If source and target implement [ifaces.Ordered] and [ifaces.SetOrdered] respectively, +// they are considered "ordered maps" and the order of keys is maintained in the +// "jsonification" process. In that case, map[string]any values are replaced by (ordered) [JSONMapSlice] ones. +func FromDynamicJSON(source, target any) error { + b, err := WriteJSON(source) + if err != nil { + return err + } + + return ReadJSON(b, target) +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/ordered_map.go b/vendor/github.com/go-openapi/swag/jsonutils/ordered_map.go new file mode 100644 index 00000000..38dd3e24 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/ordered_map.go @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonutils + +import ( + "iter" + + "github.com/go-openapi/swag/jsonutils/adapters" + "github.com/go-openapi/swag/typeutils" +) + +// JSONMapSlice represents a JSON object, with the order of keys maintained. +// +// It behaves like an ordered map, but keys can't be accessed in constant time. +type JSONMapSlice []JSONMapItem + +// OrderedItems iterates over all (key,value) pairs with the order of keys maintained. +// +// This implements the [ifaces.Ordered] interface, so that [ifaces.Adapter] s know how to marshal +// keys in the desired order. +func (s JSONMapSlice) OrderedItems() iter.Seq2[string, any] { + return func(yield func(string, any) bool) { + for _, item := range s { + if !yield(item.Key, item.Value) { + return + } + } + } +} + +// SetOrderedItems sets keys in the [JSONMapSlice] objects, as presented by +// the provided iterator. +// +// As a special case, if items is nil, this sets to receiver to a nil slice. +// +// This implements the [ifaces.SetOrdered] interface, so that [ifaces.Adapter] s know how to unmarshal +// keys in the desired order. +func (s *JSONMapSlice) SetOrderedItems(items iter.Seq2[string, any]) { + if items == nil { + // force receiver to be a nil slice + *s = nil + + return + } + + m := *s + if len(m) > 0 { + // update mode: short-circuited when unmarshaling fresh data structures + idx := make(map[string]int, len(m)) + + for i, item := range m { + idx[item.Key] = i + } + + for k, v := range items { + idx, ok := idx[k] + if ok { + m[idx].Value = v + + continue + } + + m = append(m, JSONMapItem{Key: k, Value: v}) + } + + *s = m + + return + } + + for k, v := range items { + m = append(m, JSONMapItem{Key: k, Value: v}) + } + + *s = m +} + +// MarshalJSON renders a [JSONMapSlice] as JSON bytes, preserving the order of keys. +// +// It will pick the JSON library currently configured by the [adapters.Registry] (defaults to the standard library). +func (s JSONMapSlice) MarshalJSON() ([]byte, error) { + orderedMarshaler := adapters.OrderedMarshalAdapterFor(s) + defer orderedMarshaler.Redeem() + + return orderedMarshaler.OrderedMarshal(s) +} + +// UnmarshalJSON builds a [JSONMapSlice] from JSON bytes, preserving the order of keys. +// +// Inner objects are unmarshaled as ordered [JSONMapSlice] slices and not map[string]any. +// +// It will pick the JSON library currently configured by the [adapters.Registry] (defaults to the standard library). +func (s *JSONMapSlice) UnmarshalJSON(data []byte) error { + if typeutils.IsNil(*s) { + // allow to unmarshal with a simple var declaration (nil slice) + *s = JSONMapSlice{} + } + + orderedUnmarshaler := adapters.OrderedUnmarshalAdapterFor(s) + defer orderedUnmarshaler.Redeem() + + return orderedUnmarshaler.OrderedUnmarshal(data, s) +} + +// JSONMapItem represents the value of a key in a JSON object held by [JSONMapSlice]. +// +// Notice that JSONMapItem should not be marshaled to or unmarshaled from JSON directly. +// +// Use this type as part of a [JSONMapSlice] when dealing with JSON bytes. +type JSONMapItem struct { + Key string + Value any +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils_iface.go b/vendor/github.com/go-openapi/swag/jsonutils_iface.go new file mode 100644 index 00000000..7bd4105f --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils_iface.go @@ -0,0 +1,65 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import ( + "log" + + "github.com/go-openapi/swag/jsonutils" +) + +// JSONMapSlice represents a JSON object, with the order of keys maintained +// +// Deprecated: use [jsonutils.JSONMapSlice] instead, or [yamlutils.YAMLMapSlice] if you marshal YAML. +type JSONMapSlice = jsonutils.JSONMapSlice + +// JSONMapItem represents a JSON object, with the order of keys maintained +// +// Deprecated: use [jsonutils.JSONMapItem] instead. +type JSONMapItem = jsonutils.JSONMapItem + +// WriteJSON writes json data. +// +// Deprecated: use [jsonutils.WriteJSON] instead. +func WriteJSON(data any) ([]byte, error) { return jsonutils.WriteJSON(data) } + +// ReadJSON reads json data. +// +// Deprecated: use [jsonutils.ReadJSON] instead. +func ReadJSON(data []byte, value any) error { return jsonutils.ReadJSON(data, value) } + +// DynamicJSONToStruct converts an untyped JSON structure into a target data type. +// +// Deprecated: use [jsonutils.FromDynamicJSON] instead. +func DynamicJSONToStruct(data any, target any) error { + return jsonutils.FromDynamicJSON(data, target) +} + +// ConcatJSON concatenates multiple JSON objects efficiently. +// +// Deprecated: use [jsonutils.ConcatJSON] instead. +func ConcatJSON(blobs ...[]byte) []byte { return jsonutils.ConcatJSON(blobs...) } + +// ToDynamicJSON turns a go value into a properly JSON untyped structure. +// +// It is the same as [FromDynamicJSON], but doesn't check for errors. +// +// Deprecated: this function is a misnomer and is unsafe. Use [jsonutils.FromDynamicJSON] instead. +func ToDynamicJSON(value any) any { + var res any + if err := FromDynamicJSON(value, &res); err != nil { + log.Println(err) + } + + return res +} + +// FromDynamicJSON turns a go value into a properly JSON typed structure. +// +// "Dynamic JSON" refers to what you get when unmarshaling JSON into an untyped any, +// i.e. objects are represented by map[string]any, arrays by []any, and all +// scalar values are any. +// +// Deprecated: use [jsonutils.FromDynamicJSON] instead. +func FromDynamicJSON(data, target any) error { return jsonutils.FromDynamicJSON(data, target) } diff --git a/vendor/github.com/go-openapi/swag/loading/LICENSE b/vendor/github.com/go-openapi/swag/loading/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/loading/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/loading/doc.go b/vendor/github.com/go-openapi/swag/loading/doc.go new file mode 100644 index 00000000..112c4996 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/loading/doc.go @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package loading provides tools to load a file from http or from a local file system. +// +// # Security +// +// By default, the local loader reads any path the process can access, including absolute +// paths and "file://" URIs (for example "file:///etc/passwd"). Applications that pass +// untrusted input to [LoadFromFileOrHTTP], [JSONDoc] (or to downstream consumers such as +// go-openapi/loads) must confine local loading to a trusted directory. +// +// Use [WithRoot] to do so: it resolves every requested path relative to a chosen directory +// and rejects anything that escapes it, including via symlink. It is built on [os.Root] +// and is therefore safer than passing an [os.DirFS] to [WithFS], which does not block +// symlink escapes. +// +// Remote loading uses a standard [net/http] client. +// By default it follows redirects and performs no destination filtering — exactly like [net/http.DefaultClient]. +// +// A caller-controlled URL may therefore reach internal services or cloud metadata endpoints +// (server-side request forgery). +// +// This package does not, and should not, embed a network policy: +// when the URL may derive from untrusted input, supply a restricted client with +// [WithHTTPClient] whose transport rejects unwanted destinations at dial time — which also +// covers redirects and DNS rebinding. +// See the example on [LoadFromFileOrHTTP]. +package loading diff --git a/vendor/github.com/go-openapi/swag/loading/errors.go b/vendor/github.com/go-openapi/swag/loading/errors.go new file mode 100644 index 00000000..b3964289 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/loading/errors.go @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package loading + +type loadingError string + +const ( + // ErrLoader is an error raised by the file loader utility + ErrLoader loadingError = "loader error" +) + +func (e loadingError) Error() string { + return string(e) +} diff --git a/vendor/github.com/go-openapi/swag/loading/json.go b/vendor/github.com/go-openapi/swag/loading/json.go new file mode 100644 index 00000000..59db12f5 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/loading/json.go @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package loading + +import ( + "encoding/json" + "errors" + "path/filepath" +) + +// JSONMatcher matches json for a file loader. +func JSONMatcher(path string) bool { + ext := filepath.Ext(path) + return ext == ".json" || ext == ".jsn" || ext == ".jso" +} + +// JSONDoc loads a json document from either a file or a remote url. +func JSONDoc(path string, opts ...Option) (json.RawMessage, error) { + data, err := LoadFromFileOrHTTP(path, opts...) + if err != nil { + return nil, errors.Join(err, ErrLoader) + } + return json.RawMessage(data), nil +} diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading/loading.go similarity index 55% rename from vendor/github.com/go-openapi/swag/loading.go rename to vendor/github.com/go-openapi/swag/loading/loading.go index 658a24b7..0b38ac1e 100644 --- a/vendor/github.com/go-openapi/swag/loading.go +++ b/vendor/github.com/go-openapi/swag/loading/loading.go @@ -1,54 +1,30 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 -package swag +package loading import ( + "context" + "embed" "fmt" "io" "log" "net/http" "net/url" - "os" "path" "path/filepath" "runtime" "strings" - "time" ) -// LoadHTTPTimeout the default timeout for load requests -var LoadHTTPTimeout = 30 * time.Second - -// LoadHTTPBasicAuthUsername the username to use when load requests require basic auth -var LoadHTTPBasicAuthUsername = "" - -// LoadHTTPBasicAuthPassword the password to use when load requests require basic auth -var LoadHTTPBasicAuthPassword = "" - -// LoadHTTPCustomHeaders an optional collection of custom HTTP headers for load requests -var LoadHTTPCustomHeaders = map[string]string{} - -// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in -func LoadFromFileOrHTTP(pth string) ([]byte, error) { - return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(pth) -} - -// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in -// timeout arg allows for per request overriding of the request timeout -func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration) ([]byte, error) { - return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(timeout))(pth) +// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in. +// +// Security: by default a local path is read with no confinement, so a caller-controlled path +// (including a "file://" URI or an absolute path) may read any file the process can access. +// When the path may derive from untrusted input, confine local loading with [WithRoot]. +func LoadFromFileOrHTTP(pth string, opts ...Option) ([]byte, error) { + o := optionsWithDefaults(opts) + return LoadStrategy(pth, o.ReadFileFunc(), loadHTTPBytes(opts...), opts...)(pth) } // LoadStrategy returns a loader function for a given path or URI. @@ -81,10 +57,15 @@ func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration) ([]byte, e // - `file://host/folder/file` becomes an UNC path like `\\host\folder\file` (no port specification is supported) // - `file:///c:/folder/file` becomes `C:\folder\file` // - `file://c:/folder/file` is tolerated (without leading `/`) and becomes `c:\folder\file` -func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) { - if strings.HasPrefix(pth, "http") { +func LoadStrategy(pth string, local, remote func(string) ([]byte, error), opts ...Option) func(string) ([]byte, error) { + if hasHTTPScheme(pth) { return remote } + o := optionsWithDefaults(opts) + _, isEmbedFS := o.fs.(embed.FS) + // any loader backed by an fs.FS or an os.Root consumes forward-slash paths on every + // platform, so it must not go through the windows-native file:// preprocessing below. + isFSBacked := o.fs != nil || o.root != "" return func(p string) ([]byte, error) { upth, err := url.PathUnescape(p) @@ -92,19 +73,25 @@ func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(s return nil, err } - if !strings.HasPrefix(p, `file://`) { + cpth, hasPrefix := strings.CutPrefix(upth, "file://") + if !hasPrefix || isFSBacked || runtime.GOOS != "windows" { + // crude processing: trim the file:// prefix. This leaves full URIs with a host with a (mostly) unexpected result // regular file path provided: just normalize slashes - return local(filepath.FromSlash(upth)) - } + if isEmbedFS { + // embed.FS always uses "/" as separator, even on windows, and rejects leading "./" or "/". + return local(strings.TrimLeft(filepath.ToSlash(cpth), "./")) // remove invalid leading characters for embed FS + } - if runtime.GOOS != "windows" { - // crude processing: this leaves full URIs with a host with a (mostly) unexpected result - upth = strings.TrimPrefix(upth, `file://`) + if isFSBacked { + // other fs.FS (e.g. os.DirFS) and os.Root loaders also use "/" on every platform. + // Escaping paths (absolute, "..", escaping symlinks) are rejected by the loader, not rewritten here. + return local(filepath.ToSlash(cpth)) + } - return local(filepath.FromSlash(upth)) + return local(filepath.FromSlash(cpth)) } - // windows-only pre-processing of file://... URIs + // windows-only pre-processing of file://... URIs, excluding embed.FS // support for canonical file URIs on windows. u, err := url.Parse(filepath.ToSlash(upth)) @@ -139,19 +126,44 @@ func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(s } } -func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { +// hasHTTPScheme reports whether pth is an absolute URL with an http or https scheme, +// selecting the remote loader. The comparison is case-insensitive, as URL schemes are. +// +// Requiring the "://" separator (rather than a bare "http" prefix) avoids misrouting a +// local file whose name merely starts with "http" (e.g. "httpbin.json") to the remote loader. +func hasHTTPScheme(pth string) bool { + for _, scheme := range [...]string{"http://", "https://"} { + if len(pth) >= len(scheme) && strings.EqualFold(pth[:len(scheme)], scheme) { + return true + } + } + + return false +} + +func loadHTTPBytes(opts ...Option) func(path string) ([]byte, error) { + o := optionsWithDefaults(opts) + return func(path string) ([]byte, error) { - client := &http.Client{Timeout: timeout} - req, err := http.NewRequest(http.MethodGet, path, nil) //nolint:noctx + client := o.client + timeoutCtx := context.Background() + var cancel func() + + if o.httpTimeout > 0 { + timeoutCtx, cancel = context.WithTimeout(timeoutCtx, o.httpTimeout) + defer cancel() + } + + req, err := http.NewRequestWithContext(timeoutCtx, http.MethodGet, path, nil) if err != nil { return nil, err } - if LoadHTTPBasicAuthUsername != "" && LoadHTTPBasicAuthPassword != "" { - req.SetBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword) + if o.basicAuthUsername != "" && o.basicAuthPassword != "" { + req.SetBasicAuth(o.basicAuthUsername, o.basicAuthPassword) } - for key, val := range LoadHTTPCustomHeaders { + for key, val := range o.customHeaders { req.Header.Set(key, val) } diff --git a/vendor/github.com/go-openapi/swag/loading/options.go b/vendor/github.com/go-openapi/swag/loading/options.go new file mode 100644 index 00000000..2c128231 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/loading/options.go @@ -0,0 +1,170 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package loading + +import ( + "errors" + "io/fs" + "net/http" + "os" + "time" +) + +type ( + // Option provides options for loading a file over HTTP or from a file. + Option func(*options) + + httpOptions struct { + httpTimeout time.Duration + basicAuthUsername string + basicAuthPassword string + customHeaders map[string]string + client *http.Client + } + + fileOptions struct { + fs fs.ReadFileFS + root string // when non-empty, local reads are confined to this directory via os.Root + } + + options struct { + httpOptions + fileOptions + } +) + +func (fo fileOptions) ReadFileFunc() func(string) ([]byte, error) { + if fo.root != "" { + root := fo.root + + return func(name string) ([]byte, error) { + r, err := os.OpenRoot(root) + if err != nil { + return nil, errors.Join(err, ErrLoader) + } + defer func() { _ = r.Close() }() + + return r.ReadFile(name) + } + } + + if fo.fs == nil { + return os.ReadFile + } + + return fo.fs.ReadFile +} + +// WithTimeout sets a timeout for the remote file loader. +// +// The default timeout is 30s. +func WithTimeout(timeout time.Duration) Option { + return func(o *options) { + o.httpTimeout = timeout + } +} + +// WithBasicAuth sets a basic authentication scheme for the remote file loader. +func WithBasicAuth(username, password string) Option { + return func(o *options) { + o.basicAuthUsername = username + o.basicAuthPassword = password + } +} + +// WithCustomHeaders sets custom headers for the remote file loader. +func WithCustomHeaders(headers map[string]string) Option { + return func(o *options) { + if o.customHeaders == nil { + o.customHeaders = make(map[string]string, len(headers)) + } + + for header, value := range headers { + o.customHeaders[header] = value + } + } +} + +// WithHTTPClient overrides the default HTTP client used to fetch a remote file. +// +// By default, [http.DefaultClient] is used. +func WithHTTPClient(client *http.Client) Option { + return func(o *options) { + o.client = client + } +} + +// WithFS sets a file system for the local file loader. +// +// If the provided file system is a [fs.ReadFileFS], the ReadFile function is used. +// Otherwise, ReadFile is wrapped using [fs.ReadFile]. +// +// By default, the file system is the one provided by the os package. +// +// For example, this may be set to consume from an embedded file system, or a rooted FS. +// +// WithFS and [WithRoot] are mutually exclusive: the last one applied wins. +// +// Security note: a file system built from [os.DirFS] confines paths but does NOT protect +// against symlinks that escape the root. To load from a directory derived from untrusted +// input, prefer [WithRoot], which is symlink-escape resistant. +func WithFS(filesystem fs.FS) Option { + return func(o *options) { + o.root = "" // last-wins vs WithRoot + if rfs, ok := filesystem.(fs.ReadFileFS); ok { + o.fs = rfs + + return + } + o.fs = readFileFS{FS: filesystem} + } +} + +// WithRoot confines local file loading to dir. +// +// Every requested path is resolved relative to dir, and any path that would escape dir — +// whether through an absolute path, ".." traversal, or a symlink pointing outside dir — is +// rejected. This is built on [os.Root] and is therefore resistant to the symlink escapes +// that a plain [os.DirFS] does not prevent. +// +// WithRoot is the recommended option when loading specs from a location derived from +// untrusted input. It applies to local loading only and has no effect on remote +// (http/https) loading. WithRoot and [WithFS] are mutually exclusive: the last one applied +// wins. +// +// Note: [os.Root] confines path resolution but does not, by itself, protect against +// traversal of mount/bind boundaries, /proc special files, or device files. Point WithRoot +// at a directory that holds only the documents you intend to expose. +func WithRoot(dir string) Option { + return func(o *options) { + o.root = dir + o.fs = nil // last-wins vs WithFS + } +} + +type readFileFS struct { + fs.FS +} + +func (r readFileFS) ReadFile(name string) ([]byte, error) { + return fs.ReadFile(r.FS, name) +} + +func optionsWithDefaults(opts []Option) options { + const defaultTimeout = 30 * time.Second + + o := options{ + // package level defaults + httpOptions: httpOptions{ + httpTimeout: defaultTimeout, + client: http.DefaultClient, + }, + } + + for _, apply := range opts { + apply(&o) + } + + return o +} diff --git a/vendor/github.com/go-openapi/swag/loading/yaml.go b/vendor/github.com/go-openapi/swag/loading/yaml.go new file mode 100644 index 00000000..3ebb5366 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/loading/yaml.go @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package loading + +import ( + "encoding/json" + "path/filepath" + + "github.com/go-openapi/swag/yamlutils" +) + +// YAMLMatcher matches yaml for a file loader. +func YAMLMatcher(path string) bool { + ext := filepath.Ext(path) + return ext == ".yaml" || ext == ".yml" +} + +// YAMLDoc loads a yaml document from either http or a file and converts it to json. +func YAMLDoc(path string, opts ...Option) (json.RawMessage, error) { + yamlDoc, err := YAMLData(path, opts...) + if err != nil { + return nil, err + } + + return yamlutils.YAMLToJSON(yamlDoc) +} + +// YAMLData loads a yaml document from either http or a file. +func YAMLData(path string, opts ...Option) (any, error) { + data, err := LoadFromFileOrHTTP(path, opts...) + if err != nil { + return nil, err + } + + return yamlutils.BytesToYAMLDoc(data) +} diff --git a/vendor/github.com/go-openapi/swag/loading_iface.go b/vendor/github.com/go-openapi/swag/loading_iface.go new file mode 100644 index 00000000..78dadfcc --- /dev/null +++ b/vendor/github.com/go-openapi/swag/loading_iface.go @@ -0,0 +1,93 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import ( + "encoding/json" + "time" + + "github.com/go-openapi/swag/loading" +) + +var ( + // Package-level defaults for the file loading utilities (deprecated). + + // LoadHTTPTimeout the default timeout for load requests. + // + // Deprecated: use [loading.WithTimeout] instead. + LoadHTTPTimeout = 30 * time.Second + + // LoadHTTPBasicAuthUsername the username to use when load requests require basic auth. + // + // Deprecated: use [loading.WithBasicAuth] instead. + LoadHTTPBasicAuthUsername = "" + + // LoadHTTPBasicAuthPassword the password to use when load requests require basic auth. + // + // Deprecated: use [loading.WithBasicAuth] instead. + LoadHTTPBasicAuthPassword = "" + + // LoadHTTPCustomHeaders an optional collection of custom HTTP headers for load requests. + // + // Deprecated: use [loading.WithCustomHeaders] instead. + LoadHTTPCustomHeaders = map[string]string{} +) + +// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the provided path. +// +// Deprecated: use [loading.LoadFromFileOrHTTP] instead. +func LoadFromFileOrHTTP(pth string, opts ...loading.Option) ([]byte, error) { + return loading.LoadFromFileOrHTTP(pth, loadingOptionsWithDefaults(opts)...) +} + +// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in +// timeout arg allows for per request overriding of the request timeout. +// +// Deprecated: use [loading.LoadFileOrHTTP] with the [loading.WithTimeout] option instead. +func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration, opts ...loading.Option) ([]byte, error) { + opts = append(opts, loading.WithTimeout(timeout)) + + return LoadFromFileOrHTTP(pth, opts...) +} + +// LoadStrategy returns a loader function for a given path or URL. +// +// Deprecated: use [loading.LoadStrategy] instead. +func LoadStrategy(pth string, local, remote func(string) ([]byte, error), opts ...loading.Option) func(string) ([]byte, error) { + return loading.LoadStrategy(pth, local, remote, loadingOptionsWithDefaults(opts)...) +} + +// YAMLMatcher matches yaml for a file loader. +// +// Deprecated: use [loading.YAMLMatcher] instead. +func YAMLMatcher(path string) bool { return loading.YAMLMatcher(path) } + +// YAMLDoc loads a yaml document from either http or a file and converts it to json. +// +// Deprecated: use [loading.YAMLDoc] instead. +func YAMLDoc(path string) (json.RawMessage, error) { + return loading.YAMLDoc(path) +} + +// YAMLData loads a yaml document from either http or a file. +// +// Deprecated: use [loading.YAMLData] instead. +func YAMLData(path string) (any, error) { + return loading.YAMLData(path) +} + +// loadingOptionsWithDefaults bridges deprecated default settings that use package-level variables, +// with the recommended use of loading.Option. +func loadingOptionsWithDefaults(opts []loading.Option) []loading.Option { + const defaultOptions = 3 + o := make([]loading.Option, 0, defaultOptions+len(opts)) + o = append(o, []loading.Option{ + loading.WithTimeout(LoadHTTPTimeout), + loading.WithBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword), + loading.WithCustomHeaders(LoadHTTPCustomHeaders), + }...) + o = append(o, opts...) + + return o +} diff --git a/vendor/github.com/go-openapi/swag/BENCHMARK.md b/vendor/github.com/go-openapi/swag/mangling/BENCHMARK.md similarity index 53% rename from vendor/github.com/go-openapi/swag/BENCHMARK.md rename to vendor/github.com/go-openapi/swag/mangling/BENCHMARK.md index e7f28ed6..abe6e953 100644 --- a/vendor/github.com/go-openapi/swag/BENCHMARK.md +++ b/vendor/github.com/go-openapi/swag/mangling/BENCHMARK.md @@ -1,12 +1,10 @@ -# Benchmarks - -## Name mangling utilities +# Benchmarking name mangling utilities ```bash go test -bench XXX -run XXX -benchtime 30s ``` -### Benchmarks at b3e7a5386f996177e4808f11acb2aa93a0f660df +## Benchmarks at `b3e7a5386f996177e4808f11acb2aa93a0f660df` ``` goos: linux @@ -21,7 +19,7 @@ BenchmarkToXXXName/ToHumanNameLower-4 895334 40354 ns/op 10472 B/op BenchmarkToXXXName/ToHumanNameTitle-4 882441 40678 ns/op 10566 B/op 749 allocs/op ``` -### Benchmarks after PR #79 +## Benchmarks after PR #79 ~ x10 performance improvement and ~ /100 memory allocations. @@ -50,3 +48,43 @@ BenchmarkToXXXName/ToCommandName-16 32256634 1137 ns/op 147 B/op BenchmarkToXXXName/ToHumanNameLower-16 18599661 1946 ns/op 92 B/op 6 allocs/op BenchmarkToXXXName/ToHumanNameTitle-16 17581353 2054 ns/op 105 B/op 6 allocs/op ``` + +## Benchmarks at `d7d2d1b895f5b6747afaff312dd2a402e69e818b` + +go1.24 + +``` +goos: linux +goarch: amd64 +pkg: github.com/go-openapi/swag +cpu: AMD Ryzen 7 5800X 8-Core Processor +BenchmarkToXXXName/ToGoName-16 19757858 1881 ns/op 42 B/op 5 allocs/op +BenchmarkToXXXName/ToVarName-16 17494111 2094 ns/op 74 B/op 7 allocs/op +BenchmarkToXXXName/ToFileName-16 28161226 1492 ns/op 158 B/op 7 allocs/op +BenchmarkToXXXName/ToCommandName-16 23787333 1489 ns/op 158 B/op 7 allocs/op +BenchmarkToXXXName/ToHumanNameLower-16 17537257 2030 ns/op 103 B/op 6 allocs/op +BenchmarkToXXXName/ToHumanNameTitle-16 16977453 2156 ns/op 105 B/op 6 allocs/op +``` + +## Benchmarks after PR #106 + +Moving the scope of everything down to a struct allowed to reduce a bit garbage and pooling. + +On top of that, ToGoName (and thus ToVarName) have been subject to a minor optimization, removing a few allocations. + +Overall timings improve by ~ -10%. + +go1.24 + +``` +goos: linux +goarch: amd64 +pkg: github.com/go-openapi/swag/mangling +cpu: AMD Ryzen 7 5800X 8-Core Processor +BenchmarkToXXXName/ToGoName-16 22496130 1618 ns/op 31 B/op 3 allocs/op +BenchmarkToXXXName/ToVarName-16 22538068 1618 ns/op 33 B/op 3 allocs/op +BenchmarkToXXXName/ToFileName-16 27722977 1236 ns/op 105 B/op 6 allocs/op +BenchmarkToXXXName/ToCommandName-16 27967395 1258 ns/op 105 B/op 6 allocs/op +BenchmarkToXXXName/ToHumanNameLower-16 18587901 1917 ns/op 103 B/op 6 allocs/op +BenchmarkToXXXName/ToHumanNameTitle-16 17193208 2019 ns/op 108 B/op 7 allocs/op +``` diff --git a/vendor/github.com/go-openapi/swag/mangling/LICENSE b/vendor/github.com/go-openapi/swag/mangling/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/mangling/doc.go b/vendor/github.com/go-openapi/swag/mangling/doc.go new file mode 100644 index 00000000..ce0d8904 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/doc.go @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package mangling provides name mangling capabilities. +// +// Name mangling is an important stage when generating code: +// it helps construct safe program identifiers that abide by the language rules +// and play along with linters. +// +// Examples: +// +// Suppose we get an object name taken from an API spec: "json_object", +// +// We may generate a legit go type name using [NameMangler.ToGoName]: "JsonObject". +// +// We may then locate this type in a source file named using [NameMangler.ToFileName]: "json_object.go". +// +// The methods exposed by the NameMangler are used to generate code in many different contexts, such as: +// +// - generating exported or unexported go identifiers from a JSON schema or an API spec +// - generating file names +// - generating human-readable comments for types and variables +// - generating JSON-like API identifiers from go code +// - ... +package mangling diff --git a/vendor/github.com/go-openapi/swag/mangling/initialism_index.go b/vendor/github.com/go-openapi/swag/mangling/initialism_index.go new file mode 100644 index 00000000..e5b70c14 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/initialism_index.go @@ -0,0 +1,270 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling + +import ( + "sort" + "strings" + "unicode" + "unicode/utf8" +) + +// DefaultInitialisms returns all the initialisms configured by default for this package. +// +// # Motivation +// +// Common initialisms are acronyms for which the ordinary camel-casing rules are altered and +// for which we retain the original case. +// +// This is largely specific to the go naming conventions enforced by golint (now revive). +// +// # Example +// +// In go, "id" is a good-looking identifier, but "Id" is not and "ID" is preferred +// (notice that this stems only from conventions: the go compiler accepts all of these). +// +// Similarly, we may use "http", but not "Http". In this case, "HTTP" is preferred. +// +// # Reference and customization +// +// The default list of these casing-style exceptions is taken from the [github.com/mgechev/revive] linter for go: +// https://github.com/mgechev/revive/blob/master/lint/name.go#L93 +// +// There are a few additions to the original list, such as IPv4, IPv6 and OAI ("OpenAPI"). +// +// For these additions, "IPv4" would be preferred to "Ipv4" or "IPV4", and "OAI" to "Oai" +// +// You may redefine this list entirely using the mangler option [WithInitialisms], or simply add extra definitions +// using [WithAdditionalInitialisms]. +// +// # Mixed-case and plurals +// +// Notice that initialisms are not necessarily fully upper-cased: a mixed-case initialism indicates the preferred casing. +// +// Obviously, lower-case only initialisms do not make a lot of sense: if lower-case only initialisms are added, +// they will be considered fully capitalized. +// +// Plural forms use mixed case like "IDs". And so do values like "IPv4" or "IPv6". +// +// The [NameMangler] automatically detects simple plurals for words such as "IDs" or "APIs", +// so you don't need to configure these variants. +// +// At this moment, it doesn't support pluralization of terms that ends with an 's' (or 'S'), since there is +// no clear consensus on whether a word like DNS should be pluralized as DNSes or remain invariant. +// The [NameMangler] consider those invariant. Therefore DNSs or DNSes are not recognized as plurals for DNS. +// +// Besids, we don't want to support pluralization of terms which would otherwise conflict with another one, +// like "HTTPs" vs "HTTPS". All these should be considered invariant. Hence: "Https" matches "HTTPS" and +// "HTTPSS" is "HTTPS" followed by "S". +func DefaultInitialisms() []string { + return []string{ + "ACL", + "API", + "ASCII", + "CPU", + "CSS", + "DNS", + "EOF", + "GUID", + "HTML", + "HTTPS", + "HTTP", + "ID", + "IP", + "IPv4", // prefer the mixed case outcome IPv4 over the capitalized IPV4 + "IPv6", // prefer the mixed case outcome IPv6 over the capitalized IPV6 + "JSON", + "LHS", + "OAI", + "QPS", + "RAM", + "RHS", + "RPC", + "SLA", + "SMTP", + "SQL", + "SSH", + "TCP", + "TLS", + "TTL", + "UDP", + "UI", + "UID", + "UUID", + "URI", + "URL", + "UTF8", + "VM", + "XML", + "XMPP", + "XSRF", + "XSS", + } +} + +type indexOfInitialisms struct { + initialismsCache + + index map[string]struct{} +} + +func newIndexOfInitialisms() *indexOfInitialisms { + return &indexOfInitialisms{ + index: make(map[string]struct{}), + } +} + +func (m *indexOfInitialisms) add(words ...string) *indexOfInitialisms { + for _, word := range words { + // sanitization of injected words: trimmed from blanks, and must start with a letter + trimmed := strings.TrimSpace(word) + + firstRune, _ := utf8.DecodeRuneInString(trimmed) + if !unicode.IsLetter(firstRune) { + continue + } + + // Initialisms are case-sensitive. This means that we support mixed-case words. + // However, if specified as a lower-case string, the initialism should be fully capitalized. + if trimmed == strings.ToLower(trimmed) { + m.index[strings.ToUpper(trimmed)] = struct{}{} + + continue + } + + m.index[trimmed] = struct{}{} + } + return m +} + +func (m *indexOfInitialisms) sorted() []string { + result := make([]string, 0, len(m.index)) + for k := range m.index { + result = append(result, k) + } + sort.Sort(sort.Reverse(byInitialism(result))) + return result +} + +func (m *indexOfInitialisms) buildCache() { + m.build(m.sorted(), m.pluralForm) +} + +// initialismsCache caches all needed pre-computed and converted initialism entries, +// in the desired resolution order. +type initialismsCache struct { + initialisms []string + initialismsRunes [][]rune + initialismsUpperCased [][]rune // initialisms cached in their trimmed, upper-cased version + initialismsPluralForm []pluralForm +} + +func (c *initialismsCache) build(in []string, pluralfunc func(string) pluralForm) { + c.initialisms = in + c.initialismsRunes = asRunes(c.initialisms) + c.initialismsUpperCased = asUpperCased(c.initialisms) + c.initialismsPluralForm = asPluralForms(c.initialisms, pluralfunc) +} + +// pluralForm denotes the kind of pluralization to be used for initialisms. +// +// At this moment, initialisms are either invariant or follow a simple plural form with an +// extra (lower case) "s". +type pluralForm uint8 + +const ( + notPlural pluralForm = iota + invariantPlural + simplePlural +) + +func (f pluralForm) String() string { + switch f { + case notPlural: + return "notPlural" + case invariantPlural: + return "invariantPlural" + case simplePlural: + return "simplePlural" + default: + return "" + } +} + +// pluralForm indicates how we want to pluralize a given initialism. +// +// Besides configured invariant forms (like HTTP and HTTPS), +// an initialism is normally pluralized by adding a single 's', like in IDs. +// +// Initialisms ending with an 'S' or an 's' are configured as invariant (we don't +// support plural forms like CSSes or DNSes, however the mechanism could be extended to +// do just that). +func (m *indexOfInitialisms) pluralForm(key string) pluralForm { + if _, ok := m.index[key]; !ok { + return notPlural + } + + if strings.HasSuffix(strings.ToUpper(key), "S") { + return invariantPlural + } + + if _, ok := m.index[key+"s"]; ok { + return invariantPlural + } + + if _, ok := m.index[key+"S"]; ok { + return invariantPlural + } + + return simplePlural +} + +type byInitialism []string + +func (s byInitialism) Len() int { + return len(s) +} +func (s byInitialism) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Less specifies the order in which initialisms are prioritized: +// 1. match longest first +// 2. when equal length, match in reverse lexicographical order, lower case match comes first +func (s byInitialism) Less(i, j int) bool { + if len(s[i]) != len(s[j]) { + return len(s[i]) < len(s[j]) + } + + return s[i] < s[j] +} + +func asRunes(in []string) [][]rune { + out := make([][]rune, len(in)) + for i, initialism := range in { + out[i] = []rune(initialism) + } + + return out +} + +func asUpperCased(in []string) [][]rune { + out := make([][]rune, len(in)) + + for i, initialism := range in { + out[i] = []rune(upper(trim(initialism))) + } + + return out +} + +// asPluralForms bakes an index of pluralization support. +func asPluralForms(in []string, pluralFunc func(string) pluralForm) []pluralForm { + out := make([]pluralForm, len(in)) + for i, initialism := range in { + out[i] = pluralFunc(initialism) + } + + return out +} diff --git a/vendor/github.com/go-openapi/swag/mangling/name_lexem.go b/vendor/github.com/go-openapi/swag/mangling/name_lexem.go new file mode 100644 index 00000000..bc837e3b --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/name_lexem.go @@ -0,0 +1,186 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling + +import ( + "bytes" + "strings" + "unicode" + "unicode/utf8" +) + +type ( + lexemKind uint8 + + nameLexem struct { + original string + matchedInitialism string + kind lexemKind + } +) + +const ( + lexemKindCasualName lexemKind = iota + lexemKindInitialismName +) + +func newInitialismNameLexem(original, matchedInitialism string) nameLexem { + return nameLexem{ + kind: lexemKindInitialismName, + original: original, + matchedInitialism: matchedInitialism, + } +} + +func newCasualNameLexem(original string) nameLexem { + return nameLexem{ + kind: lexemKindCasualName, + original: trim(original), // TODO: save on calls to trim + } +} + +// WriteTitleized writes the titleized lexeme to a bytes.Buffer. +// +// If the first letter cannot be capitalized, it doesn't write anything and return false, +// so the caller may attempt some workaround strategy. +func (l nameLexem) WriteTitleized(w *bytes.Buffer, alwaysUpper bool) bool { + if l.kind == lexemKindInitialismName { + w.WriteString(l.matchedInitialism) + + return true + } + + if len(l.original) == 0 { + return true + } + + if len(l.original) == 1 { + // identifier is too short: casing will depend on the context + firstByte := l.original[0] + switch { + case 'A' <= firstByte && firstByte <= 'Z': + // safe + w.WriteByte(firstByte) + + return true + case alwaysUpper && 'a' <= firstByte && firstByte <= 'z': + w.WriteByte(firstByte - 'a' + 'A') + + return true + default: + + // not a letter: skip and let the caller decide + return false + } + } + + if firstByte := l.original[0]; firstByte < utf8.RuneSelf { + // ASCII + switch { + case 'A' <= firstByte && firstByte <= 'Z': + // already an upper case letter + w.WriteString(l.original) + + return true + case 'a' <= firstByte && firstByte <= 'z': + w.WriteByte(firstByte - 'a' + 'A') + w.WriteString(l.original[1:]) + + return true + default: + // not a good candidate: doesn't start with a letter + return false + } + } + + // unicode + firstRune, idx := utf8.DecodeRuneInString(l.original) + if !unicode.IsLetter(firstRune) || !unicode.IsUpper(unicode.ToUpper(firstRune)) { + // not a good candidate: doesn't start with a letter + // or a rune for which case doesn't make sense (e.g. East-Asian runes etc) + return false + } + + rest := l.original[idx:] + w.WriteRune(unicode.ToUpper(firstRune)) + w.WriteString(strings.ToLower(rest)) + + return true +} + +// WriteLower is like write titleized but it writes a lower-case version of the lexeme. +// +// Similarly, there is no writing if the casing of the first rune doesn't make sense. +func (l nameLexem) WriteLower(w *bytes.Buffer, alwaysLower bool) bool { + if l.kind == lexemKindInitialismName { + w.WriteString(lower(l.matchedInitialism)) + + return true + } + + if len(l.original) == 0 { + return true + } + + if len(l.original) == 1 { + // identifier is too short: casing will depend on the context + firstByte := l.original[0] + switch { + case 'a' <= firstByte && firstByte <= 'z': + // safe + w.WriteByte(firstByte) + + return true + case alwaysLower && 'A' <= firstByte && firstByte <= 'Z': + w.WriteByte(firstByte - 'A' + 'a') + + return true + default: + + // not a letter: skip and let the caller decide + return false + } + } + + if firstByte := l.original[0]; firstByte < utf8.RuneSelf { + // ASCII + switch { + case 'a' <= firstByte && firstByte <= 'z': + // already a lower case letter + w.WriteString(l.original) + + return true + case 'A' <= firstByte && firstByte <= 'Z': + w.WriteByte(firstByte - 'A' + 'a') + w.WriteString(l.original[1:]) + + return true + default: + // not a good candidate: doesn't start with a letter + return false + } + } + + // unicode + firstRune, idx := utf8.DecodeRuneInString(l.original) + if !unicode.IsLetter(firstRune) || !unicode.IsLower(unicode.ToLower(firstRune)) { + // not a good candidate: doesn't start with a letter + // or a rune for which case doesn't make sense (e.g. East-Asian runes etc) + return false + } + + rest := l.original[idx:] + w.WriteRune(unicode.ToLower(firstRune)) + w.WriteString(rest) + + return true +} + +func (l nameLexem) GetOriginal() string { + return l.original +} + +func (l nameLexem) IsInitialism() bool { + return l.kind == lexemKindInitialismName +} diff --git a/vendor/github.com/go-openapi/swag/mangling/name_mangler.go b/vendor/github.com/go-openapi/swag/mangling/name_mangler.go new file mode 100644 index 00000000..da685681 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/name_mangler.go @@ -0,0 +1,370 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling + +import ( + "strings" + "unicode" +) + +// NameMangler knows how to transform sentences or words into +// identifiers that are a better fit in contexts such as: +// +// - unexported or exported go variable identifiers +// - file names +// - camel cased identifiers +// - ... +// +// The [NameMangler] is safe for concurrent use, save for its [NameMangler.AddInitialisms] method, +// which is not. +// +// # Known limitations +// +// At this moment, the [NameMangler] doesn't play well with "all caps" text: +// +// unless every single upper-cased word is declared as an initialism, capitalized words would generally +// not be transformed with the expected result, e.g. +// +// ToFileName("THIS_IS_ALL_CAPS") +// +// yields the weird outcome +// +// "t_h_i_s_i_s_a_l_l_c_a_p_s" +type NameMangler struct { + options + + index *indexOfInitialisms + + splitter splitter + splitterWithPostSplit splitter + + _ struct{} +} + +// NewNameMangler builds a name mangler ready to convert strings. +// +// The default name mangler is configured with default common initialisms and all default options. +func NewNameMangler(opts ...Option) NameMangler { + m := NameMangler{ + options: optionsWithDefaults(opts), + index: newIndexOfInitialisms(), + } + m.addInitialisms(m.commonInitialisms...) + + // a splitter that returns matches lexemes as ready-to-assemble strings: + // details of the lexemes are redeemed. + m.splitter = newSplitter( + withInitialismsCache(&m.index.initialismsCache), + withReplaceFunc(m.replaceFunc), + ) + + // a splitter that returns matches lexemes ready for post-processing + m.splitterWithPostSplit = newSplitter( + withInitialismsCache(&m.index.initialismsCache), + withReplaceFunc(m.replaceFunc), + withPostSplitInitialismCheck, + ) + + return m +} + +// AddInitialisms declares extra initialisms to the mangler. +// +// It declares extra words as "initialisms" (i.e. words that won't be camel cased or titled cased), +// on top of the existing list of common initialisms (such as ID, HTTP...). +// +// Added words must start with a (unicode) letter. If some don't, they are ignored. +// Added words are either fully capitalized or mixed-cased. Lower-case only words are considered capitalized. +// +// It is typically used just after initializing the [NameMangler]. +// +// When all initialisms are known at the time the mangler is initialized, it is preferable to +// use [NewNameMangler] with the option [WithAdditionalInitialisms]. +// +// Adding initialisms mutates the mangler and should not be carried out concurrently with other calls to the mangler. +func (m *NameMangler) AddInitialisms(words ...string) { + m.addInitialisms(words...) +} + +// Initialisms renders the list of initialisms supported by this mangler. +func (m *NameMangler) Initialisms() []string { + return m.index.initialisms +} + +// Camelize a single word. +// +// Example: +// +// - "HELLO" and "hello" become "Hello". +func (m NameMangler) Camelize(word string) string { + ru := []rune(word) + + switch len(ru) { + case 0: + return "" + case 1: + return string(unicode.ToUpper(ru[0])) + default: + camelized := poolOfBuffers.BorrowBuffer(len(word)) + camelized.Grow(len(word)) + defer func() { + poolOfBuffers.RedeemBuffer(camelized) + }() + + camelized.WriteRune(unicode.ToUpper(ru[0])) + for _, ru := range ru[1:] { + camelized.WriteRune(unicode.ToLower(ru)) + } + + return camelized.String() + } +} + +// ToFileName generates a suitable snake-case file name from a sentence. +// +// It lower-cases everything with underscore (_) as a word separator. +// +// Examples: +// +// - "Hello, Swagger" becomes "hello_swagger" +// - "HelloSwagger" becomes "hello_swagger" +func (m NameMangler) ToFileName(name string) string { + inptr := m.split(name) + in := *inptr + out := make([]string, 0, len(in)) + + for _, w := range in { + out = append(out, lower(w)) + } + poolOfStrings.RedeemStrings(inptr) + + return strings.Join(out, "_") +} + +// ToCommandName generates a suitable CLI command name from a sentence. +// +// It lower-cases everything with dash (-) as a word separator. +// +// Examples: +// +// - "Hello, Swagger" becomes "hello-swagger" +// - "HelloSwagger" becomes "hello-swagger" +func (m NameMangler) ToCommandName(name string) string { + inptr := m.split(name) + in := *inptr + out := make([]string, 0, len(in)) + + for _, w := range in { + out = append(out, lower(w)) + } + poolOfStrings.RedeemStrings(inptr) + + return strings.Join(out, "-") +} + +// ToHumanNameLower represents a code name as a human-readable series of words. +// +// It lower-cases everything with blank space as a word separator. +// +// NOTE: parts recognized as initialisms just keep their original casing. +// +// Examples: +// +// - "Hello, Swagger" becomes "hello swagger" +// - "HelloSwagger" or "Hello-Swagger" become "hello swagger" +func (m NameMangler) ToHumanNameLower(name string) string { + s := m.splitterWithPostSplit + in := s.split(name) + out := make([]string, 0, len(*in)) + + for _, w := range *in { + if !w.IsInitialism() { + out = append(out, lower(w.GetOriginal())) + } else { + out = append(out, trim(w.GetOriginal())) + } + } + + poolOfLexems.RedeemLexems(in) + + return strings.Join(out, " ") +} + +// ToHumanNameTitle represents a code name as a human-readable series of titleized words. +// +// It titleizes every word with blank space as a word separator. +// +// Examples: +// +// - "hello, Swagger" becomes "Hello Swagger" +// - "helloSwagger" becomes "Hello Swagger" +func (m NameMangler) ToHumanNameTitle(name string) string { + s := m.splitterWithPostSplit + in := s.split(name) + + out := make([]string, 0, len(*in)) + for _, w := range *in { + original := trim(w.GetOriginal()) + if !w.IsInitialism() { + out = append(out, m.Camelize(original)) + } else { + out = append(out, original) + } + } + poolOfLexems.RedeemLexems(in) + + return strings.Join(out, " ") +} + +// ToJSONName generates a camelized single-word version of a sentence. +// +// The output assembles every camelized word, but for the first word, which +// is lower-cased. +// +// Example: +// +// - "Hello_swagger" becomes "helloSwagger" +func (m NameMangler) ToJSONName(name string) string { + inptr := m.split(name) + in := *inptr + out := make([]string, 0, len(in)) + + for i, w := range in { + if i == 0 { + out = append(out, lower(w)) + continue + } + out = append(out, m.Camelize(trim(w))) + } + + poolOfStrings.RedeemStrings(inptr) + + return strings.Join(out, "") +} + +// ToVarName generates a legit unexported go variable name from a sentence. +// +// The generated name plays well with linters (see also [NameMangler.ToGoName]). +// +// Examples: +// +// - "Hello_swagger" becomes "helloSwagger" +// - "Http_server" becomes "httpServer" +// +// This name applies the same rules as [NameMangler.ToGoName] (legit exported variable), save the +// capitalization of the initial rune. +// +// Special case: when the initial part is a recognized as an initialism (like in the example above), +// the full part is lower-cased. +func (m NameMangler) ToVarName(name string) string { + return m.goIdentifier(name, false) +} + +// ToGoName generates a legit exported go variable name from a sentence. +// +// The generated name plays well with most linters. +// +// ToGoName abides by the go "exported" symbol rule starting with an upper-case letter. +// +// Examples: +// +// - "hello_swagger" becomes "HelloSwagger" +// - "Http_server" becomes "HTTPServer" +// +// # Edge cases +// +// Whenever the first rune is not eligible to upper case, a special prefix is prepended to the resulting name. +// By default this is simply "X" and you may customize this behavior using the [WithGoNamePrefixFunc] option. +// +// This happens when the first rune is not a letter, e.g. a digit, or a symbol that has no word transliteration +// (see also [WithReplaceFunc] about symbol transliterations), +// as well as for most East Asian or Devanagari runes, for which there is no such concept as upper-case. +// +// # Linting +// +// [revive], the successor of golint is the reference linter. +// +// This means that [NameMangler.ToGoName] supports the initialisms that revive checks (see also [DefaultInitialisms]). +// +// At this moment, there is no attempt to transliterate unicode into ascii, meaning that some linters +// (e.g. asciicheck, gosmopolitan) may croak on go identifiers generated from unicode input. +// +// [revive]: https://github.com/mgechev/revive +func (m NameMangler) ToGoName(name string) string { + return m.goIdentifier(name, true) +} + +func (m NameMangler) goIdentifier(name string, exported bool) string { + s := m.splitterWithPostSplit + lexems := s.split(name) + defer func() { + poolOfLexems.RedeemLexems(lexems) + }() + lexemes := *lexems + + if len(lexemes) == 0 { + return "" + } + + result := poolOfBuffers.BorrowBuffer(len(name)) + defer func() { + poolOfBuffers.RedeemBuffer(result) + }() + + firstPart := lexemes[0] + if !exported { + if ok := firstPart.WriteLower(result, true); !ok { + // NOTE: an initialism as the first part is lower-cased: no longer generates stuff like hTTPxyz. + // + // same prefixing rule applied to unexported variable as to an exported one, so that we have consistent + // names, whether the generated identifier is exported or not. + result.WriteString(strings.ToLower(m.prefixFunc()(name))) + result.WriteString(lexemes[0].GetOriginal()) + } + } else { + if ok := firstPart.WriteTitleized(result, true); !ok { + // "repairs" a lexeme that doesn't start with a letter to become + // the start a legit go name. The current strategy is very crude and simply adds a fixed prefix, + // e.g. "X". + // For instance "1_sesame_street" would be split into lexemes ["1", "sesame", "street"] and + // the first one ("1") would result in something like "X1" (with the default prefix function). + // + // NOTE: no longer forcing the first part to be fully upper-cased + result.WriteString(m.prefixFunc()(name)) + result.WriteString(lexemes[0].GetOriginal()) + } + } + + for _, lexem := range lexemes[1:] { + // NOTE: no longer forcing initialism parts to be fully upper-cased: + // * pluralized initialism preserve their trailing "s" + // * mixed-cased initialisms, such as IPv4, are preserved + if ok := lexem.WriteTitleized(result, false); !ok { + // it's not titleized: perhaps it's too short, perhaps the first rune is not a letter. + // write anyway + result.WriteString(lexem.GetOriginal()) + } + } + + return result.String() +} + +func (m *NameMangler) addInitialisms(words ...string) { + m.index.add(words...) + m.index.buildCache() +} + +// split calls the inner splitter. +func (m NameMangler) split(str string) *[]string { + s := m.splitter + lexems := s.split(str) + result := poolOfStrings.BorrowStrings() + + for _, lexem := range *lexems { + *result = append(*result, lexem.GetOriginal()) + } + poolOfLexems.RedeemLexems(lexems) + + return result +} diff --git a/vendor/github.com/go-openapi/swag/mangling/options.go b/vendor/github.com/go-openapi/swag/mangling/options.go new file mode 100644 index 00000000..3c92b2f1 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/options.go @@ -0,0 +1,150 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling + +type ( + // PrefixFunc defines a safeguard rule (that may depend on the input string), to prefix + // a generated go name (in [NameMangler.ToGoName] and [NameMangler.ToVarName]). + // + // See [NameMangler.ToGoName] for more about which edge cases the prefix function covers. + PrefixFunc func(string) string + + // ReplaceFunc is a transliteration function to replace special runes by a word. + ReplaceFunc func(r rune) (string, bool) + + // Option to configure a [NameMangler]. + Option func(*options) + + options struct { + commonInitialisms []string + + goNamePrefixFunc PrefixFunc + goNamePrefixFuncPtr *PrefixFunc + replaceFunc func(r rune) (string, bool) + } +) + +func (o *options) prefixFunc() PrefixFunc { + if o.goNamePrefixFuncPtr != nil && *o.goNamePrefixFuncPtr != nil { + return *o.goNamePrefixFuncPtr + } + + return o.goNamePrefixFunc +} + +// WithGoNamePrefixFunc overrides the default prefix rule to safeguard generated go names. +// +// Example: +// +// This helps convert "123" into "{prefix}123" (a very crude strategy indeed, but it works). +// +// See [github.com/go-swagger/go-swagger/generator.DefaultFuncMap] for an example. +// +// The prefix function is assumed to return a string that starts with an upper case letter. +// +// The default is to prefix with "X". +// +// See [NameMangler.ToGoName] for more about which edge cases the prefix function covers. +func WithGoNamePrefixFunc(fn PrefixFunc) Option { + return func(o *options) { + o.goNamePrefixFunc = fn + } +} + +// WithGoNamePrefixFuncPtr is like [WithGoNamePrefixFunc] but it specifies a pointer to a function. +// +// [WithGoNamePrefixFunc] should be preferred in most situations. This option should only serve the +// purpose of handling special situations where the prefix function is not an internal variable +// (e.g. an exported package global). +// +// [WithGoNamePrefixFuncPtr] supersedes [WithGoNamePrefixFunc] if it also specified. +// +// If the provided pointer is nil or points to a nil value, this option has no effect. +// +// The caller should ensure that no undesirable concurrent changes are applied to the function pointed to. +func WithGoNamePrefixFuncPtr(ptr *PrefixFunc) Option { + return func(o *options) { + o.goNamePrefixFuncPtr = ptr + } +} + +// WithInitialisms declares the initialisms this mangler supports. +// +// This supersedes any pre-loaded defaults (see [DefaultInitialisms] for more about what initialisms are). +// +// It declares words to be recognized as "initialisms" (i.e. words that won't be camel cased or titled cased). +// +// Words must start with a (unicode) letter. If some don't, they are ignored. +// Words are either fully capitalized or mixed-cased. Lower-case only words are considered capitalized. +func WithInitialisms(words ...string) Option { + return func(o *options) { + o.commonInitialisms = words + } +} + +// WithAdditionalInitialisms adds new initialisms to the currently supported list (see [DefaultInitialisms]). +// +// The same sanitization rules apply as those described for [WithInitialisms]. +func WithAdditionalInitialisms(words ...string) Option { + return func(o *options) { + o.commonInitialisms = append(o.commonInitialisms, words...) + } +} + +// WithReplaceFunc specifies a custom transliteration function instead of the default. +// +// The default translates the following characters into words as follows: +// +// - '@' -> 'At' +// - '&' -> 'And' +// - '|' -> 'Pipe' +// - '$' -> 'Dollar' +// - '!' -> 'Bang' +// +// Notice that the outcome of a transliteration should always be titleized. +func WithReplaceFunc(fn ReplaceFunc) Option { + return func(o *options) { + o.replaceFunc = fn + } +} + +func defaultPrefixFunc(_ string) string { + return "X" +} + +// defaultReplaceTable finds a word representation for special characters. +func defaultReplaceTable(r rune) (string, bool) { + switch r { + case '@': + return "At ", true + case '&': + return "And ", true + case '|': + return "Pipe ", true + case '$': + return "Dollar ", true + case '!': + return "Bang ", true + case '-': + return "", true + case '_': + return "", true + default: + return "", false + } +} + +func optionsWithDefaults(opts []Option) options { + o := options{ + commonInitialisms: DefaultInitialisms(), + goNamePrefixFunc: defaultPrefixFunc, + replaceFunc: defaultReplaceTable, + } + + for _, apply := range opts { + apply(&o) + } + + return o +} diff --git a/vendor/github.com/go-openapi/swag/mangling/pools.go b/vendor/github.com/go-openapi/swag/mangling/pools.go new file mode 100644 index 00000000..f8104351 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/pools.go @@ -0,0 +1,123 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling + +import ( + "bytes" + "sync" +) + +const maxAllocMatches = 8 + +type ( + // memory pools of temporary objects. + // + // These are used to recycle temporarily allocated objects + // and relieve the GC from undue pressure. + + matchesPool struct { + *sync.Pool + } + + buffersPool struct { + *sync.Pool + } + + lexemsPool struct { + *sync.Pool + } + + stringsPool struct { + *sync.Pool + } +) + +var ( + // poolOfMatches holds temporary slices for recycling during the initialism match process + poolOfMatches = matchesPool{ + Pool: &sync.Pool{ + New: func() any { + s := make(initialismMatches, 0, maxAllocMatches) + + return &s + }, + }, + } + + poolOfBuffers = buffersPool{ + Pool: &sync.Pool{ + New: func() any { + return new(bytes.Buffer) + }, + }, + } + + poolOfLexems = lexemsPool{ + Pool: &sync.Pool{ + New: func() any { + s := make([]nameLexem, 0, maxAllocMatches) + + return &s + }, + }, + } + + poolOfStrings = stringsPool{ + Pool: &sync.Pool{ + New: func() any { + s := make([]string, 0, maxAllocMatches) + + return &s + }, + }, + } +) + +func (p matchesPool) BorrowMatches() *initialismMatches { + s := p.Get().(*initialismMatches) + *s = (*s)[:0] // reset slice, keep allocated capacity + + return s +} + +func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer { + s := p.Get().(*bytes.Buffer) + s.Reset() + + if s.Cap() < size { + s.Grow(size) + } + + return s +} + +func (p lexemsPool) BorrowLexems() *[]nameLexem { + s := p.Get().(*[]nameLexem) + *s = (*s)[:0] // reset slice, keep allocated capacity + + return s +} + +func (p stringsPool) BorrowStrings() *[]string { + s := p.Get().(*[]string) + *s = (*s)[:0] // reset slice, keep allocated capacity + + return s +} + +func (p matchesPool) RedeemMatches(s *initialismMatches) { + p.Put(s) +} + +func (p buffersPool) RedeemBuffer(s *bytes.Buffer) { + p.Put(s) +} + +func (p lexemsPool) RedeemLexems(s *[]nameLexem) { + p.Put(s) +} + +func (p stringsPool) RedeemStrings(s *[]string) { + p.Put(s) +} diff --git a/vendor/github.com/go-openapi/swag/mangling/split.go b/vendor/github.com/go-openapi/swag/mangling/split.go new file mode 100644 index 00000000..ed12ea25 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/split.go @@ -0,0 +1,341 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling + +import ( + "fmt" + "unicode" +) + +type splitterOption func(*splitter) + +// withPostSplitInitialismCheck allows to catch initialisms after main split process +func withPostSplitInitialismCheck(s *splitter) { + s.postSplitInitialismCheck = true +} + +func withReplaceFunc(fn ReplaceFunc) func(*splitter) { + return func(s *splitter) { + s.replaceFunc = fn + } +} + +func withInitialismsCache(c *initialismsCache) splitterOption { + return func(s *splitter) { + s.initialismsCache = c + } +} + +type ( + initialismMatch struct { + body []rune + start, end int + complete bool + hasPlural pluralForm + } + initialismMatches []initialismMatch +) + +// String representation of a match, e.g. for debugging. +func (m initialismMatch) String() string { + return fmt.Sprintf("{body: %s (%d), start: %d, end; %d, complete: %t, hasPlural: %v}", + string(m.body), len(m.body), m.start, m.end, m.complete, m.hasPlural, + ) +} + +func (m initialismMatch) isZero() bool { + return m.start == 0 && m.end == 0 +} + +type splitter struct { + *initialismsCache + + postSplitInitialismCheck bool + replaceFunc ReplaceFunc +} + +func newSplitter(options ...splitterOption) splitter { + var s splitter + + for _, option := range options { + option(&s) + } + + if s.replaceFunc == nil { + s.replaceFunc = defaultReplaceTable + } + + return s +} + +func (s splitter) split(name string) *[]nameLexem { + nameRunes := []rune(name) + matches := s.gatherInitialismMatches(nameRunes) + if matches == nil { + return poolOfLexems.BorrowLexems() + } + + return s.mapMatchesToNameLexems(nameRunes, matches) +} + +func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches { + matches := poolOfMatches.BorrowMatches() + const minLenInitialism = 1 + if len(nameRunes) < minLenInitialism+1 { + // can't match initialism with 0 or 1 rune + return matches + } + + // first iteration + s.findMatches(matches, nameRunes, nameRunes[0], 0) + + for i, currentRune := range nameRunes[1:] { + currentRunePosition := i + 1 + // recycle allocations as we loop over runes + // with such recycling, only 2 slices should be allocated per call + // instead of o(n). + // + // BorrowMatches always yields slices with zero length (with some capacity) + newMatches := poolOfMatches.BorrowMatches() + + // check current initialism matches + for _, match := range *matches { + if keepCompleteMatch := match.complete; keepCompleteMatch { + // the match is already complete: keep it then move on to the next match + *newMatches = append(*newMatches, match) + continue + } + + if currentRunePosition-match.start == len(match.body) { + // unmatched: skip + continue + } + + // 1. by construction of the matches, we can't have currentRunePosition - match.start < 0 + // because matches have been computed with their start <= currentRunePosition in the previous + // iterations. + // 2. by construction of the matches, we can't have currentRunePosition - match.start >= len(match.body) + + currentMatchRune := match.body[currentRunePosition-match.start] + if currentMatchRune != currentRune { + // failed match, discard it then move on to the next match + continue + } + + // try to complete the current match + if currentRunePosition-match.start == len(match.body)-1 { + // we are close: the next step is to check the symbol ahead + // if it is a lowercase letter, then it is not the end of match + // but the beginning of the next word. + // + // NOTE(fredbi): this heuristic sometimes leads to counterintuitive splits and + // perhaps (not sure yet) we should check against case _alternance_. + // + // Example: + // + // In the current version, in the sentence "IDS initialism", "ID" is recognized as an initialism, + // leading to a split like "id_s_initialism" (or IDSInitialism), + // whereas in the sentence "IDx initialism", it is not and produces something like + // "i_d_x_initialism" (or IDxInitialism). The generated file name is not great. + // + // Both go identifiers are tolerated by linters. + // + // Notice that the slightly different input "IDs initialism" is correctly detected + // as a pluralized initialism and produces something like "ids_initialism" (or IDsInitialism). + + if currentRunePosition < len(nameRunes)-1 { // when before the last rune + nextRune := nameRunes[currentRunePosition+1] + + // recognize a plural form for this initialism (only simple english pluralization is supported). + if nextRune == 's' && match.hasPlural == simplePlural { + // detected a pluralized initialism + match.body = append(match.body, nextRune) + lookAhead := currentRunePosition + 1 + if lookAhead < len(nameRunes)-1 { + nextRune = nameRunes[lookAhead+1] + if newWord := unicode.IsLower(nextRune); newWord { + // it is the start of a new word. + // Match is only partial and the initialism is not recognized: + // move on to the next match, but do not advance the rune position + continue + } + } + + // this is a pluralized match: keep it + currentRunePosition++ + match.complete = true + match.hasPlural = simplePlural + match.end = currentRunePosition + *newMatches = append(*newMatches, match) + + // match is complete: keep it then move on to the next match + continue + } + + // other cases + // example: invariant plural such as "TLS" + if newWord := unicode.IsLower(nextRune); newWord { + // it is the start of a new word + // Match is only partial and the initialism is not recognized : move on + continue + } + } + + match.complete = true + match.end = currentRunePosition + } + + // append the ongoing matching attempt: it is not necessarily complete, but was successful so far. + // Let's see if it still matches on the next rune. + *newMatches = append(*newMatches, match) + } + + s.findMatches(newMatches, nameRunes, currentRune, currentRunePosition) + + poolOfMatches.RedeemMatches(matches) + matches = newMatches + } + + // it is up to the caller to redeem this last slice + return matches +} + +func (s splitter) findMatches(newMatches *initialismMatches, nameRunes []rune, currentRune rune, currentRunePosition int) { + // check for new initialism matches, based on the first character + for i, r := range s.initialismsRunes { + if r[0] != currentRune { + continue + } + + if currentRunePosition+len(r) > len(nameRunes) { + continue // not eligible: would spilll over the initial string + } + + // possible matches: all initialisms starting with the current rune and that can fit the given string (nameRunes) + *newMatches = append(*newMatches, initialismMatch{ + start: currentRunePosition, + body: r, + complete: false, + hasPlural: s.initialismsPluralForm[i], + }) + } +} + +func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem { + nameLexems := poolOfLexems.BorrowLexems() + + var lastAcceptedMatch initialismMatch + for _, match := range *matches { + if !match.complete { + continue + } + + if firstMatch := lastAcceptedMatch.isZero(); firstMatch { + s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start]) + *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body))) + + lastAcceptedMatch = match + + continue + } + + if overlappedMatch := match.start <= lastAcceptedMatch.end; overlappedMatch { + continue + } + + middle := nameRunes[lastAcceptedMatch.end+1 : match.start] + s.appendBrokenDownCasualString(nameLexems, middle) + *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body))) + + lastAcceptedMatch = match + } + + // we have not found any accepted matches + if lastAcceptedMatch.isZero() { + *nameLexems = (*nameLexems)[:0] + s.appendBrokenDownCasualString(nameLexems, nameRunes) + } else if lastAcceptedMatch.end+1 != len(nameRunes) { + rest := nameRunes[lastAcceptedMatch.end+1:] + s.appendBrokenDownCasualString(nameLexems, rest) + } + + poolOfMatches.RedeemMatches(matches) + + return nameLexems +} + +func (s splitter) breakInitialism(original string) nameLexem { + return newInitialismNameLexem(original, original) +} + +func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) { + currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused + defer func() { + poolOfBuffers.RedeemBuffer(currentSegment) + }() + + addCasualNameLexem := func(original string) { + *segments = append(*segments, newCasualNameLexem(original)) + } + + addInitialismNameLexem := func(original, match string) { + *segments = append(*segments, newInitialismNameLexem(original, match)) + } + + var addNameLexem func(string) + if s.postSplitInitialismCheck { + addNameLexem = func(original string) { + for i := range s.initialisms { + if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) { + addInitialismNameLexem(original, s.initialisms[i]) + + return + } + } + + addCasualNameLexem(original) + } + } else { + addNameLexem = addCasualNameLexem + } + + // NOTE: (performance). The few remaining non-amortized allocations + // lay in the code below: using String() forces + for _, rn := range str { + if replace, found := s.replaceFunc(rn); found { + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) + currentSegment.Reset() + } + + if replace != "" { + addNameLexem(replace) + } + + continue + } + + if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) { + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) + currentSegment.Reset() + } + + continue + } + + if unicode.IsUpper(rn) { + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) + } + currentSegment.Reset() + } + + currentSegment.WriteRune(rn) + } + + if currentSegment.Len() > 0 { + addNameLexem(currentSegment.String()) + } +} diff --git a/vendor/github.com/go-openapi/swag/string_bytes.go b/vendor/github.com/go-openapi/swag/mangling/string_bytes.go similarity index 60% rename from vendor/github.com/go-openapi/swag/string_bytes.go rename to vendor/github.com/go-openapi/swag/mangling/string_bytes.go index 90745d5c..28daaf72 100644 --- a/vendor/github.com/go-openapi/swag/string_bytes.go +++ b/vendor/github.com/go-openapi/swag/mangling/string_bytes.go @@ -1,4 +1,7 @@ -package swag +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling import "unsafe" diff --git a/vendor/github.com/go-openapi/swag/mangling/util.go b/vendor/github.com/go-openapi/swag/mangling/util.go new file mode 100644 index 00000000..0636417e --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling/util.go @@ -0,0 +1,118 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mangling + +import ( + "strings" + "unicode" + "unicode/utf8" +) + +// Removes leading whitespaces +func trim(str string) string { return strings.TrimSpace(str) } + +// upper is strings.ToUpper() combined with trim +func upper(str string) string { + return strings.ToUpper(trim(str)) +} + +// lower is strings.ToLower() combined with trim +func lower(str string) string { + return strings.ToLower(trim(str)) +} + +// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but +// it ignores leading and trailing blank spaces in the compared +// string. +// +// base is assumed to be composed of upper-cased runes, and be already +// trimmed. +// +// This code is heavily inspired from strings.EqualFold. +func isEqualFoldIgnoreSpace(base []rune, str string) bool { + var i, baseIndex int + // equivalent to b := []byte(str), but without data copy + b := hackStringBytes(str) + + for i < len(b) { + if c := b[i]; c < utf8.RuneSelf { + // fast path for ASCII + if c != ' ' && c != '\t' { + break + } + i++ + + continue + } + + // unicode case + r, size := utf8.DecodeRune(b[i:]) + if !unicode.IsSpace(r) { + break + } + i += size + } + + if i >= len(b) { + return len(base) == 0 + } + + for _, baseRune := range base { + if i >= len(b) { + break + } + + if c := b[i]; c < utf8.RuneSelf { + // single byte rune case (ASCII) + if baseRune >= utf8.RuneSelf { + return false + } + + baseChar := byte(baseRune) + if c != baseChar && ((c < 'a') || (c > 'z') || (c-'a'+'A' != baseChar)) { + return false + } + + baseIndex++ + i++ + + continue + } + + // unicode case + r, size := utf8.DecodeRune(b[i:]) + if unicode.ToUpper(r) != baseRune { + return false + } + baseIndex++ + i += size + } + + if baseIndex != len(base) { + return false + } + + // all passed: now we should only have blanks + for i < len(b) { + if c := b[i]; c < utf8.RuneSelf { + // fast path for ASCII + if c != ' ' && c != '\t' { + return false + } + i++ + + continue + } + + // unicode case + r, size := utf8.DecodeRune(b[i:]) + if !unicode.IsSpace(r) { + return false + } + + i += size + } + + return true +} diff --git a/vendor/github.com/go-openapi/swag/mangling_iface.go b/vendor/github.com/go-openapi/swag/mangling_iface.go new file mode 100644 index 00000000..98b9a999 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/mangling_iface.go @@ -0,0 +1,69 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import "github.com/go-openapi/swag/mangling" + +// GoNamePrefixFunc sets an optional rule to prefix go names +// which do not start with a letter. +// +// GoNamePrefixFunc should not be written to while concurrently using the other mangling functions of this package. +// +// Deprecated: use [mangling.WithGoNamePrefixFunc] instead. +var GoNamePrefixFunc mangling.PrefixFunc + +// swagNameMangler is a global instance of the name mangler specifically alloted +// to support deprecated functions. +var swagNameMangler = mangling.NewNameMangler( + mangling.WithGoNamePrefixFuncPtr(&GoNamePrefixFunc), +) + +// AddInitialisms adds additional initialisms to the default list (see [mangling.DefaultInitialisms]). +// +// AddInitialisms is not safe to be called concurrently. +// +// Deprecated: use [mangling.WithAdditionalInitialisms] instead. +func AddInitialisms(words ...string) { + swagNameMangler.AddInitialisms(words...) +} + +// Camelize a single word. +// +// Deprecated: use [mangling.NameMangler.Camelize] instead. +func Camelize(word string) string { return swagNameMangler.Camelize(word) } + +// ToFileName lowercases and underscores a go type name. +// +// Deprecated: use [mangling.NameMangler.ToFileName] instead. +func ToFileName(name string) string { return swagNameMangler.ToFileName(name) } + +// ToCommandName lowercases and underscores a go type name. +// +// Deprecated: use [mangling.NameMangler.ToCommandName] instead. +func ToCommandName(name string) string { return swagNameMangler.ToCommandName(name) } + +// ToHumanNameLower represents a code name as a human series of words. +// +// Deprecated: use [mangling.NameMangler.ToHumanNameLower] instead. +func ToHumanNameLower(name string) string { return swagNameMangler.ToHumanNameLower(name) } + +// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized. +// +// Deprecated: use [mangling.NameMangler.ToHumanNameTitle] instead. +func ToHumanNameTitle(name string) string { return swagNameMangler.ToHumanNameTitle(name) } + +// ToJSONName camel-cases a name which can be underscored or pascal-cased. +// +// Deprecated: use [mangling.NameMangler.ToJSONName] instead. +func ToJSONName(name string) string { return swagNameMangler.ToJSONName(name) } + +// ToVarName camel-cases a name which can be underscored or pascal-cased. +// +// Deprecated: use [mangling.NameMangler.ToVarName] instead. +func ToVarName(name string) string { return swagNameMangler.ToVarName(name) } + +// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes. +// +// Deprecated: use [mangling.NameMangler.ToGoName] instead. +func ToGoName(name string) string { return swagNameMangler.ToGoName(name) } diff --git a/vendor/github.com/go-openapi/swag/name_lexem.go b/vendor/github.com/go-openapi/swag/name_lexem.go deleted file mode 100644 index 8bb64ac3..00000000 --- a/vendor/github.com/go-openapi/swag/name_lexem.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "unicode" - "unicode/utf8" -) - -type ( - lexemKind uint8 - - nameLexem struct { - original string - matchedInitialism string - kind lexemKind - } -) - -const ( - lexemKindCasualName lexemKind = iota - lexemKindInitialismName -) - -func newInitialismNameLexem(original, matchedInitialism string) nameLexem { - return nameLexem{ - kind: lexemKindInitialismName, - original: original, - matchedInitialism: matchedInitialism, - } -} - -func newCasualNameLexem(original string) nameLexem { - return nameLexem{ - kind: lexemKindCasualName, - original: original, - } -} - -func (l nameLexem) GetUnsafeGoName() string { - if l.kind == lexemKindInitialismName { - return l.matchedInitialism - } - - var ( - first rune - rest string - ) - - for i, orig := range l.original { - if i == 0 { - first = orig - continue - } - - if i > 0 { - rest = l.original[i:] - break - } - } - - if len(l.original) > 1 { - b := poolOfBuffers.BorrowBuffer(utf8.UTFMax + len(rest)) - defer func() { - poolOfBuffers.RedeemBuffer(b) - }() - b.WriteRune(unicode.ToUpper(first)) - b.WriteString(lower(rest)) - return b.String() - } - - return l.original -} - -func (l nameLexem) GetOriginal() string { - return l.original -} - -func (l nameLexem) IsInitialism() bool { - return l.kind == lexemKindInitialismName -} diff --git a/vendor/github.com/go-openapi/swag/net.go b/vendor/github.com/go-openapi/swag/net.go deleted file mode 100644 index 821235f8..00000000 --- a/vendor/github.com/go-openapi/swag/net.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "net" - "strconv" -) - -// SplitHostPort splits a network address into a host and a port. -// The port is -1 when there is no port to be found -func SplitHostPort(addr string) (host string, port int, err error) { - h, p, err := net.SplitHostPort(addr) - if err != nil { - return "", -1, err - } - if p == "" { - return "", -1, &net.AddrError{Err: "missing port in address", Addr: addr} - } - - pi, err := strconv.Atoi(p) - if err != nil { - return "", -1, err - } - return h, pi, nil -} diff --git a/vendor/github.com/go-openapi/swag/netutils/LICENSE b/vendor/github.com/go-openapi/swag/netutils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/netutils/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/netutils/doc.go b/vendor/github.com/go-openapi/swag/netutils/doc.go new file mode 100644 index 00000000..74282f8e --- /dev/null +++ b/vendor/github.com/go-openapi/swag/netutils/doc.go @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package netutils provides helpers for network-related tasks. +package netutils diff --git a/vendor/github.com/go-openapi/swag/netutils/net.go b/vendor/github.com/go-openapi/swag/netutils/net.go new file mode 100644 index 00000000..82a1544a --- /dev/null +++ b/vendor/github.com/go-openapi/swag/netutils/net.go @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package netutils + +import ( + "net" + "strconv" +) + +// SplitHostPort splits a network address into a host and a port. +// +// The difference with the standard net.SplitHostPort is that the port is converted to an int. +// +// The port is -1 when there is no port to be found. +func SplitHostPort(addr string) (host string, port int, err error) { + h, p, err := net.SplitHostPort(addr) + if err != nil { + return "", -1, err + } + if p == "" { + return "", -1, &net.AddrError{Err: "missing port in address", Addr: addr} + } + + pi, err := strconv.Atoi(p) + if err != nil { + return "", -1, err + } + + return h, pi, nil +} diff --git a/vendor/github.com/go-openapi/swag/netutils_iface.go b/vendor/github.com/go-openapi/swag/netutils_iface.go new file mode 100644 index 00000000..d658de25 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/netutils_iface.go @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import "github.com/go-openapi/swag/netutils" + +// SplitHostPort splits a network address into a host and a port. +// +// Deprecated: use [netutils.SplitHostPort] instead. +func SplitHostPort(addr string) (host string, port int, err error) { + return netutils.SplitHostPort(addr) +} diff --git a/vendor/github.com/go-openapi/swag/pools/LICENSE b/vendor/github.com/go-openapi/swag/pools/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/pools/README.md b/vendor/github.com/go-openapi/swag/pools/README.md new file mode 100644 index 00000000..1966461c --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/README.md @@ -0,0 +1 @@ +# pools diff --git a/vendor/github.com/go-openapi/swag/pools/debug.go b/vendor/github.com/go-openapi/swag/pools/debug.go new file mode 100644 index 00000000..94415e98 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/debug.go @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +// TB is the subset of [testing.TB] used by [AssertNoLeaks]. +// +// It is satisfied by *[testing.T] and *[testing.B]. +// +// A local interface is used (rather than importing "testing") so that the +// release build does not pull the testing package — and its flags — into +// production binaries. +type TB interface { + Helper() + Errorf(format string, args ...any) + Logf(format string, args ...any) +} diff --git a/vendor/github.com/go-openapi/swag/pools/debug_off.go b/vendor/github.com/go-openapi/swag/pools/debug_off.go new file mode 100644 index 00000000..9163d6d6 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/debug_off.go @@ -0,0 +1,51 @@ +//go:build !poolsdebug + +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +// This is the release implementation of the pool instrumentation: it does +// nothing. +// +// tracker is an empty struct, so it adds no field to the pool types and its +// methods inline away to nothing. +// +// Build with -tags poolsdebug to get the instrumented variant (see +// debug_on.go). + +// debugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug tag). +const debugBuild = false + +// DebugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug build tag). +// +// It lets a test that must run in both modes skip the parts that are invalid +// under instrumentation — e.g. an allocation-count assertion, since the +// instrumented build allocates a per-borrow tracker. +const DebugBuild = debugBuild + +type tracker[T any] struct{} + +func (tracker[T]) register() {} + +func (tracker[T]) onBorrow(*T) {} + +func (tracker[T]) onRedeem(*T) {} + +func (tracker[T]) borrowRedeemer(_ *T, cached func()) func() { return cached } + +// AssertNoLeaks reports whether every borrowed object has been redeemed across +// all pools. +// +// It is only meaningful in the instrumented build (-tags poolsdebug). +// +// In a release build it is a no-op that always reports true, so the same test +// can run in both modes. +func AssertNoLeaks(TB) bool { return true } + +// ResetTracking clears all recorded borrow/redeem tracking. +// +// This is a no-op in a release build. +func ResetTracking() {} diff --git a/vendor/github.com/go-openapi/swag/pools/debug_on.go b/vendor/github.com/go-openapi/swag/pools/debug_on.go new file mode 100644 index 00000000..64ccc57d --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/debug_on.go @@ -0,0 +1,237 @@ +//go:build poolsdebug + +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +import ( + "fmt" + "runtime" + "sync" +) + +// This is the instrumented implementation of the pool tracking, enabled with +// -tags poolsdebug. +// +// Each pool carries a tracker that records, per recycled pointer, whether it is +// currently borrowed or redeemed, together with the call sites of the last +// borrow and redeem. +// It panics loudly (with those call sites) when it detects misuse: +// +// - a double redeem (the same object returned to the pool twice — corrupts sync.Pool); +// - for the redeemable pools, a redeem of a stale borrow (the slot was re-borrowed since — the +// ABA case the production atomic guard cannot catch), thanks to a per-borrow generation; +// - a redeem of an object the pool never handed out; +// - a borrow of an object still checked out (a symptom of an earlier double-Put). +// +// Borrowed-but-never-redeemed objects (leaks) are reported by [AssertNoLeaks]. + +// debugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug tag). +const debugBuild = true + +// DebugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug build tag). +// +// See the release-build doc for usage. +const DebugBuild = debugBuild + +type trackStatus uint8 + +const ( + trackBorrowed trackStatus = iota + 1 + trackRedeemed +) + +type trackEntry struct { + status trackStatus + gen uint64 // identifies the current borrow, to detect a redeem racing a re-borrow (ABA) + borrowedAt string + redeemedAt string +} + +type tracker[T any] struct { + mu sync.Mutex + entries map[*T]*trackEntry + nextGen uint64 +} + +func (t *tracker[T]) register() { + t.mu.Lock() + if t.entries == nil { + t.entries = make(map[*T]*trackEntry) + } + t.mu.Unlock() + + registerLeakChecker(t) +} + +// markBorrow records a borrow of ptr and returns its generation. +// +// Caller must hold no lock. +func (t *tracker[T]) markBorrow(ptr *T, site string) uint64 { + t.mu.Lock() + defer t.mu.Unlock() + + e := t.entries[ptr] + if e == nil { + e = &trackEntry{} + t.entries[ptr] = e + } else if e.status == trackBorrowed { + panic(fmt.Sprintf( + "pools: borrow of an object still checked out (borrowed at %s); "+ + "this usually means it was redeemed twice earlier", e.borrowedAt)) + } + + t.nextGen++ + e.status = trackBorrowed + e.gen = t.nextGen + e.borrowedAt = site + + return t.nextGen +} + +// markRedeem validates and records a redeem of ptr. gen is the borrow +// generation the caller is redeeming, or 0 to skip the ABA check (plain +// Pool[T], which has no per-borrow token). +func (t *tracker[T]) markRedeem(ptr *T, gen uint64, site string) { + t.mu.Lock() + defer t.mu.Unlock() + + e := t.entries[ptr] + switch { + case e == nil: + panic("pools: redeem of an object this pool never handed out") + case e.status != trackBorrowed: + panic(fmt.Sprintf("pools: double redeem (first redeemed at %s)", e.redeemedAt)) + case gen != 0 && e.gen != gen: + panic(fmt.Sprintf( + "pools: redeem of a stale borrow (the slot was re-borrowed at %s since this borrow); "+ + "a redeem is racing a re-borrow of the same slot (ABA)", e.borrowedAt)) + } + + e.status = trackRedeemed + e.redeemedAt = site +} + +const stackOffset = 3 + +func (t *tracker[T]) onBorrow(ptr *T) { + t.markBorrow(ptr, caller(stackOffset)) +} + +func (t *tracker[T]) onRedeem(ptr *T) { + t.markRedeem(ptr, 0, caller(stackOffset)) +} + +// borrowRedeemer records the borrow and returns a generation-stamped redeemer +// that validates the redeem (catching double-redeem and ABA) before delegating +// to the cached redeemer. +func (t *tracker[T]) borrowRedeemer(ptr *T, cached func()) func() { + gen := t.markBorrow(ptr, caller(stackOffset)) + + return func() { + t.markRedeem(ptr, gen, caller(stackOffset-1)) + cached() + } +} + +func (t *tracker[T]) checkLeaks(tb TB) bool { + t.mu.Lock() + defer t.mu.Unlock() + + ok := true + for _, e := range t.entries { + if e.status != trackRedeemed { + tb.Logf("pools: object borrowed but never redeemed (borrowed at %s)", e.borrowedAt) + ok = false + } + } + + return ok +} + +func (t *tracker[T]) resetTracking() { + t.mu.Lock() + t.entries = make(map[*T]*trackEntry) + t.nextGen = 0 + t.mu.Unlock() +} + +// leakChecker is the build-erased view of a tracker that the global registry +// holds, so trackers of different element types can be checked uniformly. +type leakChecker interface { + checkLeaks(tb TB) bool + resetTracking() +} + +var ( + registryMu sync.Mutex + registry []leakChecker +) + +func registerLeakChecker(c leakChecker) { + registryMu.Lock() + registry = append(registry, c) + registryMu.Unlock() +} + +// AssertNoLeaks reports whether every borrowed object has been redeemed across +// all pools created so far. +// +// It logs the borrow call site of each leaked object and fails tb when any are +// found. +// +// Typical use, with [ResetTracking] to isolate the test from earlier ones: +// +// func TestX(t *testing.T) { +// pools.ResetTracking() +// t.Cleanup(func() { pools.AssertNoLeaks(t) }) +// // ... exercise code that borrows/redeems ... +// } +func AssertNoLeaks(tb TB) bool { + tb.Helper() + registryMu.Lock() + defer registryMu.Unlock() + + ok := true + for _, c := range registry { + if !c.checkLeaks(tb) { + ok = false + } + } + if !ok { + tb.Errorf("pools: leaked pooled objects detected (borrowed but never redeemed)") + } + + return ok +} + +// ResetTracking clears all recorded borrow/redeem tracking across every pool. +// +// Call it at the start of a test so leaks from earlier tests are not attributed +// to it. +func ResetTracking() { + registryMu.Lock() + defer registryMu.Unlock() + + for _, c := range registry { + c.resetTracking() + } +} + +// caller returns "file:line" of the frame skip levels above caller itself. +func caller(skip int) string { + pc, _, _, ok := runtime.Caller(skip) + if !ok { + return "unknown" + } + fn := runtime.FuncForPC(pc) + if fn == nil { + return "unknown" + } + file, line := fn.FileLine(pc) + + return fmt.Sprintf("%s:%d", file, line) +} diff --git a/vendor/github.com/go-openapi/swag/pools/doc.go b/vendor/github.com/go-openapi/swag/pools/doc.go new file mode 100644 index 00000000..395c24d2 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/doc.go @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package pools provide utilities to recycle allocated objects. +// +// This package provides: +// +// - a generic [Pool] type that wraps [sync.Pool], +// - a [PoolRedeemable] variant that hands out a cached redeem closure, +// - a [PoolSlice] for recycling slices without juggling pointers. +// +// # Debug build +// +// Building with the "poolsdebug" tag (go test -tags poolsdebug ./...) turns on +// instrumentation that tracks every borrow and redeem and panics on misuse: +// +// - double redeem (including the A -> B -> A case for the redeemable pools), +// - redeem of a foreign object, +// - borrow of an object still checked out +// +// It reports the offending call sites. +// +// [AssertNoLeaks] then reports any object borrowed but never redeemed. +// +// The instrumentation is a no-op with zero overhead when the tag is absent. +package pools diff --git a/vendor/github.com/go-openapi/swag/pools/pools.go b/vendor/github.com/go-openapi/swag/pools/pools.go new file mode 100644 index 00000000..d78ea579 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/pools.go @@ -0,0 +1,410 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +import ( + "iter" + "slices" + "sync" + "sync/atomic" +) + +// Resettable is an interface for types that want to recycle a clean instance +// from a [Pool]. +// +// When T (or rather *T) implements [Resettable], the pool calls Reset on an +// instance both when it is redeemed and when it is borrowed: +// +// - on redeem, so that no references held by the instance are retained while it sits idle in the +// pool (which would pin a reference graph alive across a GC cycle); +// - on borrow, so that the next borrower receives a clean object regardless of how the instance +// reached the pool. +// +// Reset must be safe to call more than once on the same instance (it runs at +// least twice per cycle). +type Resettable interface { + Reset() +} + +// resetIfResettable calls Reset on v when *T implements [Resettable]. +func resetIfResettable[T any](v *T) { + if r, ok := any(v).(Resettable); ok { + r.Reset() + } +} + +// borrow state of a [redeemable] wrapper, used to detect double-redeem. +const ( + stateIdle uint32 = iota // sitting in the pool (or freshly created), not checked out + stateBorrowed // checked out by a borrower +) + +type redeemable[T any] struct { + inner *T + redeemer func() + // state guards against a double-redeem (the same wrapper Put into the pool + // twice, which would let one object be handed to two borrowers). + // + // It is set to stateBorrowed on borrow and atomically flipped back to + // stateIdle on redeem; a redeem that finds it already idle panics. + state atomic.Uint32 +} + +// redeemPanic is the message raised when a slot is redeemed while already idle. +const redeemPanic = "pools: " + + "double redeem detected (object already returned to the pool); " + + "a borrowed object must be redeemed exactly once" + +// Pool wraps a [sync.Pool] to make it available for any type. +// +// T must be the value type of the pooled object (e.g. Pool[bytes.Buffer]): +// [Pool.Borrow] returns a *T. Using a pointer type as T (e.g. +// Pool[*bytes.Buffer]) would yield a **T and is almost certainly a mistake. +type Pool[T any] struct { + pool sync.Pool + tracker tracker[T] // empty (zero-cost) unless built with the poolsdebug tag +} + +// PoolRedeemable wraps a [sync.Pool] to make it available for any type. +// +// It differs from [Pool] in the way objects are redeemed to the pool: borrowing +// also yields a cached redeem closure, so no closure is allocated at redeem +// time. +type PoolRedeemable[T any] struct { + pool sync.Pool + tracker tracker[redeemable[T]] // empty (zero-cost) unless built with the poolsdebug tag +} + +// New builds a new [Pool] to recycle allocations of type T explicitly using +// [Pool.Redeem] and the allocated pointer. +// +// Freshly allocated instances of type T are set to their zero value; like +// recycled instances they are reset (if [Resettable]) when borrowed, so +// [Pool.Borrow] always yields a clean object. +func New[T any]() *Pool[T] { + p := &Pool[T]{} + p.pool = sync.Pool{ + New: func() any { + return new(T) + }, + } + p.tracker.register() + + return p +} + +// NewRedeemable builds a new redeemable [Pool] to recycle allocations of type +// T, and use the inner redeemer to relinquish objects to the pool. +func NewRedeemable[T any]() *PoolRedeemable[T] { + p := &PoolRedeemable[T]{} + p.pool = sync.Pool{ + New: func() any { + r := &redeemable[T]{inner: new(T)} + r.redeemer = func() { + if !r.state.CompareAndSwap(stateBorrowed, stateIdle) { + panic(redeemPanic) + } + resetIfResettable(r.inner) + p.pool.Put(r) + } + + return r + }, + } + p.tracker.register() + + return p +} + +// Borrow an instance from the pool. +// +// If the type implements [Resettable], the returned instance is reset before +// being handed out, so it is always clean. +func (p *Pool[T]) Borrow() *T { + target := p.pool.Get().(*T) + resetIfResettable(target) + p.tracker.onBorrow(target) + + return target +} + +// Redeem a borrowed instance to the pool. +// +// A nil pointer is ignored (it would otherwise corrupt the pool: a typed-nil +// boxed into an interface is not the nil interface that [sync.Pool.Put] skips). +// +// The instance is reset (if it implements [Resettable]) before being returned +// to the pool. +// After calling Redeem, the caller must drop its reference to ptr: continuing +// to use it is a use-after-redeem bug. +// +// Unlike [PoolRedeemable], this plain pool holds no per-object state, so it +// cannot detect a double-redeem of the same pointer (which corrupts the pool). +// +// Prefer [PoolRedeemable] when you want that guard, or the debug build for full +// tracking. +func (p *Pool[T]) Redeem(ptr *T) { + if ptr == nil { + return + } + p.tracker.onRedeem(ptr) + resetIfResettable(ptr) + p.pool.Put(ptr) +} + +// BorrowWithRedeem borrows an instance from the pool and provides the +// corresponding redeem function. +// +// This is useful for instance to use with defer. +// +// The instance is reset (if it implements [Resettable]) both when borrowed and +// when the returned redeem closure is called. +// After calling the redeem closure, the caller must drop its reference to the +// returned instance. +// +// Calling the redeem closure more than once panics (see [redeemable.state]): a +// borrowed instance must be redeemed exactly once. +func (p *PoolRedeemable[T]) BorrowWithRedeem() (*T, func()) { + container := p.pool.Get().(*redeemable[T]) + container.state.Store(stateBorrowed) + resetIfResettable(container.inner) + + // In release builds borrowRedeemer returns container.redeemer unchanged (zero + // cost). + // Under the poolsdebug tag it returns a generation-stamped wrapper that tracks + // the borrow and detects double-redeem (incl. + // + // ABA), foreign-redeem and leaks. + return container.inner, p.tracker.borrowRedeemer(container, container.redeemer) +} + +// Slice is a struct that wraps a slice []T. +// +// This is useful to borrow and redeem slices from a pool, without having to +// constantly manipulate pointers to the slice. +// +// The wrapper holds the authoritative slice header. +// +// Its mutating methods ([Slice.Append], [Slice.Concat], [Slice.Grow]) return +// the current backing slice for convenience, so it reads as an idiomatic []T. +// +// But the returned slice is only a snapshot of the wrapper's state at that +// moment: if you keep it and grow it yourself with the builtin append and it +// reallocates, the new backing array lives only in your local copy and is NOT +// tracked by the wrapper — it will not be recycled when the wrapper is +// redeemed (and a later borrower would get the old, smaller array). +// +// Rule of thumb: it is fine to read or pass the returned []T to a consumer; but +// if you plan to grow the slice, keep calling the wrapper's methods so the +// growth is tracked and recycled. +type Slice[T any] struct { + length int + inner []T +} + +// Slice returns the inner slice. +// +// Treat the result as a read-only view (for ranging or passing to a consumer), +// valid until the next mutation or redeem. +// To grow or append, use the wrapper methods so the new backing array is +// tracked and recycled (see [Slice]). +func (s *Slice[T]) Slice() []T { + return s.inner +} + +// Grow the inner slice so it can accommodate at least size more elements +// without reallocating, and return the current backing slice. +// +// Growth is tracked by the wrapper, so the enlarged backing array is recycled +// on redeem. +// See [Slice] for the caveat about growing the returned slice yourself. +func (s *Slice[T]) Grow(size int) []T { + s.inner = slices.Grow(s.inner, size) + + return s.inner +} + +func (s *Slice[T]) Len() int { + return len(s.inner) +} + +func (s *Slice[T]) Cap() int { + return cap(s.inner) +} + +// Append elements to the inner slice and return the current backing slice. +// +// This should be preferred to the append builtin if you plan that the slice will +// grow and you want the newly allocated space to be tracked and recycled. +// See [Slice] for the caveat about growing the returned slice yourself. +func (s *Slice[T]) Append(elems ...T) []T { + s.inner = append(s.inner, elems...) + + return s.inner +} + +// Concat another slice to the inner slice and return the current backing slice. +// +// Unlike [slices.Concat], this reuses the inner slice's capacity instead of +// always allocating a fresh backing array. +// See [Slice] for the caveat about growing the returned slice yourself. +func (s *Slice[T]) Concat(slice []T) []T { + s.inner = append(s.inner, slice...) + + return s.inner +} + +// IndexedElems iterates over the inner slice. +func (s *Slice[T]) IndexedElems() iter.Seq2[int, T] { + return func(yield func(int, T) bool) { + for i, elem := range s.inner { + if !yield(i, elem) { + return + } + } + } +} + +// Reset the inner slice to its configured initial length, keeping allocated +// capacity. +// +// All elements are zeroed, so the pool never retains stale element references +// (which would keep a referenced graph alive for slices of pointers) and so a +// [WithLength] slice is handed out clean rather than carrying data from a +// previous borrower. +func (s *Slice[T]) Reset() { + clear(s.inner) + if s.length > cap(s.inner) { + s.inner = slices.Grow(s.inner[:0], s.length) + } + s.inner = s.inner[:s.length] +} + +// Clip removes unused capacity from the inner slice. +func (s *Slice[T]) Clip() { + s.inner = slices.Clip(s.inner) +} + +// resetWithCapacity discards the current backing array and replaces it with a +// fresh one of the configured length and the given capacity. +// +// It is used by a capacity-capped pool to stop recycling an oversized backing +// array (the old array is left for the GC). +func (s *Slice[T]) resetWithCapacity(capacity int) { + s.inner = make([]T, s.length, max(s.length, capacity)) +} + +// PoolSlice is a pool of [Slice[T]]. +// +// [PoolSlice.BorrowWithRedeem] will return an empty inner slice by default. +// This default may be altered using [WithMinimumCapacity]. +// +// Use [PoolSlice.BorrowWithSizeAndRedeem] or [Slice.Grow] to grow the capacity +// of the inner slice. +type PoolSlice[T any] struct { + // redeemable is held as an unexported field rather than embedded, so the + // underlying [PoolRedeemable] and its [sync.Pool] are not part of PoolSlice's + // public surface. + redeemable *PoolRedeemable[Slice[T]] +} + +// PoolSliceOption alters the default settings to allocate new pooled slices +type PoolSliceOption func(*poolSliceOptions) + +type poolSliceOptions struct { + minCapacity int + length int + maxCapacity int +} + +func WithMinimumCapacity(size int) PoolSliceOption { + return func(o *poolSliceOptions) { + o.minCapacity = size + } +} + +// WithMaxCapacity bounds the capacity of recycled slices. +// +// When a borrowed slice has grown past size at redeem time, its (oversized) +// backing array is discarded and replaced with a fresh one sized to the minimum +// capacity, instead of being recycled. +// +// This stops the pool from accumulating large backing arrays after an +// occasional large request, keeping the steady-state memory bounded. +// +// The trade-off: a workload that genuinely needs slices larger than size will +// reallocate on every cycle. +// Set size from the high-water mark you actually expect, not below it. +// A size of 0 (the default) means no cap: grown slices are recycled as-is. +func WithMaxCapacity(size int) PoolSliceOption { + return func(o *poolSliceOptions) { + o.maxCapacity = size + } +} + +// WithLength ensures that the borrowed slices have a fixed given initial +// length. +// +// By default, the borrowed slices are reset to length 0. +func WithLength(size int) PoolSliceOption { + return func(o *poolSliceOptions) { + o.length = size + } +} + +// NewPoolSlice builds a pool to recycle slices of type []T. +func NewPoolSlice[T any](opts ...PoolSliceOption) *PoolSlice[T] { + var o poolSliceOptions + for _, apply := range opts { + apply(&o) + } + + rp := &PoolRedeemable[Slice[T]]{} + rp.pool = sync.Pool{ + New: func() any { + s := &redeemable[Slice[T]]{ + inner: &Slice[T]{ + length: o.length, + inner: make([]T, o.length, max(o.length, o.minCapacity)), + }, + } + + s.redeemer = func() { + if !s.state.CompareAndSwap(stateBorrowed, stateIdle) { + panic(redeemPanic) + } + if o.maxCapacity > 0 && s.inner.Cap() > o.maxCapacity { + s.inner.resetWithCapacity(o.minCapacity) + } else { + s.inner.Reset() + } + rp.pool.Put(s) + } + + return s + }, + } + rp.tracker.register() + + return &PoolSlice[T]{redeemable: rp} +} + +// BorrowWithRedeem returns the slice wrapper and the redeem closure to +// relinquish the allocated wrapper. +// +// The wrapper is reset (elements zeroed, length restored) both on borrow and +// when the redeem closure is called. +// Calling the redeem closure more than once panics. +func (p *PoolSlice[T]) BorrowWithRedeem() (*Slice[T], func()) { + return p.redeemable.BorrowWithRedeem() +} + +// BorrowWithSizeAndRedeem borrows a slice []T from the pool and ensures that +// its capacity is at least the provided size. +func (p *PoolSlice[T]) BorrowWithSizeAndRedeem(size int) (*Slice[T], func()) { + s, redeem := p.BorrowWithRedeem() + s.Grow(size) + + return s, redeem +} diff --git a/vendor/github.com/go-openapi/swag/split.go b/vendor/github.com/go-openapi/swag/split.go deleted file mode 100644 index 274727a8..00000000 --- a/vendor/github.com/go-openapi/swag/split.go +++ /dev/null @@ -1,508 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "bytes" - "sync" - "unicode" - "unicode/utf8" -) - -type ( - splitter struct { - initialisms []string - initialismsRunes [][]rune - initialismsUpperCased [][]rune // initialisms cached in their trimmed, upper-cased version - postSplitInitialismCheck bool - } - - splitterOption func(*splitter) - - initialismMatch struct { - body []rune - start, end int - complete bool - } - initialismMatches []initialismMatch -) - -type ( - // memory pools of temporary objects. - // - // These are used to recycle temporarily allocated objects - // and relieve the GC from undue pressure. - - matchesPool struct { - *sync.Pool - } - - buffersPool struct { - *sync.Pool - } - - lexemsPool struct { - *sync.Pool - } - - splittersPool struct { - *sync.Pool - } -) - -var ( - // poolOfMatches holds temporary slices for recycling during the initialism match process - poolOfMatches = matchesPool{ - Pool: &sync.Pool{ - New: func() any { - s := make(initialismMatches, 0, maxAllocMatches) - - return &s - }, - }, - } - - poolOfBuffers = buffersPool{ - Pool: &sync.Pool{ - New: func() any { - return new(bytes.Buffer) - }, - }, - } - - poolOfLexems = lexemsPool{ - Pool: &sync.Pool{ - New: func() any { - s := make([]nameLexem, 0, maxAllocMatches) - - return &s - }, - }, - } - - poolOfSplitters = splittersPool{ - Pool: &sync.Pool{ - New: func() any { - s := newSplitter() - - return &s - }, - }, - } -) - -// nameReplaceTable finds a word representation for special characters. -func nameReplaceTable(r rune) (string, bool) { - switch r { - case '@': - return "At ", true - case '&': - return "And ", true - case '|': - return "Pipe ", true - case '$': - return "Dollar ", true - case '!': - return "Bang ", true - case '-': - return "", true - case '_': - return "", true - default: - return "", false - } -} - -// split calls the splitter. -// -// Use newSplitter for more control and options -func split(str string) []string { - s := poolOfSplitters.BorrowSplitter() - lexems := s.split(str) - result := make([]string, 0, len(*lexems)) - - for _, lexem := range *lexems { - result = append(result, lexem.GetOriginal()) - } - poolOfLexems.RedeemLexems(lexems) - poolOfSplitters.RedeemSplitter(s) - - return result - -} - -func newSplitter(options ...splitterOption) splitter { - s := splitter{ - postSplitInitialismCheck: false, - initialisms: initialisms, - initialismsRunes: initialismsRunes, - initialismsUpperCased: initialismsUpperCased, - } - - for _, option := range options { - option(&s) - } - - return s -} - -// withPostSplitInitialismCheck allows to catch initialisms after main split process -func withPostSplitInitialismCheck(s *splitter) { - s.postSplitInitialismCheck = true -} - -func (p matchesPool) BorrowMatches() *initialismMatches { - s := p.Get().(*initialismMatches) - *s = (*s)[:0] // reset slice, keep allocated capacity - - return s -} - -func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer { - s := p.Get().(*bytes.Buffer) - s.Reset() - - if s.Cap() < size { - s.Grow(size) - } - - return s -} - -func (p lexemsPool) BorrowLexems() *[]nameLexem { - s := p.Get().(*[]nameLexem) - *s = (*s)[:0] // reset slice, keep allocated capacity - - return s -} - -func (p splittersPool) BorrowSplitter(options ...splitterOption) *splitter { - s := p.Get().(*splitter) - s.postSplitInitialismCheck = false // reset options - for _, apply := range options { - apply(s) - } - - return s -} - -func (p matchesPool) RedeemMatches(s *initialismMatches) { - p.Put(s) -} - -func (p buffersPool) RedeemBuffer(s *bytes.Buffer) { - p.Put(s) -} - -func (p lexemsPool) RedeemLexems(s *[]nameLexem) { - p.Put(s) -} - -func (p splittersPool) RedeemSplitter(s *splitter) { - p.Put(s) -} - -func (m initialismMatch) isZero() bool { - return m.start == 0 && m.end == 0 -} - -func (s splitter) split(name string) *[]nameLexem { - nameRunes := []rune(name) - matches := s.gatherInitialismMatches(nameRunes) - if matches == nil { - return poolOfLexems.BorrowLexems() - } - - return s.mapMatchesToNameLexems(nameRunes, matches) -} - -func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches { - var matches *initialismMatches - - for currentRunePosition, currentRune := range nameRunes { - // recycle these allocations as we loop over runes - // with such recycling, only 2 slices should be allocated per call - // instead of o(n). - newMatches := poolOfMatches.BorrowMatches() - - // check current initialism matches - if matches != nil { // skip first iteration - for _, match := range *matches { - if keepCompleteMatch := match.complete; keepCompleteMatch { - *newMatches = append(*newMatches, match) - continue - } - - // drop failed match - currentMatchRune := match.body[currentRunePosition-match.start] - if currentMatchRune != currentRune { - continue - } - - // try to complete ongoing match - if currentRunePosition-match.start == len(match.body)-1 { - // we are close; the next step is to check the symbol ahead - // if it is a small letter, then it is not the end of match - // but beginning of the next word - - if currentRunePosition < len(nameRunes)-1 { - nextRune := nameRunes[currentRunePosition+1] - if newWord := unicode.IsLower(nextRune); newWord { - // oh ok, it was the start of a new word - continue - } - } - - match.complete = true - match.end = currentRunePosition - } - - *newMatches = append(*newMatches, match) - } - } - - // check for new initialism matches - for i := range s.initialisms { - initialismRunes := s.initialismsRunes[i] - if initialismRunes[0] == currentRune { - *newMatches = append(*newMatches, initialismMatch{ - start: currentRunePosition, - body: initialismRunes, - complete: false, - }) - } - } - - if matches != nil { - poolOfMatches.RedeemMatches(matches) - } - matches = newMatches - } - - // up to the caller to redeem this last slice - return matches -} - -func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem { - nameLexems := poolOfLexems.BorrowLexems() - - var lastAcceptedMatch initialismMatch - for _, match := range *matches { - if !match.complete { - continue - } - - if firstMatch := lastAcceptedMatch.isZero(); firstMatch { - s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start]) - *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body))) - - lastAcceptedMatch = match - - continue - } - - if overlappedMatch := match.start <= lastAcceptedMatch.end; overlappedMatch { - continue - } - - middle := nameRunes[lastAcceptedMatch.end+1 : match.start] - s.appendBrokenDownCasualString(nameLexems, middle) - *nameLexems = append(*nameLexems, s.breakInitialism(string(match.body))) - - lastAcceptedMatch = match - } - - // we have not found any accepted matches - if lastAcceptedMatch.isZero() { - *nameLexems = (*nameLexems)[:0] - s.appendBrokenDownCasualString(nameLexems, nameRunes) - } else if lastAcceptedMatch.end+1 != len(nameRunes) { - rest := nameRunes[lastAcceptedMatch.end+1:] - s.appendBrokenDownCasualString(nameLexems, rest) - } - - poolOfMatches.RedeemMatches(matches) - - return nameLexems -} - -func (s splitter) breakInitialism(original string) nameLexem { - return newInitialismNameLexem(original, original) -} - -func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) { - currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused - defer func() { - poolOfBuffers.RedeemBuffer(currentSegment) - }() - - addCasualNameLexem := func(original string) { - *segments = append(*segments, newCasualNameLexem(original)) - } - - addInitialismNameLexem := func(original, match string) { - *segments = append(*segments, newInitialismNameLexem(original, match)) - } - - var addNameLexem func(string) - if s.postSplitInitialismCheck { - addNameLexem = func(original string) { - for i := range s.initialisms { - if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) { - addInitialismNameLexem(original, s.initialisms[i]) - - return - } - } - - addCasualNameLexem(original) - } - } else { - addNameLexem = addCasualNameLexem - } - - for _, rn := range str { - if replace, found := nameReplaceTable(rn); found { - if currentSegment.Len() > 0 { - addNameLexem(currentSegment.String()) - currentSegment.Reset() - } - - if replace != "" { - addNameLexem(replace) - } - - continue - } - - if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) { - if currentSegment.Len() > 0 { - addNameLexem(currentSegment.String()) - currentSegment.Reset() - } - - continue - } - - if unicode.IsUpper(rn) { - if currentSegment.Len() > 0 { - addNameLexem(currentSegment.String()) - } - currentSegment.Reset() - } - - currentSegment.WriteRune(rn) - } - - if currentSegment.Len() > 0 { - addNameLexem(currentSegment.String()) - } -} - -// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but -// it ignores leading and trailing blank spaces in the compared -// string. -// -// base is assumed to be composed of upper-cased runes, and be already -// trimmed. -// -// This code is heavily inspired from strings.EqualFold. -func isEqualFoldIgnoreSpace(base []rune, str string) bool { - var i, baseIndex int - // equivalent to b := []byte(str), but without data copy - b := hackStringBytes(str) - - for i < len(b) { - if c := b[i]; c < utf8.RuneSelf { - // fast path for ASCII - if c != ' ' && c != '\t' { - break - } - i++ - - continue - } - - // unicode case - r, size := utf8.DecodeRune(b[i:]) - if !unicode.IsSpace(r) { - break - } - i += size - } - - if i >= len(b) { - return len(base) == 0 - } - - for _, baseRune := range base { - if i >= len(b) { - break - } - - if c := b[i]; c < utf8.RuneSelf { - // single byte rune case (ASCII) - if baseRune >= utf8.RuneSelf { - return false - } - - baseChar := byte(baseRune) - if c != baseChar && - !('a' <= c && c <= 'z' && c-'a'+'A' == baseChar) { - return false - } - - baseIndex++ - i++ - - continue - } - - // unicode case - r, size := utf8.DecodeRune(b[i:]) - if unicode.ToUpper(r) != baseRune { - return false - } - baseIndex++ - i += size - } - - if baseIndex != len(base) { - return false - } - - // all passed: now we should only have blanks - for i < len(b) { - if c := b[i]; c < utf8.RuneSelf { - // fast path for ASCII - if c != ' ' && c != '\t' { - return false - } - i++ - - continue - } - - // unicode case - r, size := utf8.DecodeRune(b[i:]) - if !unicode.IsSpace(r) { - return false - } - - i += size - } - - return true -} diff --git a/vendor/github.com/go-openapi/swag/stringutils/LICENSE b/vendor/github.com/go-openapi/swag/stringutils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/stringutils/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/stringutils/collection_formats.go b/vendor/github.com/go-openapi/swag/stringutils/collection_formats.go new file mode 100644 index 00000000..28056ad2 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/stringutils/collection_formats.go @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package stringutils + +import "strings" + +const ( + // collectionFormatComma = "csv" + collectionFormatSpace = "ssv" + collectionFormatTab = "tsv" + collectionFormatPipe = "pipes" + collectionFormatMulti = "multi" + + collectionFormatDefaultSep = "," +) + +// JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute): +// +// ssv: space separated value +// tsv: tab separated value +// pipes: pipe (|) separated value +// csv: comma separated value (default) +func JoinByFormat(data []string, format string) []string { + if len(data) == 0 { + return data + } + var sep string + switch format { + case collectionFormatSpace: + sep = " " + case collectionFormatTab: + sep = "\t" + case collectionFormatPipe: + sep = "|" + case collectionFormatMulti: + return data + default: + sep = collectionFormatDefaultSep + } + return []string{strings.Join(data, sep)} +} + +// SplitByFormat splits a string by a known format: +// +// ssv: space separated value +// tsv: tab separated value +// pipes: pipe (|) separated value +// csv: comma separated value (default) +func SplitByFormat(data, format string) []string { + if data == "" { + return nil + } + var sep string + switch format { + case collectionFormatSpace: + sep = " " + case collectionFormatTab: + sep = "\t" + case collectionFormatPipe: + sep = "|" + case collectionFormatMulti: + return nil + default: + sep = collectionFormatDefaultSep + } + var result []string + for _, s := range strings.Split(data, sep) { + if ts := strings.TrimSpace(s); ts != "" { + result = append(result, ts) + } + } + return result +} diff --git a/vendor/github.com/go-openapi/swag/stringutils/doc.go b/vendor/github.com/go-openapi/swag/stringutils/doc.go new file mode 100644 index 00000000..c6d17a11 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/stringutils/doc.go @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package stringutils exposes helpers to search and process strings. +package stringutils diff --git a/vendor/github.com/go-openapi/swag/stringutils/strings.go b/vendor/github.com/go-openapi/swag/stringutils/strings.go new file mode 100644 index 00000000..cd792b7d --- /dev/null +++ b/vendor/github.com/go-openapi/swag/stringutils/strings.go @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package stringutils + +import ( + "slices" + "strings" +) + +// ContainsStrings searches a slice of strings for a case-sensitive match +// +// Now equivalent to the standard library [slice.Contains]. +func ContainsStrings(coll []string, item string) bool { + return slices.Contains(coll, item) +} + +// ContainsStringsCI searches a slice of strings for a case-insensitive match +func ContainsStringsCI(coll []string, item string) bool { + return slices.ContainsFunc(coll, func(e string) bool { + return strings.EqualFold(e, item) + }) +} diff --git a/vendor/github.com/go-openapi/swag/stringutils_iface.go b/vendor/github.com/go-openapi/swag/stringutils_iface.go new file mode 100644 index 00000000..dbfa4848 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/stringutils_iface.go @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import "github.com/go-openapi/swag/stringutils" + +// ContainsStrings searches a slice of strings for a case-sensitive match. +// +// Deprecated: use [slices.Contains] or [stringutils.ContainsStrings] instead. +func ContainsStrings(coll []string, item string) bool { + return stringutils.ContainsStrings(coll, item) +} + +// ContainsStringsCI searches a slice of strings for a case-insensitive match. +// +// Deprecated: use [stringutils.ContainsStringsCI] instead. +func ContainsStringsCI(coll []string, item string) bool { + return stringutils.ContainsStringsCI(coll, item) +} + +// JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute). +// +// Deprecated: use [stringutils.JoinByFormat] instead. +func JoinByFormat(data []string, format string) []string { + return stringutils.JoinByFormat(data, format) +} + +// SplitByFormat splits a string by a known format. +// +// Deprecated: use [stringutils.SplitByFormat] instead. +func SplitByFormat(data, format string) []string { + return stringutils.SplitByFormat(data, format) +} diff --git a/vendor/github.com/go-openapi/swag/typeutils/LICENSE b/vendor/github.com/go-openapi/swag/typeutils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/typeutils/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/typeutils/doc.go b/vendor/github.com/go-openapi/swag/typeutils/doc.go new file mode 100644 index 00000000..66bed20d --- /dev/null +++ b/vendor/github.com/go-openapi/swag/typeutils/doc.go @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package typeutils exposes utilities to inspect generic types. +package typeutils diff --git a/vendor/github.com/go-openapi/swag/typeutils/types.go b/vendor/github.com/go-openapi/swag/typeutils/types.go new file mode 100644 index 00000000..55487a67 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/typeutils/types.go @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package typeutils + +import "reflect" + +type zeroable interface { + IsZero() bool +} + +// IsZero returns true when the value passed into the function is a zero value. +// This allows for safer checking of interface values. +func IsZero(data any) bool { + v := reflect.ValueOf(data) + // check for nil data + switch v.Kind() { //nolint:exhaustive + case + reflect.Interface, + reflect.Func, + reflect.Chan, + reflect.Pointer, + reflect.UnsafePointer, + reflect.Map, + reflect.Slice: + if v.IsNil() { + return true + } + } + + // check for things that have an IsZero method instead + if vv, ok := data.(zeroable); ok { + return vv.IsZero() + } + + // continue with slightly more complex reflection + switch v.Kind() { //nolint:exhaustive + case 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.Struct, reflect.Array: + return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface()) + case reflect.Invalid: + return true + default: + return false + } +} + +// IsNil checks if input is nil. +// +// For types chan, func, interface, map, pointer, or slice it returns true if its argument is nil. +// +// See [reflect.Value.IsNil]. +func IsNil(input any) bool { + if input == nil { + return true + } + + kind := reflect.TypeOf(input).Kind() + switch kind { //nolint:exhaustive + case reflect.Pointer, + reflect.UnsafePointer, + reflect.Map, + reflect.Slice, + reflect.Chan, + reflect.Interface, + reflect.Func: + return reflect.ValueOf(input).IsNil() + default: + return false + } +} diff --git a/vendor/github.com/go-openapi/swag/typeutils_iface.go b/vendor/github.com/go-openapi/swag/typeutils_iface.go new file mode 100644 index 00000000..b63813ea --- /dev/null +++ b/vendor/github.com/go-openapi/swag/typeutils_iface.go @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import "github.com/go-openapi/swag/typeutils" + +// IsZero returns true when the value passed into the function is a zero value. +// This allows for safer checking of interface values. +// +// Deprecated: use [typeutils.IsZero] instead. +func IsZero(data any) bool { return typeutils.IsZero(data) } diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go deleted file mode 100644 index 5051401c..00000000 --- a/vendor/github.com/go-openapi/swag/util.go +++ /dev/null @@ -1,364 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "reflect" - "strings" - "unicode" - "unicode/utf8" -) - -// GoNamePrefixFunc sets an optional rule to prefix go names -// which do not start with a letter. -// -// The prefix function is assumed to return a string that starts with an upper case letter. -// -// e.g. to help convert "123" into "{prefix}123" -// -// The default is to prefix with "X" -var GoNamePrefixFunc func(string) string - -func prefixFunc(name, in string) string { - if GoNamePrefixFunc == nil { - return "X" + in - } - - return GoNamePrefixFunc(name) + in -} - -const ( - // collectionFormatComma = "csv" - collectionFormatSpace = "ssv" - collectionFormatTab = "tsv" - collectionFormatPipe = "pipes" - collectionFormatMulti = "multi" -) - -// JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute): -// -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) -func JoinByFormat(data []string, format string) []string { - if len(data) == 0 { - return data - } - var sep string - switch format { - case collectionFormatSpace: - sep = " " - case collectionFormatTab: - sep = "\t" - case collectionFormatPipe: - sep = "|" - case collectionFormatMulti: - return data - default: - sep = "," - } - return []string{strings.Join(data, sep)} -} - -// SplitByFormat splits a string by a known format: -// -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) -func SplitByFormat(data, format string) []string { - if data == "" { - return nil - } - var sep string - switch format { - case collectionFormatSpace: - sep = " " - case collectionFormatTab: - sep = "\t" - case collectionFormatPipe: - sep = "|" - case collectionFormatMulti: - return nil - default: - sep = "," - } - var result []string - for _, s := range strings.Split(data, sep) { - if ts := strings.TrimSpace(s); ts != "" { - result = append(result, ts) - } - } - return result -} - -// Removes leading whitespaces -func trim(str string) string { - return strings.TrimSpace(str) -} - -// Shortcut to strings.ToUpper() -func upper(str string) string { - return strings.ToUpper(trim(str)) -} - -// Shortcut to strings.ToLower() -func lower(str string) string { - return strings.ToLower(trim(str)) -} - -// Camelize an uppercased word -func Camelize(word string) string { - camelized := poolOfBuffers.BorrowBuffer(len(word)) - defer func() { - poolOfBuffers.RedeemBuffer(camelized) - }() - - for pos, ru := range []rune(word) { - if pos > 0 { - camelized.WriteRune(unicode.ToLower(ru)) - } else { - camelized.WriteRune(unicode.ToUpper(ru)) - } - } - return camelized.String() -} - -// ToFileName lowercases and underscores a go type name -func ToFileName(name string) string { - in := split(name) - out := make([]string, 0, len(in)) - - for _, w := range in { - out = append(out, lower(w)) - } - - return strings.Join(out, "_") -} - -// ToCommandName lowercases and underscores a go type name -func ToCommandName(name string) string { - in := split(name) - out := make([]string, 0, len(in)) - - for _, w := range in { - out = append(out, lower(w)) - } - return strings.Join(out, "-") -} - -// ToHumanNameLower represents a code name as a human series of words -func ToHumanNameLower(name string) string { - s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck) - in := s.split(name) - poolOfSplitters.RedeemSplitter(s) - out := make([]string, 0, len(*in)) - - for _, w := range *in { - if !w.IsInitialism() { - out = append(out, lower(w.GetOriginal())) - } else { - out = append(out, trim(w.GetOriginal())) - } - } - poolOfLexems.RedeemLexems(in) - - return strings.Join(out, " ") -} - -// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized -func ToHumanNameTitle(name string) string { - s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck) - in := s.split(name) - poolOfSplitters.RedeemSplitter(s) - - out := make([]string, 0, len(*in)) - for _, w := range *in { - original := trim(w.GetOriginal()) - if !w.IsInitialism() { - out = append(out, Camelize(original)) - } else { - out = append(out, original) - } - } - poolOfLexems.RedeemLexems(in) - - return strings.Join(out, " ") -} - -// ToJSONName camelcases a name which can be underscored or pascal cased -func ToJSONName(name string) string { - in := split(name) - out := make([]string, 0, len(in)) - - for i, w := range in { - if i == 0 { - out = append(out, lower(w)) - continue - } - out = append(out, Camelize(trim(w))) - } - return strings.Join(out, "") -} - -// ToVarName camelcases a name which can be underscored or pascal cased -func ToVarName(name string) string { - res := ToGoName(name) - if isInitialism(res) { - return lower(res) - } - if len(res) <= 1 { - return lower(res) - } - return lower(res[:1]) + res[1:] -} - -// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes -func ToGoName(name string) string { - s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck) - lexems := s.split(name) - poolOfSplitters.RedeemSplitter(s) - defer func() { - poolOfLexems.RedeemLexems(lexems) - }() - lexemes := *lexems - - if len(lexemes) == 0 { - return "" - } - - result := poolOfBuffers.BorrowBuffer(len(name)) - defer func() { - poolOfBuffers.RedeemBuffer(result) - }() - - // check if not starting with a letter, upper case - firstPart := lexemes[0].GetUnsafeGoName() - if lexemes[0].IsInitialism() { - firstPart = upper(firstPart) - } - - if c := firstPart[0]; c < utf8.RuneSelf { - // ASCII - switch { - case 'A' <= c && c <= 'Z': - result.WriteString(firstPart) - case 'a' <= c && c <= 'z': - result.WriteByte(c - 'a' + 'A') - result.WriteString(firstPart[1:]) - default: - result.WriteString(prefixFunc(name, firstPart)) - // NOTE: no longer check if prefixFunc returns a string that starts with uppercase: - // assume this is always the case - } - } else { - // unicode - firstRune, _ := utf8.DecodeRuneInString(firstPart) - switch { - case !unicode.IsLetter(firstRune): - result.WriteString(prefixFunc(name, firstPart)) - case !unicode.IsUpper(firstRune): - result.WriteString(prefixFunc(name, firstPart)) - /* - result.WriteRune(unicode.ToUpper(firstRune)) - result.WriteString(firstPart[offset:]) - */ - default: - result.WriteString(firstPart) - } - } - - for _, lexem := range lexemes[1:] { - goName := lexem.GetUnsafeGoName() - - // to support old behavior - if lexem.IsInitialism() { - goName = upper(goName) - } - result.WriteString(goName) - } - - return result.String() -} - -// ContainsStrings searches a slice of strings for a case-sensitive match -func ContainsStrings(coll []string, item string) bool { - for _, a := range coll { - if a == item { - return true - } - } - return false -} - -// ContainsStringsCI searches a slice of strings for a case-insensitive match -func ContainsStringsCI(coll []string, item string) bool { - for _, a := range coll { - if strings.EqualFold(a, item) { - return true - } - } - return false -} - -type zeroable interface { - IsZero() bool -} - -// IsZero returns true when the value passed into the function is a zero value. -// This allows for safer checking of interface values. -func IsZero(data interface{}) bool { - v := reflect.ValueOf(data) - // check for nil data - switch v.Kind() { //nolint:exhaustive - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - if v.IsNil() { - return true - } - } - - // check for things that have an IsZero method instead - if vv, ok := data.(zeroable); ok { - return vv.IsZero() - } - - // continue with slightly more complex reflection - switch v.Kind() { //nolint:exhaustive - case 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.Struct, reflect.Array: - return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface()) - case reflect.Invalid: - return true - default: - return false - } -} - -// CommandLineOptionsGroup represents a group of user-defined command line options -type CommandLineOptionsGroup struct { - ShortDescription string - LongDescription string - Options interface{} -} diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go deleted file mode 100644 index 57534653..00000000 --- a/vendor/github.com/go-openapi/swag/yaml.go +++ /dev/null @@ -1,481 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package swag - -import ( - "encoding/json" - "fmt" - "path/filepath" - "reflect" - "sort" - "strconv" - - "github.com/mailru/easyjson/jlexer" - "github.com/mailru/easyjson/jwriter" - yaml "gopkg.in/yaml.v3" -) - -// YAMLMatcher matches yaml -func YAMLMatcher(path string) bool { - ext := filepath.Ext(path) - return ext == ".yaml" || ext == ".yml" -} - -// YAMLToJSON converts YAML unmarshaled data into json compatible data -func YAMLToJSON(data interface{}) (json.RawMessage, error) { - jm, err := transformData(data) - if err != nil { - return nil, err - } - b, err := WriteJSON(jm) - return json.RawMessage(b), err -} - -// BytesToYAMLDoc converts a byte slice into a YAML document -func BytesToYAMLDoc(data []byte) (interface{}, error) { - var document yaml.Node // preserve order that is present in the document - if err := yaml.Unmarshal(data, &document); err != nil { - return nil, err - } - if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode { - return nil, fmt.Errorf("only YAML documents that are objects are supported: %w", ErrYAML) - } - return &document, nil -} - -func yamlNode(root *yaml.Node) (interface{}, error) { - switch root.Kind { - case yaml.DocumentNode: - return yamlDocument(root) - case yaml.SequenceNode: - return yamlSequence(root) - case yaml.MappingNode: - return yamlMapping(root) - case yaml.ScalarNode: - return yamlScalar(root) - case yaml.AliasNode: - return yamlNode(root.Alias) - default: - return nil, fmt.Errorf("unsupported YAML node type: %v: %w", root.Kind, ErrYAML) - } -} - -func yamlDocument(node *yaml.Node) (interface{}, error) { - if len(node.Content) != 1 { - return nil, fmt.Errorf("unexpected YAML Document node content length: %d: %w", len(node.Content), ErrYAML) - } - return yamlNode(node.Content[0]) -} - -func yamlMapping(node *yaml.Node) (interface{}, error) { - const sensibleAllocDivider = 2 - m := make(JSONMapSlice, len(node.Content)/sensibleAllocDivider) - - var j int - for i := 0; i < len(node.Content); i += 2 { - var nmi JSONMapItem - k, err := yamlStringScalarC(node.Content[i]) - if err != nil { - return nil, fmt.Errorf("unable to decode YAML map key: %w: %w", err, ErrYAML) - } - nmi.Key = k - v, err := yamlNode(node.Content[i+1]) - if err != nil { - return nil, fmt.Errorf("unable to process YAML map value for key %q: %w: %w", k, err, ErrYAML) - } - nmi.Value = v - m[j] = nmi - j++ - } - return m, nil -} - -func yamlSequence(node *yaml.Node) (interface{}, error) { - s := make([]interface{}, 0) - - for i := 0; i < len(node.Content); i++ { - - v, err := yamlNode(node.Content[i]) - if err != nil { - return nil, fmt.Errorf("unable to decode YAML sequence value: %w: %w", err, ErrYAML) - } - s = append(s, v) - } - return s, nil -} - -const ( // See https://yaml.org/type/ - yamlStringScalar = "tag:yaml.org,2002:str" - yamlIntScalar = "tag:yaml.org,2002:int" - yamlBoolScalar = "tag:yaml.org,2002:bool" - yamlFloatScalar = "tag:yaml.org,2002:float" - yamlTimestamp = "tag:yaml.org,2002:timestamp" - yamlNull = "tag:yaml.org,2002:null" -) - -func yamlScalar(node *yaml.Node) (interface{}, error) { - switch node.LongTag() { - case yamlStringScalar: - return node.Value, nil - case yamlBoolScalar: - b, err := strconv.ParseBool(node.Value) - if err != nil { - return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting bool content: %w: %w", node.Value, err, ErrYAML) - } - return b, nil - case yamlIntScalar: - i, err := strconv.ParseInt(node.Value, 10, 64) - if err != nil { - return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting integer content: %w: %w", node.Value, err, ErrYAML) - } - return i, nil - case yamlFloatScalar: - f, err := strconv.ParseFloat(node.Value, 64) - if err != nil { - return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting float content: %w: %w", node.Value, err, ErrYAML) - } - return f, nil - case yamlTimestamp: - return node.Value, nil - case yamlNull: - return nil, nil //nolint:nilnil - default: - return nil, fmt.Errorf("YAML tag %q is not supported: %w", node.LongTag(), ErrYAML) - } -} - -func yamlStringScalarC(node *yaml.Node) (string, error) { - if node.Kind != yaml.ScalarNode { - return "", fmt.Errorf("expecting a string scalar but got %q: %w", node.Kind, ErrYAML) - } - switch node.LongTag() { - case yamlStringScalar, yamlIntScalar, yamlFloatScalar: - return node.Value, nil - default: - return "", fmt.Errorf("YAML tag %q is not supported as map key: %w", node.LongTag(), ErrYAML) - } -} - -// JSONMapSlice represent a JSON object, with the order of keys maintained -type JSONMapSlice []JSONMapItem - -// MarshalJSON renders a JSONMapSlice as JSON -func (s JSONMapSlice) MarshalJSON() ([]byte, error) { - w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty} - s.MarshalEasyJSON(w) - return w.BuildBytes() -} - -// MarshalEasyJSON renders a JSONMapSlice as JSON, using easyJSON -func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) { - w.RawByte('{') - - ln := len(s) - last := ln - 1 - for i := 0; i < ln; i++ { - s[i].MarshalEasyJSON(w) - if i != last { // last item - w.RawByte(',') - } - } - - w.RawByte('}') -} - -// UnmarshalJSON makes a JSONMapSlice from JSON -func (s *JSONMapSlice) UnmarshalJSON(data []byte) error { - l := jlexer.Lexer{Data: data} - s.UnmarshalEasyJSON(&l) - return l.Error() -} - -// UnmarshalEasyJSON makes a JSONMapSlice from JSON, using easyJSON -func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) { - if in.IsNull() { - in.Skip() - return - } - - var result JSONMapSlice - in.Delim('{') - for !in.IsDelim('}') { - var mi JSONMapItem - mi.UnmarshalEasyJSON(in) - result = append(result, mi) - } - *s = result -} - -func (s JSONMapSlice) MarshalYAML() (interface{}, error) { - var n yaml.Node - n.Kind = yaml.DocumentNode - var nodes []*yaml.Node - for _, item := range s { - nn, err := json2yaml(item.Value) - if err != nil { - return nil, err - } - ns := []*yaml.Node{ - { - Kind: yaml.ScalarNode, - Tag: yamlStringScalar, - Value: item.Key, - }, - nn, - } - nodes = append(nodes, ns...) - } - - n.Content = []*yaml.Node{ - { - Kind: yaml.MappingNode, - Content: nodes, - }, - } - - return yaml.Marshal(&n) -} - -func isNil(input interface{}) bool { - if input == nil { - return true - } - kind := reflect.TypeOf(input).Kind() - switch kind { //nolint:exhaustive - case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan: - return reflect.ValueOf(input).IsNil() - default: - return false - } -} - -func json2yaml(item interface{}) (*yaml.Node, error) { - if isNil(item) { - return &yaml.Node{ - Kind: yaml.ScalarNode, - Value: "null", - }, nil - } - - switch val := item.(type) { - case JSONMapSlice: - var n yaml.Node - n.Kind = yaml.MappingNode - for i := range val { - childNode, err := json2yaml(&val[i].Value) - if err != nil { - return nil, err - } - n.Content = append(n.Content, &yaml.Node{ - Kind: yaml.ScalarNode, - Tag: yamlStringScalar, - Value: val[i].Key, - }, childNode) - } - return &n, nil - case map[string]interface{}: - var n yaml.Node - n.Kind = yaml.MappingNode - keys := make([]string, 0, len(val)) - for k := range val { - keys = append(keys, k) - } - sort.Strings(keys) - - for _, k := range keys { - v := val[k] - childNode, err := json2yaml(v) - if err != nil { - return nil, err - } - n.Content = append(n.Content, &yaml.Node{ - Kind: yaml.ScalarNode, - Tag: yamlStringScalar, - Value: k, - }, childNode) - } - return &n, nil - case []interface{}: - var n yaml.Node - n.Kind = yaml.SequenceNode - for i := range val { - childNode, err := json2yaml(val[i]) - if err != nil { - return nil, err - } - n.Content = append(n.Content, childNode) - } - return &n, nil - case string: - return &yaml.Node{ - Kind: yaml.ScalarNode, - Tag: yamlStringScalar, - Value: val, - }, nil - case float64: - return &yaml.Node{ - Kind: yaml.ScalarNode, - Tag: yamlFloatScalar, - Value: strconv.FormatFloat(val, 'f', -1, 64), - }, nil - case int64: - return &yaml.Node{ - Kind: yaml.ScalarNode, - Tag: yamlIntScalar, - Value: strconv.FormatInt(val, 10), - }, nil - case uint64: - return &yaml.Node{ - Kind: yaml.ScalarNode, - Tag: yamlIntScalar, - Value: strconv.FormatUint(val, 10), - }, nil - case bool: - return &yaml.Node{ - Kind: yaml.ScalarNode, - Tag: yamlBoolScalar, - Value: strconv.FormatBool(val), - }, nil - default: - return nil, fmt.Errorf("unhandled type: %T: %w", val, ErrYAML) - } -} - -// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice -type JSONMapItem struct { - Key string - Value interface{} -} - -// MarshalJSON renders a JSONMapItem as JSON -func (s JSONMapItem) MarshalJSON() ([]byte, error) { - w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty} - s.MarshalEasyJSON(w) - return w.BuildBytes() -} - -// MarshalEasyJSON renders a JSONMapItem as JSON, using easyJSON -func (s JSONMapItem) MarshalEasyJSON(w *jwriter.Writer) { - w.String(s.Key) - w.RawByte(':') - w.Raw(WriteJSON(s.Value)) -} - -// UnmarshalJSON makes a JSONMapItem from JSON -func (s *JSONMapItem) UnmarshalJSON(data []byte) error { - l := jlexer.Lexer{Data: data} - s.UnmarshalEasyJSON(&l) - return l.Error() -} - -// UnmarshalEasyJSON makes a JSONMapItem from JSON, using easyJSON -func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) { - key := in.UnsafeString() - in.WantColon() - value := in.Interface() - in.WantComma() - s.Key = key - s.Value = value -} - -func transformData(input interface{}) (out interface{}, err error) { - format := func(t interface{}) (string, error) { - switch k := t.(type) { - case string: - return k, nil - case uint: - return strconv.FormatUint(uint64(k), 10), nil - case uint8: - return strconv.FormatUint(uint64(k), 10), nil - case uint16: - return strconv.FormatUint(uint64(k), 10), nil - case uint32: - return strconv.FormatUint(uint64(k), 10), nil - case uint64: - return strconv.FormatUint(k, 10), nil - case int: - return strconv.Itoa(k), nil - case int8: - return strconv.FormatInt(int64(k), 10), nil - case int16: - return strconv.FormatInt(int64(k), 10), nil - case int32: - return strconv.FormatInt(int64(k), 10), nil - case int64: - return strconv.FormatInt(k, 10), nil - default: - return "", fmt.Errorf("unexpected map key type, got: %T: %w", k, ErrYAML) - } - } - - switch in := input.(type) { - case yaml.Node: - return yamlNode(&in) - case *yaml.Node: - return yamlNode(in) - case map[interface{}]interface{}: - o := make(JSONMapSlice, 0, len(in)) - for ke, va := range in { - var nmi JSONMapItem - if nmi.Key, err = format(ke); err != nil { - return nil, err - } - - v, ert := transformData(va) - if ert != nil { - return nil, ert - } - nmi.Value = v - o = append(o, nmi) - } - return o, nil - case []interface{}: - len1 := len(in) - o := make([]interface{}, len1) - for i := 0; i < len1; i++ { - o[i], err = transformData(in[i]) - if err != nil { - return nil, err - } - } - return o, nil - } - return input, nil -} - -// YAMLDoc loads a yaml document from either http or a file and converts it to json -func YAMLDoc(path string) (json.RawMessage, error) { - yamlDoc, err := YAMLData(path) - if err != nil { - return nil, err - } - - data, err := YAMLToJSON(yamlDoc) - if err != nil { - return nil, err - } - - return data, nil -} - -// YAMLData loads a yaml document from either http or a file -func YAMLData(path string) (interface{}, error) { - data, err := LoadFromFileOrHTTP(path) - if err != nil { - return nil, err - } - - return BytesToYAMLDoc(data) -} diff --git a/vendor/github.com/go-openapi/swag/yamlutils/LICENSE b/vendor/github.com/go-openapi/swag/yamlutils/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/yamlutils/LICENSE @@ -0,0 +1,202 @@ + + 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/go-openapi/swag/yamlutils/doc.go b/vendor/github.com/go-openapi/swag/yamlutils/doc.go new file mode 100644 index 00000000..7bb92a82 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/yamlutils/doc.go @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package yamlutils provides utilities to work with YAML documents. +// +// - [BytesToYAMLDoc] to construct a [yaml.Node] document +// - [YAMLToJSON] to convert a [yaml.Node] document to JSON bytes +// - [YAMLMapSlice] to serialize and deserialize YAML with the order of keys maintained +package yamlutils + +import ( + _ "go.yaml.in/yaml/v3" // for documentation purpose only +) diff --git a/vendor/github.com/go-openapi/swag/yamlutils/errors.go b/vendor/github.com/go-openapi/swag/yamlutils/errors.go new file mode 100644 index 00000000..e87bc5e8 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/yamlutils/errors.go @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package yamlutils + +type yamlError string + +const ( + // ErrYAML is an error raised by YAML utilities + ErrYAML yamlError = "yaml error" +) + +func (e yamlError) Error() string { + return string(e) +} diff --git a/vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go b/vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go new file mode 100644 index 00000000..24d951f8 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go @@ -0,0 +1,335 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package yamlutils + +import ( + "fmt" + "iter" + "slices" + "sort" + "strconv" + + "github.com/go-openapi/swag/conv" + "github.com/go-openapi/swag/jsonutils" + "github.com/go-openapi/swag/jsonutils/adapters/ifaces" + "github.com/go-openapi/swag/typeutils" + yaml "go.yaml.in/yaml/v3" +) + +var ( + _ yaml.Marshaler = YAMLMapSlice{} + _ yaml.Unmarshaler = &YAMLMapSlice{} +) + +// YAMLMapSlice represents a YAML object, with the order of keys maintained. +// +// It is similar to [jsonutils.JSONMapSlice] and also knows how to marshal and unmarshal YAML. +// +// It behaves like an ordered map, but keys can't be accessed in constant time. +type YAMLMapSlice []YAMLMapItem + +// YAMLMapItem represents the value of a key in a YAML object held by [YAMLMapSlice]. +// +// It is entirely equivalent to [jsonutils.JSONMapItem], with the same limitation that +// you should not Marshal or Unmarshal directly this type, outside of a [YAMLMapSlice]. +type YAMLMapItem = jsonutils.JSONMapItem + +func (s YAMLMapSlice) OrderedItems() iter.Seq2[string, any] { + return func(yield func(string, any) bool) { + for _, item := range s { + if !yield(item.Key, item.Value) { + return + } + } + } +} + +// SetOrderedItems implements [ifaces.SetOrdered]: it merges keys passed by the iterator argument +// into the [YAMLMapSlice]. +func (s *YAMLMapSlice) SetOrderedItems(items iter.Seq2[string, any]) { + if items == nil { + // force receiver to be a nil slice + *s = nil + + return + } + + m := *s + if len(m) > 0 { + // update mode: short-circuited when unmarshaling fresh data structures + idx := make(map[string]int, len(m)) + + for i, item := range m { + idx[item.Key] = i + } + + for k, v := range items { + idx, ok := idx[k] + if ok { + m[idx].Value = v + + continue + } + + m = append(m, YAMLMapItem{Key: k, Value: v}) + } + + *s = m + + return + } + + for k, v := range items { + m = append(m, YAMLMapItem{Key: k, Value: v}) + } + + *s = m +} + +// MarshalJSON renders this YAML object as JSON bytes. +// +// The difference with standard JSON marshaling is that the order of keys is maintained. +func (s YAMLMapSlice) MarshalJSON() ([]byte, error) { + return jsonutils.JSONMapSlice(s).MarshalJSON() +} + +// UnmarshalJSON builds this YAML object from JSON bytes. +// +// The difference with standard JSON marshaling is that the order of keys is maintained. +func (s *YAMLMapSlice) UnmarshalJSON(data []byte) error { + js := jsonutils.JSONMapSlice(*s) + + if err := js.UnmarshalJSON(data); err != nil { + return err + } + + *s = YAMLMapSlice(js) + + return nil +} + +// MarshalYAML produces a YAML document as bytes +// +// The difference with standard YAML marshaling is that the order of keys is maintained. +// +// It implements [yaml.Marshaler]. +func (s YAMLMapSlice) MarshalYAML() (any, error) { + if typeutils.IsNil(s) { + return []byte("null\n"), nil + } + var n yaml.Node + n.Kind = yaml.DocumentNode + var nodes []*yaml.Node + + for _, item := range s { + nn, err := json2yaml(item.Value, 1) + if err != nil { + return nil, err + } + + ns := []*yaml.Node{ + { + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: item.Key, + }, + nn, + } + nodes = append(nodes, ns...) + } + + n.Content = []*yaml.Node{ + { + Kind: yaml.MappingNode, + Content: nodes, + }, + } + + return yaml.Marshal(&n) +} + +// UnmarshalYAML builds a YAMLMapSlice object from a YAML document [yaml.Node]. +// +// It implements [yaml.Unmarshaler]. +func (s *YAMLMapSlice) UnmarshalYAML(node *yaml.Node) error { + return s.unmarshalYAML(newYAMLWalker(), node, 0) +} + +// unmarshalYAML builds the slice from a [yaml.Node], tracking the recursion depth (against +// stack-overflow) and threading the [yamlWalker] so anchor/alias expansion stays bounded +// across the whole document. +func (s *YAMLMapSlice) unmarshalYAML(w *yamlWalker, node *yaml.Node, depth int) error { + if depth > defaultMaxNestingDepth { + return errMaxNestingDepth + } + + if typeutils.IsNil(*s) { + // allow to unmarshal with a simple var declaration (nil slice) + *s = YAMLMapSlice{} + } + if node == nil { + *s = nil + return nil + } + + const sensibleAllocDivider = 2 + m := slices.Grow(*s, len(node.Content)/sensibleAllocDivider) + m = m[:0] + + for i := 0; i < len(node.Content); i += 2 { + if err := w.account(); err != nil { // account the key node + return err + } + + var nmi YAMLMapItem + k, err := yamlStringScalarC(node.Content[i]) + if err != nil { + return fmt.Errorf("unable to decode YAML map key: %w: %w", err, ErrYAML) + } + nmi.Key = k + v, err := w.node(node.Content[i+1], depth+1) + if err != nil { + return fmt.Errorf("unable to process YAML map value for key %q: %w: %w", k, err, ErrYAML) + } + nmi.Value = v + m = append(m, nmi) + } + + *s = m + + return nil +} + +func json2yaml(item any, depth int) (*yaml.Node, error) { + if depth > defaultMaxNestingDepth { + return nil, errMaxNestingDepth + } + + if typeutils.IsNil(item) { + return &yaml.Node{ + Kind: yaml.ScalarNode, + Value: "null", + }, nil + } + + switch val := item.(type) { + case ifaces.Ordered: + return orderedYAML(val, depth) + + case map[string]any: + var n yaml.Node + n.Kind = yaml.MappingNode + keys := make([]string, 0, len(val)) + for k := range val { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + v := val[k] + childNode, err := json2yaml(v, depth+1) + if err != nil { + return nil, err + } + n.Content = append(n.Content, &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: k, + }, childNode) + } + return &n, nil + + case []any: + var n yaml.Node + n.Kind = yaml.SequenceNode + for i := range val { + childNode, err := json2yaml(val[i], depth+1) + if err != nil { + return nil, err + } + n.Content = append(n.Content, childNode) + } + return &n, nil + case string: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: val, + }, nil + case float32: + return floatNode(val) + case float64: + return floatNode(val) + case int: + return integerNode(val) + case int8: + return integerNode(val) + case int16: + return integerNode(val) + case int32: + return integerNode(val) + case int64: + return integerNode(val) + case uint: + return uintegerNode(val) + case uint8: + return uintegerNode(val) + case uint16: + return uintegerNode(val) + case uint32: + return uintegerNode(val) + case uint64: + return uintegerNode(val) + case bool: + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlBoolScalar, + Value: strconv.FormatBool(val), + }, nil + default: + return nil, fmt.Errorf("unhandled type: %T: %w", val, ErrYAML) + } +} + +func floatNode[T conv.Float](val T) (*yaml.Node, error) { + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlFloatScalar, + Value: conv.FormatFloat(val), + }, nil +} + +func integerNode[T conv.Signed](val T) (*yaml.Node, error) { + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlIntScalar, + Value: conv.FormatInteger(val), + }, nil +} + +func uintegerNode[T conv.Unsigned](val T) (*yaml.Node, error) { + return &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlIntScalar, + Value: conv.FormatUinteger(val), + }, nil +} + +func orderedYAML[T ifaces.Ordered](val T, depth int) (*yaml.Node, error) { + var n yaml.Node + n.Kind = yaml.MappingNode + for key, value := range val.OrderedItems() { + childNode, err := json2yaml(value, depth+1) + if err != nil { + return nil, err + } + + n.Content = append(n.Content, &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: yamlStringScalar, + Value: key, + }, childNode) + } + return &n, nil +} diff --git a/vendor/github.com/go-openapi/swag/yamlutils/yaml.go b/vendor/github.com/go-openapi/swag/yamlutils/yaml.go new file mode 100644 index 00000000..d4b5335f --- /dev/null +++ b/vendor/github.com/go-openapi/swag/yamlutils/yaml.go @@ -0,0 +1,328 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package yamlutils + +import ( + json "encoding/json" + "fmt" + "strconv" + + "github.com/go-openapi/swag/jsonutils" + yaml "go.yaml.in/yaml/v3" +) + +// defaultMaxNestingDepth caps the recursion depth of the YAML<->JSON transforms to +// guard against stack-overflow on deeply nested (possibly adversarial) input. +// +// It matches the limit enforced by go.yaml.in/yaml/v3's own parser and by +// encoding/json's decoder. +const defaultMaxNestingDepth = 10000 + +// Bounds on YAML anchor/alias expansion. +// +// go.yaml.in/yaml/v3 enforces these when decoding into Go values, but that guard is +// coupled to the library's own tree walk: when we decode into a low-level [yaml.Node] +// (to preserve key order) and expand aliases ourselves in [yamlWalker.node], we bypass +// it. We therefore reproduce it here, with the same constants and ratio schedule as the +// library's decoder (see go.yaml.in/yaml/v3 decode.go, "excessive aliasing"). +const ( + aliasCountThreshold = 100 + decodeCountThreshold = 1000 + + // 400,000 decode operations is ~500kb of dense object declarations, or + // ~5kb of dense object declarations with 10000% alias expansion. + aliasRatioRangeLow = 400000 + // 4,000,000 decode operations is ~5MB of dense object declarations. + aliasRatioRangeHigh = 4000000 + aliasRatioRange = float64(aliasRatioRangeHigh - aliasRatioRangeLow) + + // tolerated share of alias-driven decodes: from aliasRatioSmall (small/medium documents) + // down to aliasRatioLarge (very large ones), interpolated with slope aliasRatioSlope. + aliasRatioSmall = 0.99 + aliasRatioLarge = 0.10 + aliasRatioSlope = aliasRatioSmall - aliasRatioLarge +) + +var ( + // errMaxNestingDepth is returned when a document nests deeper than [defaultMaxNestingDepth]. + errMaxNestingDepth = fmt.Errorf("maximum nesting depth of %d exceeded: %w", defaultMaxNestingDepth, ErrYAML) + + // errExcessiveAliasing is returned when anchor/alias expansion is disproportionate to the + // size of the document, i.e. an "alias bomb". + errExcessiveAliasing = fmt.Errorf("document contains excessive aliasing: %w", ErrYAML) +) + +// allowedAliasRatio scales the tolerated share of alias-driven decode operations from 99% +// for small-to-medium documents down to 10% for very large ones, mirroring go.yaml.in/yaml/v3. +func allowedAliasRatio(decodeCount int) float64 { + switch { + case decodeCount <= aliasRatioRangeLow: + return aliasRatioSmall + case decodeCount >= aliasRatioRangeHigh: + return aliasRatioLarge + default: + return aliasRatioSmall - aliasRatioSlope*(float64(decodeCount-aliasRatioRangeLow)/aliasRatioRange) + } +} + +// yamlWalker carries the state needed to bound a single YAML-tree traversal: +// anchor/alias expansion accounting and cycle detection. +// +// A fresh walker is created per top-level conversion; it is threaded (not copied) through +// the whole recursive walk so its counters accumulate across the entire document. +type yamlWalker struct { + decodeCount int + aliasCount int + aliasDepth int + aliases map[*yaml.Node]bool // anchors currently being expanded, for cycle detection +} + +func newYAMLWalker() *yamlWalker { + return &yamlWalker{aliases: make(map[*yaml.Node]bool)} +} + +// account records one processed node and fails if alias expansion has become excessive. +func (w *yamlWalker) account() error { + w.decodeCount++ + if w.aliasDepth > 0 { + w.aliasCount++ + } + + if w.aliasCount > aliasCountThreshold && + w.decodeCount > decodeCountThreshold && + float64(w.aliasCount)/float64(w.decodeCount) > allowedAliasRatio(w.decodeCount) { + return errExcessiveAliasing + } + + return nil +} + +// YAMLToJSON converts a YAML document into JSON bytes. +// +// Note: a YAML document is the output from a [yaml.Marshaler], e.g a pointer to a [yaml.Node]. +// +// [YAMLToJSON] is typically called after [BytesToYAMLDoc]. +func YAMLToJSON(value any) (json.RawMessage, error) { + jm, err := transformData(value, 0) + if err != nil { + return nil, err + } + + b, err := jsonutils.WriteJSON(jm) + + return json.RawMessage(b), err +} + +// BytesToYAMLDoc converts a byte slice into a YAML document. +// +// This function only supports root documents that are objects. +// +// A YAML document is a pointer to a [yaml.Node]. +func BytesToYAMLDoc(data []byte) (any, error) { + var document yaml.Node // preserve order that is present in the document + if err := yaml.Unmarshal(data, &document); err != nil { + return nil, err + } + if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode { + return nil, fmt.Errorf("only YAML documents that are objects are supported: %w", ErrYAML) + } + return &document, nil +} + +func (w *yamlWalker) node(root *yaml.Node, depth int) (any, error) { + if depth > defaultMaxNestingDepth { + return nil, errMaxNestingDepth + } + if err := w.account(); err != nil { + return nil, err + } + + switch root.Kind { + case yaml.DocumentNode: + return w.document(root, depth) + case yaml.SequenceNode: + return w.sequence(root, depth) + case yaml.MappingNode: + return w.mapping(root, depth) + case yaml.ScalarNode: + return yamlScalar(root) + case yaml.AliasNode: + return w.alias(root, depth) + default: + return nil, fmt.Errorf("unsupported YAML node type: %v: %w", root.Kind, ErrYAML) + } +} + +// alias resolves an anchor reference, expanding the anchored subtree. It detects cycles +// (an anchor whose expansion transitively references itself) and accounts the expansion +// against the alias-bomb budget via [yamlWalker.aliasDepth]. +func (w *yamlWalker) alias(node *yaml.Node, depth int) (any, error) { + if node.Alias == nil { + return nil, fmt.Errorf("invalid YAML alias node %q: %w", node.Value, ErrYAML) + } + if w.aliases[node.Alias] { + return nil, fmt.Errorf("anchor %q contains itself: %w", node.Value, ErrYAML) + } + + w.aliases[node.Alias] = true + w.aliasDepth++ + out, err := w.node(node.Alias, depth+1) + w.aliasDepth-- + delete(w.aliases, node.Alias) + + return out, err +} + +func (w *yamlWalker) document(node *yaml.Node, depth int) (any, error) { + if len(node.Content) != 1 { + return nil, fmt.Errorf("unexpected YAML Document node content length: %d: %w", len(node.Content), ErrYAML) + } + return w.node(node.Content[0], depth+1) +} + +func (w *yamlWalker) mapping(node *yaml.Node, depth int) (any, error) { + const sensibleAllocDivider = 2 // nodes concatenate (key,value) sequences + m := make(YAMLMapSlice, len(node.Content)/sensibleAllocDivider) + + if err := m.unmarshalYAML(w, node, depth); err != nil { + return nil, err + } + + return m, nil +} + +func (w *yamlWalker) sequence(node *yaml.Node, depth int) (any, error) { + s := make([]any, 0) + + for i := range len(node.Content) { + v, err := w.node(node.Content[i], depth+1) + if err != nil { + return nil, fmt.Errorf("unable to decode YAML sequence value: %w: %w", err, ErrYAML) + } + s = append(s, v) + } + return s, nil +} + +const ( // See https://yaml.org/type/ + yamlStringScalar = "tag:yaml.org,2002:str" + yamlIntScalar = "tag:yaml.org,2002:int" + yamlBoolScalar = "tag:yaml.org,2002:bool" + yamlFloatScalar = "tag:yaml.org,2002:float" + yamlTimestamp = "tag:yaml.org,2002:timestamp" + yamlNull = "tag:yaml.org,2002:null" +) + +func yamlScalar(node *yaml.Node) (any, error) { + switch node.LongTag() { + case yamlStringScalar: + return node.Value, nil + case yamlBoolScalar: + b, err := strconv.ParseBool(node.Value) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting bool content: %w: %w", node.Value, err, ErrYAML) + } + return b, nil + case yamlIntScalar: + i, err := strconv.ParseInt(node.Value, 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting integer content: %w: %w", node.Value, err, ErrYAML) + } + return i, nil + case yamlFloatScalar: + f, err := strconv.ParseFloat(node.Value, 64) + if err != nil { + return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting float content: %w: %w", node.Value, err, ErrYAML) + } + return f, nil + case yamlTimestamp: + // YAML timestamp is marshaled as string, not time + return node.Value, nil + case yamlNull: + return nil, nil //nolint:nilnil + default: + return nil, fmt.Errorf("YAML tag %q is not supported: %w", node.LongTag(), ErrYAML) + } +} + +func yamlStringScalarC(node *yaml.Node) (string, error) { + if node.Kind != yaml.ScalarNode { + return "", fmt.Errorf("expecting a string scalar but got %q: %w", node.Kind, ErrYAML) + } + switch node.LongTag() { + case yamlStringScalar, yamlIntScalar, yamlFloatScalar: + return node.Value, nil + default: + return "", fmt.Errorf("YAML tag %q is not supported as map key: %w", node.LongTag(), ErrYAML) + } +} + +func format(t any) (string, error) { + switch k := t.(type) { + case string: + return k, nil + case uint: + return strconv.FormatUint(uint64(k), 10), nil + case uint8: + return strconv.FormatUint(uint64(k), 10), nil + case uint16: + return strconv.FormatUint(uint64(k), 10), nil + case uint32: + return strconv.FormatUint(uint64(k), 10), nil + case uint64: + return strconv.FormatUint(k, 10), nil + case int: + return strconv.Itoa(k), nil + case int8: + return strconv.FormatInt(int64(k), 10), nil + case int16: + return strconv.FormatInt(int64(k), 10), nil + case int32: + return strconv.FormatInt(int64(k), 10), nil + case int64: + return strconv.FormatInt(k, 10), nil + default: + return "", fmt.Errorf("unexpected map key type, got: %T: %w", k, ErrYAML) + } +} + +func transformData(input any, depth int) (out any, err error) { + if depth > defaultMaxNestingDepth { + return nil, errMaxNestingDepth + } + + switch in := input.(type) { + case yaml.Node: + return newYAMLWalker().node(&in, depth) + case *yaml.Node: + return newYAMLWalker().node(in, depth) + case map[any]any: + o := make(YAMLMapSlice, 0, len(in)) + for ke, va := range in { + var nmi YAMLMapItem + if nmi.Key, err = format(ke); err != nil { + return nil, err + } + + v, ert := transformData(va, depth+1) + if ert != nil { + return nil, ert + } + nmi.Value = v + o = append(o, nmi) + } + return o, nil + case []any: + len1 := len(in) + o := make([]any, len1) + for i := range len1 { + o[i], err = transformData(in[i], depth+1) + if err != nil { + return nil, err + } + } + return o, nil + } + return input, nil +} diff --git a/vendor/github.com/go-openapi/swag/yamlutils_iface.go b/vendor/github.com/go-openapi/swag/yamlutils_iface.go new file mode 100644 index 00000000..57767efc --- /dev/null +++ b/vendor/github.com/go-openapi/swag/yamlutils_iface.go @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package swag + +import ( + "encoding/json" + + "github.com/go-openapi/swag/yamlutils" +) + +// YAMLToJSON converts YAML unmarshaled data into json compatible data +// +// Deprecated: use [yamlutils.YAMLToJSON] instead. +func YAMLToJSON(data any) (json.RawMessage, error) { return yamlutils.YAMLToJSON(data) } + +// BytesToYAMLDoc converts a byte slice into a YAML document +// +// Deprecated: use [yamlutils.BytesToYAMLDoc] instead. +func BytesToYAMLDoc(data []byte) (any, error) { return yamlutils.BytesToYAMLDoc(data) } diff --git a/vendor/github.com/google/go-containerregistry/internal/ipaddr/ipaddr.go b/vendor/github.com/google/go-containerregistry/internal/ipaddr/ipaddr.go new file mode 100644 index 00000000..a7f5b8a4 --- /dev/null +++ b/vendor/github.com/google/go-containerregistry/internal/ipaddr/ipaddr.go @@ -0,0 +1,82 @@ +// Copyright 2026 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ipaddr + +import ( + "net/netip" + "strconv" + "strings" +) + +// IsPrivateOrLinkLocal reports whether host denotes a loopback, private, +// link-local, or unspecified address. It accepts any IP-literal form the Go +// dialer accepts — canonical dotted-quad IPv4 and IPv6, zone-qualified and +// IPv4-mapped IPv6, and legacy inet_aton encodings (32-bit decimal +// "2130706433", hexadecimal "0x7f000001", partial dotted-quad "127.1", +// zero-padded octets) — so a guard based on it cannot be bypassed by +// spelling an internal address in a non-canonical way. DNS names are not IP +// literals and return false. +func IsPrivateOrLinkLocal(host string) bool { + addr, ok := Parse(host) + if !ok { + return false + } + return addr.IsLoopback() || addr.IsLinkLocalUnicast() || addr.IsLinkLocalMulticast() || + addr.IsPrivate() || addr.IsUnspecified() +} + +// Parse parses an IP literal in any form the Go dialer accepts. +func Parse(host string) (netip.Addr, bool) { + // The dialer ignores IPv6 zone identifiers, so guards must too. + host, _, _ = strings.Cut(host, "%") + if addr, err := netip.ParseAddr(host); err == nil { + // Treat IPv4-mapped IPv6 as the IPv4 address the dialer connects to. + return addr.WithZone("").Unmap(), true + } + return parseLegacyIPv4(host) +} + +// parseLegacyIPv4 implements the inet_aton forms the Go resolver accepts for +// IPv4: one to four dot-separated parts where the final part may fill the +// remaining bytes ("127.1" == 127.0.0.1) and each part may be decimal, +// hexadecimal (0x prefix), or octal (leading 0). +func parseLegacyIPv4(host string) (netip.Addr, bool) { + parts := strings.Split(host, ".") + if len(parts) < 1 || len(parts) > 4 { + return netip.Addr{}, false + } + var b [4]byte + for i, part := range parts[:len(parts)-1] { + // bitsize 8 enforces the single-octet range before any conversion. + v, err := strconv.ParseUint(part, 0, 8) + if err != nil { + return netip.Addr{}, false + } + b[i] = byte(v) + } + // The final part may fill as many bytes as remain, e.g. "127.1" -> 127.0.0.1; + // with four parts it must still be a single octet. The bitsize enforces the + // range before the conversion below. + lastBits := [...]int{32, 24, 16, 8}[len(parts)-1] + last, err := strconv.ParseUint(parts[len(parts)-1], 0, lastBits) + if err != nil { + return netip.Addr{}, false + } + v := uint32(last) + for i := len(parts) - 1; i < 4; i++ { + b[i] = byte(v >> (8 * (3 - i))) + } + return netip.AddrFrom4(b), true +} diff --git a/vendor/github.com/google/go-containerregistry/internal/verify/verify.go b/vendor/github.com/google/go-containerregistry/internal/verify/verify.go index 463f7e4b..ff48ba87 100644 --- a/vendor/github.com/google/go-containerregistry/internal/verify/verify.go +++ b/vendor/github.com/google/go-containerregistry/internal/verify/verify.go @@ -17,7 +17,6 @@ package verify import ( - "bytes" "encoding/hex" "errors" "fmt" @@ -107,10 +106,16 @@ func Descriptor(d v1.Descriptor) error { return errors.New("error verifying descriptor; Data == nil") } - h, sz, err := v1.SHA256(bytes.NewReader(d.Data)) + hasher, err := v1.Hasher(d.Digest.Algorithm) if err != nil { return err } + hasher.Write(d.Data) + h := v1.Hash{ + Algorithm: d.Digest.Algorithm, + Hex: hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))), + } + sz := int64(len(d.Data)) if h != d.Digest { return fmt.Errorf("error verifying Digest; got %q, want %q", h, d.Digest) } diff --git a/vendor/github.com/google/go-containerregistry/pkg/authn/authn.go b/vendor/github.com/google/go-containerregistry/pkg/authn/authn.go index 1555efae..c962235c 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/authn/authn.go +++ b/vendor/github.com/google/go-containerregistry/pkg/authn/authn.go @@ -89,7 +89,9 @@ func (a *AuthConfig) UnmarshalJSON(data []byte) error { // MarshalJSON implements json.Marshaler func (a AuthConfig) MarshalJSON() ([]byte, error) { shadow := (authConfig)(a) - shadow.Auth = encodeDockerConfigFieldAuth(shadow.Username, shadow.Password) + if shadow.Username != "" || shadow.Password != "" { + shadow.Auth = encodeDockerConfigFieldAuth(shadow.Username, shadow.Password) + } return json.Marshal(shadow) } diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/digest.go b/vendor/github.com/google/go-containerregistry/pkg/name/digest.go index 5b8eb4ff..9d6650ee 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/name/digest.go +++ b/vendor/github.com/google/go-containerregistry/pkg/name/digest.go @@ -17,6 +17,8 @@ package name import ( // nolint: depguard _ "crypto/sha256" // Recommended by go-digest. + // nolint: depguard + _ "crypto/sha512" // Needed for sha512 digests. "encoding" "encoding/json" "strings" @@ -107,13 +109,8 @@ func NewDigest(name string, opts ...Option) (Digest, error) { } base := parts[0] dig := parts[1] - prefix := digest.Canonical.String() + ":" - if !strings.HasPrefix(dig, prefix) { - return Digest{}, newErrBadName("unsupported digest algorithm: %s", dig) - } - hex := strings.TrimPrefix(dig, prefix) - if err := digest.Canonical.Validate(hex); err != nil { - return Digest{}, err + if err := digest.Digest(dig).Validate(); err != nil { + return Digest{}, newErrBadName("%s: %s", err, dig) } tag, err := NewTag(base, opts...) diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/ref.go b/vendor/github.com/google/go-containerregistry/pkg/name/ref.go index 539d0ff3..1ce999a2 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/name/ref.go +++ b/vendor/github.com/google/go-containerregistry/pkg/name/ref.go @@ -16,6 +16,7 @@ package name import ( "fmt" + "strings" ) // Reference defines the interface that consumers use when they can @@ -39,6 +40,11 @@ type Reference interface { // ParseReference parses the string as a reference, either by tag or digest. // References that include both a tag and digest parse as Digest references. func ParseReference(s string, opts ...Option) (Reference, error) { + // Image references never contain a URL scheme, so tell the user to + // strip it instead of returning a confusing parse error. + if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") { + return nil, newErrBadName("image reference must not contain a URL scheme (http:// or https://): %s; to connect to a registry over plain HTTP, use name.Insecure", s) + } if t, err := NewTag(s, opts...); err == nil { return t, nil } diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/repository.go b/vendor/github.com/google/go-containerregistry/pkg/name/repository.go index efde6e86..ad7b3291 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/name/repository.go +++ b/vendor/github.com/google/go-containerregistry/pkg/name/repository.go @@ -72,7 +72,7 @@ func (r Repository) Scope(action string) string { } func checkRepository(repository string) error { - return checkElement("repository", repository, repositoryChars, 2, 255) + return checkElement("repository", repository, repositoryChars, 1, 255) } // NewRepository returns a new Repository representing the given name, according to the given strictness. diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/hash.go b/vendor/github.com/google/go-containerregistry/pkg/v1/hash.go index bbb600ed..4114d5ab 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/hash.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/hash.go @@ -16,6 +16,10 @@ package v1 import ( "crypto" + // nolint: depguard + _ "crypto/sha256" // Registered for Hasher. + // nolint: depguard + _ "crypto/sha512" // Registered for Hasher. "encoding" "encoding/hex" "encoding/json" @@ -78,6 +82,8 @@ func Hasher(name string) (hash.Hash, error) { switch name { case "sha256": return crypto.SHA256.New(), nil + case "sha512": + return crypto.SHA512.New(), nil default: return nil, fmt.Errorf("unsupported hash: %q", name) } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/index.go b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/index.go index a6fdacee..7b4ed088 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/index.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/index.go @@ -56,6 +56,9 @@ func computeDescriptor(ia IndexAddendum) (*v1.Descriptor, error) { if ia.Data != nil { desc.Data = ia.Data } + if ia.ArtifactType != "" { + desc.ArtifactType = ia.ArtifactType + } return desc, nil } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go index 596c78cb..00ad8c0d 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go @@ -24,9 +24,9 @@ import ( "maps" "path" "strings" + "sync" "time" - "github.com/google/go-containerregistry/internal/gzip" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/empty" "github.com/google/go-containerregistry/pkg/v1/match" @@ -469,7 +469,8 @@ func hasWindowsDrivePrefix(name string) bool { } // Time sets all timestamps in an image to the given timestamp. -func Time(img v1.Image, t time.Time) (v1.Image, error) { +// Layers are rewritten as dockerv2+gzip unless opts say otherwise. +func Time(img v1.Image, t time.Time, opts ...tarball.LayerOption) (v1.Image, error) { newImage := empty.Image layers, err := img.Layers() @@ -485,10 +486,7 @@ func Time(img v1.Image, t time.Time) (v1.Image, error) { addendums := make([]Addendum, max(len(ocf.History), len(layers))) var historyIdx, addendumIdx int for layerIdx := 0; layerIdx < len(layers); addendumIdx, layerIdx = addendumIdx+1, layerIdx+1 { - newLayer, err := layerTime(layers[layerIdx], t) - if err != nil { - return nil, fmt.Errorf("setting layer times: %w", err) - } + newLayer := layerTime(layers[layerIdx], t, opts...) // try to search for the history entry that corresponds to this layer for ; historyIdx < len(ocf.History); historyIdx++ { @@ -547,7 +545,28 @@ func Time(img v1.Image, t time.Time) (v1.Image, error) { return ConfigFile(newImage, cfg) } -func layerTime(layer v1.Layer, t time.Time) (v1.Layer, error) { +func layerTime(layer v1.Layer, t time.Time, opts ...tarball.LayerOption) v1.Layer { + return &timeLayer{inner: layer, t: t, opts: opts} +} + +type timeLayer struct { + inner v1.Layer + t time.Time + opts []tarball.LayerOption + + once sync.Once + material v1.Layer + err error +} + +func (l *timeLayer) materialize() error { + l.once.Do(func() { + l.material, l.err = materializeLayerTime(l.inner, l.t, l.opts...) + }) + return l.err +} + +func materializeLayerTime(layer v1.Layer, t time.Time, opts ...tarball.LayerOption) (v1.Layer, error) { layerReader, err := layer.Uncompressed() if err != nil { return nil, fmt.Errorf("getting layer: %w", err) @@ -580,7 +599,6 @@ func layerTime(layer v1.Layer, t time.Time) (v1.Layer, error) { } if header.Typeflag == tar.TypeReg { - // TODO(#1168): This should be lazy, and not buffer the entire layer contents. if _, err = io.CopyN(tarWriter, tarReader, header.Size); err != nil { return nil, fmt.Errorf("writing layer file: %w", err) } @@ -598,24 +616,65 @@ func layerTime(layer v1.Layer, t time.Time) (v1.Layer, error) { } b := w.Bytes() - // gzip the contents, then create the layer opener := func() (io.ReadCloser, error) { - return gzip.ReadCloser(io.NopCloser(bytes.NewReader(b))), nil + return io.NopCloser(bytes.NewReader(b)), nil } - layer, err = tarball.LayerFromOpener(opener) + newLayer, err := tarball.LayerFromOpener(opener, opts...) if err != nil { return nil, fmt.Errorf("creating layer: %w", err) } - return layer, nil + return newLayer, nil +} + +func (l *timeLayer) Compressed() (io.ReadCloser, error) { + if err := l.materialize(); err != nil { + return nil, err + } + return l.material.Compressed() +} + +func (l *timeLayer) Uncompressed() (io.ReadCloser, error) { + if err := l.materialize(); err != nil { + return nil, err + } + return l.material.Uncompressed() +} + +func (l *timeLayer) Size() (int64, error) { + if err := l.materialize(); err != nil { + return 0, err + } + return l.material.Size() +} + +func (l *timeLayer) DiffID() (v1.Hash, error) { + if err := l.materialize(); err != nil { + return v1.Hash{}, err + } + return l.material.DiffID() +} + +func (l *timeLayer) Digest() (v1.Hash, error) { + if err := l.materialize(); err != nil { + return v1.Hash{}, err + } + return l.material.Digest() +} + +func (l *timeLayer) MediaType() (types.MediaType, error) { + if err := l.materialize(); err != nil { + return "", err + } + return l.material.MediaType() } // Canonical is a helper function to combine Time and configFile // to remove any randomness during a docker build. -func Canonical(img v1.Image) (v1.Image, error) { +func Canonical(img v1.Image, opts ...tarball.LayerOption) (v1.Image, error) { // Set all timestamps to 0 created := time.Time{} - img, err := Time(img, created) + img, err := Time(img, created, opts...) if err != nil { return nil, err } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go index ac879a67..06e90990 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go @@ -32,9 +32,9 @@ import ( // // TODO(#412): Remove the need for this method. func CheckPushPermission(ref name.Reference, kc authn.Keychain, t http.RoundTripper) error { - auth, err := kc.Resolve(ref.Context().Registry) + auth, err := authn.Resolve(context.TODO(), kc, ref.Context()) if err != nil { - return fmt.Errorf("resolving authorization for %v failed: %w", ref.Context().Registry, err) + return fmt.Errorf("resolving authorization for %v failed: %w", ref.Context(), err) } scopes := []string{ref.Scope(transport.PushScope)} @@ -50,7 +50,7 @@ func CheckPushPermission(ref name.Reference, kc authn.Keychain, t http.RoundTrip // to avoid a roundtrip for spec-compliant registries. w := writer{ repo: ref.Context(), - client: &http.Client{Transport: tr}, + client: &http.Client{Transport: tr, CheckRedirect: checkRedirectSSRF}, } loc, _, err := w.initiateUpload(context.Background(), "", "", "") if loc != "" { diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/fetcher.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/fetcher.go index 4b238d12..26605d97 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/fetcher.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/fetcher.go @@ -17,13 +17,14 @@ package remote import ( "bytes" "context" + "encoding/hex" "fmt" "io" - "net" "net/http" "net/url" "strings" + "github.com/google/go-containerregistry/internal/ipaddr" "github.com/google/go-containerregistry/internal/limit" "github.com/google/go-containerregistry/internal/redact" "github.com/google/go-containerregistry/internal/verify" @@ -98,10 +99,8 @@ func checkRedirectSSRF(req *http.Request, via []*http.Request) error { if destHost == origHost { return nil // same-host redirect is always allowed } - if ip := net.ParseIP(destHost); ip != nil { - if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsPrivate() || ip.IsUnspecified() { - return fmt.Errorf("SSRF protection: redirect from %q to private/link-local host %q denied", origHost, destHost) - } + if ipaddr.IsPrivateOrLinkLocal(destHost) { + return fmt.Errorf("SSRF protection: redirect from %q to private/link-local host %q denied", origHost, destHost) } return nil } @@ -174,10 +173,26 @@ func (f *fetcher) fetchManifest(ctx context.Context, ref name.Reference, accepta return nil, nil, err } - digest, size, err := v1.SHA256(bytes.NewReader(manifest)) + // Hash with the algorithm of the reference when pulling by digest. + dgst, byDigest := ref.(name.Digest) + algo := "sha256" + if byDigest { + h, err := v1.NewHash(dgst.DigestStr()) + if err != nil { + return nil, nil, err + } + algo = h.Algorithm + } + hasher, err := v1.Hasher(algo) if err != nil { return nil, nil, err } + hasher.Write(manifest) + digest := v1.Hash{ + Algorithm: algo, + Hex: hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))), + } + size := int64(len(manifest)) mediaType := types.MediaType(resp.Header.Get("Content-Type")) contentDigest, err := v1.NewHash(resp.Header.Get("Docker-Content-Digest")) @@ -188,7 +203,7 @@ func (f *fetcher) fetchManifest(ctx context.Context, ref name.Reference, accepta } // Validate the digest matches what we asked for, if pulling by digest. - if dgst, ok := ref.(name.Digest); ok { + if byDigest { if digest.String() != dgst.DigestStr() { return nil, nil, fmt.Errorf("manifest digest: %q does not match requested digest: %q for %q", digest, dgst.DigestStr(), ref) } @@ -380,10 +395,8 @@ func validateForeignURL(rawURL string, insecure bool) error { return fmt.Errorf("foreign layer URL scheme %q not allowed; must be https (or http for insecure registries)", u.Scheme) } host := u.Hostname() - if ip := net.ParseIP(host); ip != nil { - if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsPrivate() || ip.IsUnspecified() { - return fmt.Errorf("foreign layer URL host %q is a private or link-local address", host) - } + if ipaddr.IsPrivateOrLinkLocal(host) { + return fmt.Errorf("foreign layer URL host %q is a private or link-local address", host) } return nil } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go index bcb0d735..094162ec 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go @@ -76,7 +76,11 @@ func (p *Puller) fetcher(ctx context.Context, target resource) (*fetcher, error) o: p.o, }) rr := v.(*reader) - return rr.f, rr.init(ctx) + if err := rr.init(ctx); err != nil { + p.readers.CompareAndDelete(target, rr) + return nil, err + } + return rr.f, nil } // Head is like remote.Head, but avoids re-authenticating when possible. diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go index 3a1d16f5..3466c7a6 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go @@ -122,7 +122,11 @@ func (p *Pusher) writer(ctx context.Context, repo name.Repository, o *options) ( o: o, }) rw := v.(*repoWriter) - return rw, rw.init(ctx) + if err := rw.init(ctx); err != nil { + p.writers.CompareAndDelete(repo, rw) + return nil, err + } + return rw, nil } func (p *Pusher) Put(ctx context.Context, ref name.Reference, t Taggable) error { diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go index f576ccd3..b9848276 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go @@ -25,6 +25,7 @@ import ( "strings" "sync" + "github.com/google/go-containerregistry/internal/ipaddr" "github.com/google/go-containerregistry/internal/limit" "github.com/google/go-containerregistry/internal/redact" "github.com/google/go-containerregistry/pkg/authn" @@ -151,10 +152,8 @@ func validateRealmURL(realm, registryHost string, insecure bool) error { // (169.254.169.254 / fd00:ec2::254). DNS-based SSRF is out of scope // here; callers should apply network-level controls if needed. host := u.Hostname() - if ip := net.ParseIP(host); ip != nil { - if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsPrivate() || ip.IsUnspecified() { - return fmt.Errorf("realm host %q is a private or link-local address", host) - } + if ipaddr.IsPrivateOrLinkLocal(host) { + return fmt.Errorf("realm host %q is a private or link-local address", host) } return nil } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go index 01e9c767..4064711f 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go @@ -21,13 +21,13 @@ import ( "errors" "fmt" "io" - "net" "net/http" "net/url" "sort" "strings" "sync" + "github.com/google/go-containerregistry/internal/ipaddr" "github.com/google/go-containerregistry/internal/redact" "github.com/google/go-containerregistry/internal/retry" "github.com/google/go-containerregistry/pkg/authn" @@ -92,7 +92,7 @@ func makeDeleteClient(ctx context.Context, repo name.Repository, o *options) (*h if err != nil { return nil, err } - return &http.Client{Transport: tr}, nil + return &http.Client{Transport: tr, CheckRedirect: checkRedirectSSRF}, nil } func makeWriter(ctx context.Context, repo name.Repository, ls []v1.Layer, o *options) (*writer, error) { @@ -116,7 +116,7 @@ func makeWriter(ctx context.Context, repo name.Repository, ls []v1.Layer, o *opt } return &writer{ repo: repo, - client: &http.Client{Transport: tr}, + client: &http.Client{Transport: tr, CheckRedirect: checkRedirectSSRF}, auth: auth, transport: o.transport, progress: o.progress, @@ -159,7 +159,7 @@ func (w *writer) maybeUpdateScopes(ctx context.Context, ml *MountableLayer) erro if err != nil { return err } - w.client = &http.Client{Transport: wt} + w.client = &http.Client{Transport: wt, CheckRedirect: checkRedirectSSRF} } return nil @@ -193,10 +193,8 @@ func (w *writer) nextLocation(resp *http.Response) (string, error) { // always allowed regardless of whether the registry IP is private. origHost := resp.Request.URL.Hostname() if destHost := resolved.Hostname(); destHost != origHost { - if ip := net.ParseIP(destHost); ip != nil { - if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsPrivate() || ip.IsUnspecified() { - return "", fmt.Errorf("SSRF protection: Location header redirects to private/link-local host %q", destHost) - } + if ipaddr.IsPrivateOrLinkLocal(destHost) { + return "", fmt.Errorf("SSRF protection: Location header redirects to private/link-local host %q", destHost) } } @@ -610,9 +608,10 @@ func (w *writer) commitManifest(ctx context.Context, t Taggable, ref name.Refere return err } var mf struct { - MediaType types.MediaType `json:"mediaType"` - Subject *v1.Descriptor `json:"subject,omitempty"` - ArtifactType string `json:"artifactType,omitempty"` + MediaType types.MediaType `json:"mediaType"` + Subject *v1.Descriptor `json:"subject,omitempty"` + ArtifactType string `json:"artifactType,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` Config struct { MediaType types.MediaType `json:"mediaType"` } `json:"config"` @@ -655,9 +654,10 @@ func (w *writer) commitManifest(ctx context.Context, t Taggable, ref name.Refere return err } desc := v1.Descriptor{ - MediaType: mf.MediaType, - Digest: h, - Size: size, + MediaType: mf.MediaType, + Digest: h, + Size: size, + Annotations: mf.Annotations, } if mf.ArtifactType != "" { desc.ArtifactType = mf.ArtifactType diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/types/types.go b/vendor/github.com/google/go-containerregistry/pkg/v1/types/types.go index c86657d7..69878980 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/types/types.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/types/types.go @@ -29,6 +29,7 @@ const ( OCIRestrictedLayer MediaType = "application/vnd.oci.image.layer.nondistributable.v1.tar+gzip" OCIUncompressedLayer MediaType = "application/vnd.oci.image.layer.v1.tar" OCIUncompressedRestrictedLayer MediaType = "application/vnd.oci.image.layer.nondistributable.v1.tar" + OCIEmptyJSON MediaType = "application/vnd.oci.empty.v1+json" DockerManifestSchema1 MediaType = "application/vnd.docker.distribution.manifest.v1+json" DockerManifestSchema1Signed MediaType = "application/vnd.docker.distribution.manifest.v1+prettyjws" diff --git a/vendor/github.com/josharian/intern/README.md b/vendor/github.com/josharian/intern/README.md deleted file mode 100644 index ffc44b21..00000000 --- a/vendor/github.com/josharian/intern/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Docs: https://godoc.org/github.com/josharian/intern - -See also [Go issue 5160](https://golang.org/issue/5160). - -License: MIT diff --git a/vendor/github.com/josharian/intern/intern.go b/vendor/github.com/josharian/intern/intern.go deleted file mode 100644 index 7acb1fe9..00000000 --- a/vendor/github.com/josharian/intern/intern.go +++ /dev/null @@ -1,44 +0,0 @@ -// Package intern interns strings. -// Interning is best effort only. -// Interned strings may be removed automatically -// at any time without notification. -// All functions may be called concurrently -// with themselves and each other. -package intern - -import "sync" - -var ( - pool sync.Pool = sync.Pool{ - New: func() interface{} { - return make(map[string]string) - }, - } -) - -// String returns s, interned. -func String(s string) string { - m := pool.Get().(map[string]string) - c, ok := m[s] - if ok { - pool.Put(m) - return c - } - m[s] = s - pool.Put(m) - return s -} - -// Bytes returns b converted to a string, interned. -func Bytes(b []byte) string { - m := pool.Get().(map[string]string) - c, ok := m[string(b)] - if ok { - pool.Put(m) - return c - } - s := string(b) - m[s] = s - pool.Put(m) - return s -} diff --git a/vendor/github.com/josharian/intern/license.md b/vendor/github.com/josharian/intern/license.md deleted file mode 100644 index 353d3055..00000000 --- a/vendor/github.com/josharian/intern/license.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Josh Bleecher Snyder - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index 2d6ef64b..7035d656 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -1,222 +1,49 @@ //go:build amd64 && !appengine && !noasm && gc -// This file contains the specialisation of Decoder.Decompress4X -// and Decoder.Decompress1X that use an asm implementation of thir main loops. +// amd64 stubs and dispatch for the asm loops used by decompress_asm.go. package huff0 import ( - "errors" - "fmt" - "github.com/klauspost/compress/internal/cpuinfo" ) -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress4x_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog > 8. // //go:noescape func decompress4x_main_loop_amd64(ctx *decompress4xContext) -// decompress4x_8b_loop_x86 is an x86 assembler implementation +// decompress4x_8b_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog <= 8 which decodes 4 entries // per loop. // //go:noescape func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) -// fallback8BitSize is the size where using Go version is faster. -const fallback8BitSize = 800 - -type decompress4xContext struct { - pbr *[4]bitReaderShifted - peekBits uint8 - out *byte - dstEvery int - tbl *dEntrySingle - decoded int - limit *byte -} - -// Decompress4X will decompress a 4X encoded stream. -// The length of the supplied input must match the end of a block exactly. -// The *capacity* of the dst slice must match the destination size of -// the uncompressed data exactly. -func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - if len(src) < 6+(4*1) { - return nil, errors.New("input too small") - } - - use8BitTables := d.actualTableLog <= 8 - if cap(dst) < fallback8BitSize && use8BitTables { - return d.decompress4X8bit(dst, src) - } - - var br [4]bitReaderShifted - // Decode "jump table" - start := 6 - for i := range 3 { - length := int(src[i*2]) | (int(src[i*2+1]) << 8) - if start+length >= len(src) { - return nil, errors.New("truncated input (or invalid offset)") - } - err := br[i].init(src[start : start+length]) - if err != nil { - return nil, err - } - start += length - } - err := br[3].init(src[start:]) - if err != nil { - return nil, err - } - - // destination, offset to match first output - dstSize := cap(dst) - dst = dst[:dstSize] - out := dst - dstEvery := (dstSize + 3) / 4 - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - single := d.dt.single[:tlSize] - - var decoded int - - if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { - ctx := decompress4xContext{ - pbr: &br, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - out: &out[0], - dstEvery: dstEvery, - tbl: &single[0], - limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. - } - if use8BitTables { - decompress4x_8b_main_loop_amd64(&ctx) - } else { - decompress4x_main_loop_amd64(&ctx) - } - - decoded = ctx.decoded - out = out[decoded/4:] - } - - // Decode remaining. - remainBytes := dstEvery - (decoded / 4) - for i := range br { - offset := dstEvery * i - endsAt := min(offset+remainBytes, len(out)) - br := &br[i] - bitsLeft := br.remaining() - for bitsLeft > 0 { - br.fill() - if offset >= endsAt { - return nil, errors.New("corruption detected: stream overrun 4") - } - - // Read value and increment offset. - val := br.peekBitsFast(d.actualTableLog) - v := single[val&tlMask].entry - nBits := uint8(v) - br.advance(nBits) - bitsLeft -= uint(nBits) - out[offset] = uint8(v >> 8) - offset++ - } - if offset != endsAt { - return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) - } - decoded += offset - dstEvery*i - err = br.close() - if err != nil { - return nil, err - } - } - if dstSize != decoded { - return nil, errors.New("corruption detected: short output block") - } - return dst, nil -} - -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress1x_main_loop_amd64 is an x86 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_amd64(ctx *decompress1xContext) -// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation +// decompress1x_main_loop_bmi2 is an x86 with BMI2 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_bmi2(ctx *decompress1xContext) -type decompress1xContext struct { - pbr *bitReaderShifted - peekBits uint8 - out *byte - outCap int - tbl *dEntrySingle - decoded int +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_amd64(ctx) } -// Error reported by asm implementations -const error_max_decoded_size_exeeded = -1 - -// Decompress1X will decompress a 1X encoded stream. -// The cap of the output buffer will be the maximum decompressed size. -// The length of the supplied input must match the end of a block exactly. -func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - var br bitReaderShifted - err := br.init(src) - if err != nil { - return dst, err - } - maxDecodedSize := cap(dst) - dst = dst[:maxDecodedSize] - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - - if maxDecodedSize >= 4 { - ctx := decompress1xContext{ - pbr: &br, - out: &dst[0], - outCap: maxDecodedSize, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - tbl: &d.dt.single[0], - } - - if cpuinfo.HasBMI2() { - decompress1x_main_loop_bmi2(&ctx) - } else { - decompress1x_main_loop_amd64(&ctx) - } - if ctx.decoded == error_max_decoded_size_exeeded { - return nil, ErrMaxDecodedSizeExceeded - } - - dst = dst[:ctx.decoded] - } +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_amd64(ctx) +} - // br < 8, so uint8 is fine - bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead - for bitsLeft > 0 { - br.fill() - if len(dst) >= maxDecodedSize { - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] - nBits := uint8(v.entry) - br.advance(nBits) - bitsLeft -= nBits - dst = append(dst, uint8(v.entry>>8)) +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + if cpuinfo.HasBMI2() { + decompress1x_main_loop_bmi2(ctx) + } else { + decompress1x_main_loop_amd64(ctx) } - return dst, br.close() } diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index c4c7ab2d..c5d4a710 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,6 +1,6 @@ -// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT. +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. -//go:build amd64 && !appengine && !noasm && gc +//go:build !appengine && !noasm && gc // func decompress4x_main_loop_amd64(ctx *decompress4xContext) TEXT ·decompress4x_main_loop_amd64(SB), $0-8 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go new file mode 100644 index 00000000..8ba3c810 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go @@ -0,0 +1,37 @@ +//go:build arm64 && !appengine && !noasm && gc + +// arm64 stubs and dispatch for the asm loops used by decompress_asm.go. +// The asm (decompress_arm64.s) is generated by the avo arm64 lowering +// printer from the same source as the amd64 asm; see _generate/gen.go. +package huff0 + +// decompress4x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog > 8. +// +//go:noescape +func decompress4x_main_loop_arm64(ctx *decompress4xContext) + +// decompress4x_8b_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog <= 8 which decodes 4 entries +// per loop. +// +//go:noescape +func decompress4x_8b_main_loop_arm64(ctx *decompress4xContext) + +// decompress1x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_arm64(ctx *decompress1xContext) + +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_arm64(ctx) +} + +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_arm64(ctx) +} + +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + decompress1x_main_loop_arm64(ctx) +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s new file mode 100644 index 00000000..e1601272 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s @@ -0,0 +1,851 @@ +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. +// EXPERIMENTAL arm64 output lowered from an amd64 avo program. + +//go:build arm64 && !appengine && !noasm && gc + +// func decompress4x_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R0 + MOVBU 8(R0), R6 + MOVD 16(R0), R3 + MOVD 48(R0), R5 + MOVD 24(R0), R7 + MOVD 32(R0), R8 + MOVD (R0), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD (R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 24(R9) + ORR R12, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVH R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 48(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 72(R9) + ORR R12, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 96(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 120(R9) + ORR R12, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7<<1, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 144(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 168(R9) + ORR R12, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7<<1, R7, R1 + ADD R1, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x02, R3, R3 + AND $0xff, R2, R15 + AND $0xff, R2, R16 + TST R16, R15 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_8b_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R1 + MOVBU 8(R1), R6 + MOVD 16(R1), R3 + MOVD 48(R1), R5 + MOVD 24(R1), R7 + MOVD 32(R1), R8 + MOVD (R1), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD (R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 24(R9) + ORR R13, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVW R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 48(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 72(R9) + ORR R13, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 96(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 120(R9) + ORR R13, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 144(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 168(R9) + ORR R13, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R7, R1 + ADD R1, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x04, R3, R3 + AND $0xff, R2, R15 + AND $0xff, R2, R16 + TST R16, R15 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress1x_main_loop_amd64(ctx *decompress1xContext) +TEXT ·decompress1x_main_loop_arm64(SB), $0-8 + MOVD ctx+0(FP), R1 + MOVD 16(R1), R2 + MOVD 24(R1), R3 + CMP $0x04, R3 + BLO error_max_decoded_size_exceeded + ADD R3, R2, R3 + MOVD (R1), R5 + MOVD (R5), R7 + MOVD 24(R5), R8 + MOVD 32(R5), R9 + MOVBU 40(R5), R10 + MOVD 32(R1), R5 + MOVBU 8(R1), R6 + JMP loop_condition + +main_loop: + // Check if we have room for 4 bytes in the output buffer + ADD $4, R2, R1 + CMP R3, R1 + BGE error_max_decoded_size_exceeded + + // Decode 4 values + CMP $0x20, R10 + BLT bitReader_fillFast_1_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + ADD R8, R7, R15 + MOVWU (R15), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_1_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + CMP $0x20, R10 + BLT bitReader_fillFast_2_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + ADD R8, R7, R15 + MOVWU (R15), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_2_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + + // Store the decoded values + MOVW R0, (R2) + ADD $0x04, R2, R2 + +loop_condition: + CMP $0x08, R8 + BGE main_loop + + // Update ctx structure + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R2, R2 + MOVD R2, 40(R0) + MOVD (R0), R0 + MOVD R8, 24(R0) + MOVD R9, 32(R0) + MOVB R10, 40(R0) + RET + + // Report error +error_max_decoded_size_exceeded: + MOVD ctx+0(FP), R0 + MOVD $-1, R1 + MOVD R1, 40(R0) + RET + +// skipped decompress1x_main_loop_bmi2 (generic twin preferred on arm64) diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_asm.go b/vendor/github.com/klauspost/compress/huff0/decompress_asm.go new file mode 100644 index 00000000..4854dd43 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_asm.go @@ -0,0 +1,193 @@ +//go:build (amd64 || arm64) && !appengine && !noasm && gc + +// This file contains the specialisation of Decoder.Decompress4X +// and Decoder.Decompress1X that use an asm implementation of their main loops. +// The asm function stubs and any per-arch dispatch live in decompress_amd64.go +// and decompress_arm64.go. +package huff0 + +import ( + "errors" + "fmt" +) + +// fallback8BitSize is the size where using Go version is faster. +const fallback8BitSize = 800 + +type decompress4xContext struct { + pbr *[4]bitReaderShifted + peekBits uint8 + out *byte + dstEvery int + tbl *dEntrySingle + decoded int + limit *byte +} + +// Decompress4X will decompress a 4X encoded stream. +// The length of the supplied input must match the end of a block exactly. +// The *capacity* of the dst slice must match the destination size of +// the uncompressed data exactly. +func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + if len(src) < 6+(4*1) { + return nil, errors.New("input too small") + } + + use8BitTables := d.actualTableLog <= 8 + if cap(dst) < fallback8BitSize && use8BitTables { + return d.decompress4X8bit(dst, src) + } + + var br [4]bitReaderShifted + // Decode "jump table" + start := 6 + for i := range 3 { + length := int(src[i*2]) | (int(src[i*2+1]) << 8) + if start+length >= len(src) { + return nil, errors.New("truncated input (or invalid offset)") + } + err := br[i].init(src[start : start+length]) + if err != nil { + return nil, err + } + start += length + } + err := br[3].init(src[start:]) + if err != nil { + return nil, err + } + + // destination, offset to match first output + dstSize := cap(dst) + dst = dst[:dstSize] + out := dst + dstEvery := (dstSize + 3) / 4 + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + single := d.dt.single[:tlSize] + + var decoded int + + if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { + ctx := decompress4xContext{ + pbr: &br, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + out: &out[0], + dstEvery: dstEvery, + tbl: &single[0], + limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. + } + if use8BitTables { + decompress4x_8b_main_loop_asm(&ctx) + } else { + decompress4x_main_loop_asm(&ctx) + } + + decoded = ctx.decoded + out = out[decoded/4:] + } + + // Decode remaining. + remainBytes := dstEvery - (decoded / 4) + for i := range br { + offset := dstEvery * i + endsAt := min(offset+remainBytes, len(out)) + br := &br[i] + bitsLeft := br.remaining() + for bitsLeft > 0 { + br.fill() + if offset >= endsAt { + return nil, errors.New("corruption detected: stream overrun 4") + } + + // Read value and increment offset. + val := br.peekBitsFast(d.actualTableLog) + v := single[val&tlMask].entry + nBits := uint8(v) + br.advance(nBits) + bitsLeft -= uint(nBits) + out[offset] = uint8(v >> 8) + offset++ + } + if offset != endsAt { + return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) + } + decoded += offset - dstEvery*i + err = br.close() + if err != nil { + return nil, err + } + } + if dstSize != decoded { + return nil, errors.New("corruption detected: short output block") + } + return dst, nil +} + +type decompress1xContext struct { + pbr *bitReaderShifted + peekBits uint8 + out *byte + outCap int + tbl *dEntrySingle + decoded int +} + +// Error reported by asm implementations +const error_max_decoded_size_exeeded = -1 + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:maxDecodedSize] + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + + if maxDecodedSize >= 4 { + ctx := decompress1xContext{ + pbr: &br, + out: &dst[0], + outCap: maxDecodedSize, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + tbl: &d.dt.single[0], + } + + decompress1x_main_loop_asm(&ctx) + if ctx.decoded == error_max_decoded_size_exeeded { + return nil, ErrMaxDecodedSizeExceeded + } + + dst = dst[:ctx.decoded] + } + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if len(dst) >= maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + return dst, br.close() +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go index 61039232..e1bca5c6 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go @@ -1,4 +1,4 @@ -//go:build !amd64 || appengine || !gc || noasm +//go:build (!amd64 && !arm64) || appengine || !gc || noasm // This file contains a generic implementation of Decoder.Decompress4X. package huff0 diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 2329e996..51f9da03 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -400,8 +400,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err } } var err error - // Use our out buffer. - huff.MaxDecodedSize = litRegenSize + // Decoder.Decompress* uses cap(dst) for the size limit. Do not write + // MaxDecodedSize on hist.huffTree: with a trained dictionary that + // pointer aliases the shared dict.litEnc and concurrent DecodeAll races. if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) } else { @@ -673,10 +674,6 @@ func (b *blockDec) executeSequences(hist *history) error { hbytes := hist.b if len(hbytes) > hist.windowSize { hbytes = hbytes[len(hbytes)-hist.windowSize:] - // We do not need history anymore. - if hist.dict != nil { - hist.dict.content = nil - } } hist.decoders.windowSize = hist.windowSize hist.decoders.out = b.dst[:0] diff --git a/vendor/github.com/klauspost/compress/zstd/dict.go b/vendor/github.com/klauspost/compress/zstd/dict.go index 4f1c4938..67f40e79 100644 --- a/vendor/github.com/klauspost/compress/zstd/dict.go +++ b/vendor/github.com/klauspost/compress/zstd/dict.go @@ -296,40 +296,81 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if offset > 3 { newOffsets[offset-3]++ } else { - newOffsets[uint32(o.Offsets[offset-1])]++ + // Repeat codes reference the training Offsets. Skip unset + // (zero) entries so they are not ranked as real offsets. + prev := o.Offsets[offset-1] + if prev > 0 { + newOffsets[uint32(prev)]++ + } } } } // Find most used offsets. var sortedOffsets []uint32 for k := range newOffsets { + if k == 0 { + continue + } sortedOffsets = append(sortedOffsets, k) } sort.Slice(sortedOffsets, func(i, j int) bool { a, b := sortedOffsets[i], sortedOffsets[j] - if a == b { + ca, cb := newOffsets[a], newOffsets[b] + if ca == cb { // Prefer the longer offset - return sortedOffsets[i] > sortedOffsets[j] + return a > b } - return newOffsets[sortedOffsets[i]] > newOffsets[sortedOffsets[j]] + return ca > cb }) - if len(sortedOffsets) > 3 { - if debug { - print("Offsets:") - for i, v := range sortedOffsets { - if i > 20 { - break - } - printf("[%d: %d],", v, newOffsets[v]) + if debug { + print("Offsets:") + for i, v := range sortedOffsets { + if i > 20 { + break } - println("") + printf("[%d: %d],", v, newOffsets[v]) + } + println("") + } + // Dictionary recent-offsets must be three positive values within the + // history. Ranked matches may be fewer (or empty when only unset + // repeat codes were seen), so fill remaining slots with defaults. + used := make(map[int]bool, 3) + var finalOffsets [3]int + nOff := 0 + for _, v := range sortedOffsets { + iv := int(v) + if iv <= 0 || iv > len(hist) || used[iv] { + continue + } + finalOffsets[nOff] = iv + used[iv] = true + nOff++ + if nOff == 3 { + break } - - sortedOffsets = sortedOffsets[:3] } - for i, v := range sortedOffsets { - o.Offsets[i] = int(v) + for _, def := range []int{1, 4, 8} { + if nOff == 3 { + break + } + if def <= len(hist) && !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + for def := 1; nOff < 3 && def <= len(hist); def++ { + if !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + if nOff < 3 { + return nil, fmt.Errorf("could not determine 3 valid dictionary offsets (history size %d)", len(hist)) } + o.Offsets = finalOffsets if debug { println("New repeat offsets", o.Offsets) } @@ -337,6 +378,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if nUsed == 0 || seqs == 0 { return nil, fmt.Errorf("%d blocks, %d sequences found", nUsed, seqs) } + if litTotal == 0 { + return nil, errors.New("0 literals found") + } if debug { println("Sequences:", seqs, "Blocks:", nUsed, "Literals:", litTotal) } @@ -517,11 +561,10 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[1]))) out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[2]))) out.Write(hist) + if _, err := loadDict(out.Bytes()); err != nil { + return nil, fmt.Errorf("built dictionary failed validation: %w", err) + } if debug { - _, err := loadDict(out.Bytes()) - if err != nil { - panic(err) - } i, err := InspectDictionary(out.Bytes()) if err != nil { panic(err) diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s index 3fc381c7..4d3188ff 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -2081,7 +2081,7 @@ sequenceDecs_decodeSync_amd64_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (AX)(R13*1), R14 + LEAQ 16(AX)(R13*1), R14 ADDQ R10, R14 CMPQ R14, 32(SP) JA error_not_enough_space @@ -2601,7 +2601,7 @@ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (CX)(R13*1), R14 + LEAQ 16(CX)(R13*1), R14 ADDQ R9, R14 CMPQ R14, 32(SP) JA error_not_enough_space diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s index a468e5fc..6f54ef21 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s @@ -12,7 +12,7 @@ TEXT ·sequenceDecs_decode_arm64(SB), $8-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 @@ -24,7 +24,7 @@ TEXT ·sequenceDecs_decode_arm64(SB), $8-32 MOVD 160(R0), R12 sequenceDecs_decode_amd64_main_loop: - MOVD (RSP), R13 + MOVD 8(RSP), R13 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -60,7 +60,8 @@ sequenceDecs_decode_amd64_fill_end: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_amd64_of_update_zero @@ -81,7 +82,8 @@ sequenceDecs_decode_amd64_of_update_zero: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_amd64_ml_update_zero @@ -131,7 +133,8 @@ sequenceDecs_decode_amd64_fill_2_end: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_amd64_ll_update_zero @@ -148,7 +151,7 @@ sequenceDecs_decode_amd64_ll_update_zero: MOVD R0, (R9) // Fill bitreader for state updates - MOVD R13, (RSP) + MOVD R13, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -166,7 +169,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -187,7 +190,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -208,7 +211,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -360,7 +363,7 @@ TEXT ·sequenceDecs_decode_56_arm64(SB), $8-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 @@ -372,7 +375,7 @@ TEXT ·sequenceDecs_decode_56_arm64(SB), $8-32 MOVD 160(R0), R12 sequenceDecs_decode_56_amd64_main_loop: - MOVD (RSP), R13 + MOVD 8(RSP), R13 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -408,7 +411,8 @@ sequenceDecs_decode_56_amd64_fill_end: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_56_amd64_of_update_zero @@ -429,7 +433,8 @@ sequenceDecs_decode_56_amd64_of_update_zero: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_56_amd64_ml_update_zero @@ -450,7 +455,8 @@ sequenceDecs_decode_56_amd64_ml_update_zero: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_56_amd64_ll_update_zero @@ -467,7 +473,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: MOVD R0, (R9) // Fill bitreader for state updates - MOVD R13, (RSP) + MOVD R13, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -485,7 +491,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -506,7 +512,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -527,7 +533,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -766,13 +772,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R10 - MOVB 2(R13), R11 - MOVH R10, (R3) - MOVB R11, 2(R3) - ADD R12, R13, R13 - ADD R12, R3, R3 - JMP copy_4_end + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R10 @@ -834,24 +841,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R10, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R3) - ADD R10, R3, R15 - MOVB R4, -1(R15) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R3) - MOVB R4, 2(R3) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -906,12 +916,13 @@ copy_overlapping_match: ADD R12, R6, R6 copy_slow_3: - MOVB (R10), R11 - MOVB R11, (R3) - ADD $1, R10, R10 - ADD $1, R3, R3 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: ADD $0x18, R0, R0 @@ -1016,24 +1027,27 @@ copy_1_small: JMP copy_1_move_8through16 copy_1_move_1or2: - MOVB (R5), R13 - ADD R10, R5, R15 - MOVB -1(R15), R14 - MOVB R13, (R3) - ADD R10, R3, R15 - MOVB R14, -1(R15) - ADD R10, R5, R5 - ADD R10, R3, R3 - JMP copy_1_end + MOVBU (R5), R16 + BFI $0, R16, $8, R13 + ADD R10, R5, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R3) + ADD R10, R3, R15 + MOVB R14, -1(R15) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end copy_1_move_3: - MOVH (R5), R13 - MOVB 2(R5), R14 - MOVH R13, (R3) - MOVB R14, 2(R3) - ADD R10, R5, R5 - ADD R10, R3, R3 - JMP copy_1_end + MOVHU (R5), R13 + MOVBU 2(R5), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R3) + MOVB R14, 2(R3) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end copy_1_move_4through7: MOVWU (R5), R13 @@ -1104,13 +1118,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R10 - MOVB 2(R13), R11 - MOVH R10, (R3) - MOVB R11, 2(R3) - ADD R12, R13, R13 - ADD R12, R3, R3 - JMP copy_4_end + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R10 @@ -1172,24 +1187,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R10, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R3) - ADD R10, R3, R15 - MOVB R4, -1(R15) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R3) - MOVB R4, 2(R3) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -1257,24 +1275,27 @@ copy_2_small: JMP copy_2_move_8through16 copy_2_move_1or2: - MOVB (R10), R11 - ADD R12, R10, R15 - MOVB -1(R15), R13 - MOVB R11, (R3) - ADD R12, R3, R15 - MOVB R13, -1(R15) - ADD R12, R10, R10 - ADD R12, R3, R3 - JMP copy_2_end + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + ADD R12, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R11, (R3) + ADD R12, R3, R15 + MOVB R13, -1(R15) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end copy_2_move_3: - MOVH (R10), R11 - MOVB 2(R10), R13 - MOVH R11, (R3) - MOVB R13, 2(R3) - ADD R12, R10, R10 - ADD R12, R3, R3 - JMP copy_2_end + MOVHU (R10), R11 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R13 + MOVH R11, (R3) + MOVB R13, 2(R3) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end copy_2_move_4through7: MOVWU (R10), R11 @@ -1305,12 +1326,13 @@ copy_overlapping_match: ADD R12, R6, R6 copy_slow_3: - MOVB (R10), R11 - MOVB R11, (R3) - ADD $1, R10, R10 - ADD $1, R3, R3 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: ADD $0x18, R0, R0 @@ -1361,41 +1383,41 @@ TEXT ·sequenceDecs_decodeSync_arm64(SB), $64-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 MOVD 88(R0), R8 MOVD $0, R1 - MOVD R1, 8(RSP) MOVD R1, 16(RSP) MOVD R1, 24(RSP) + MOVD R1, 32(RSP) MOVD 112(R0), R9 MOVD 128(R0), R1 - MOVD R1, 32(RSP) + MOVD R1, 40(RSP) MOVD 144(R0), R10 MOVD 136(R0), R11 MOVD 200(R0), R1 - MOVD R1, 56(RSP) + MOVD R1, 64(RSP) MOVD 176(R0), R1 - MOVD R1, 48(RSP) + MOVD R1, 56(RSP) MOVD 184(R0), R0 - MOVD R0, 40(RSP) - MOVD 40(RSP), R0 - MOVD 48(RSP), R16 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 ADD R0, R16, R16 - MOVD R16, 48(RSP) + MOVD R16, 56(RSP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 ADD R9, R16, R16 - MOVD R16, 32(RSP) + MOVD R16, 40(RSP) // outBase += outPosition ADD R11, R9, R9 sequenceDecs_decodeSync_amd64_main_loop: - MOVD (RSP), R12 + MOVD 8(RSP), R12 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -1431,7 +1453,8 @@ sequenceDecs_decodeSync_amd64_fill_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_amd64_of_update_zero @@ -1445,14 +1468,15 @@ sequenceDecs_decodeSync_amd64_fill_end: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_of_update_zero: - MOVD R0, 8(RSP) + MOVD R0, 16(RSP) // Update match length MOVD R7, R0 MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_amd64_ml_update_zero @@ -1466,7 +1490,7 @@ sequenceDecs_decodeSync_amd64_of_update_zero: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_ml_update_zero: - MOVD R0, 16(RSP) + MOVD R0, 24(RSP) // Fill bitreader to have enough for the remaining CMP $0x08, R5 @@ -1502,7 +1526,8 @@ sequenceDecs_decodeSync_amd64_fill_2_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_amd64_ll_update_zero @@ -1516,10 +1541,10 @@ sequenceDecs_decodeSync_amd64_fill_2_end: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_ll_update_zero: - MOVD R0, 24(RSP) + MOVD R0, 32(RSP) // Fill bitreader for state updates - MOVD R12, (RSP) + MOVD R12, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -1537,7 +1562,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1558,7 +1583,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1579,7 +1604,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1594,7 +1619,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: sequenceDecs_decodeSync_amd64_skip_update: // Adjust offset MOVD s+0(FP), R1 - MOVD 8(RSP), R12 + MOVD 16(RSP), R12 CMP $0x01, R0 BLS sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 ADD $144, R1, R15 @@ -1605,7 +1630,7 @@ sequenceDecs_decodeSync_amd64_skip_update: JMP sequenceDecs_decodeSync_amd64_after_adjust sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0: - MOVD 24(RSP), R16 + MOVD 32(RSP), R16 CMP $0x00000000, R16 BNE sequenceDecs_decodeSync_amd64_adjust_offset_maybezero ADD $1, R12, R12 @@ -1643,11 +1668,11 @@ sequenceDecs_decodeSync_amd64_adjust_skip: MOVD R13, R12 sequenceDecs_decodeSync_amd64_after_adjust: - MOVD R12, 8(RSP) + MOVD R12, 16(RSP) // Check values - MOVD 16(RSP), R0 - MOVD 24(RSP), R1 + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 ADD R1, R0, R13 MOVD s+0(FP), R14 MOVD 256(R14), R16 @@ -1666,14 +1691,15 @@ sequenceDecs_decodeSync_amd64_after_adjust: BNE sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_amd64_match_len_ofs_ok: - MOVD 24(RSP), R0 - MOVD 8(RSP), R1 - MOVD 16(RSP), R12 + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 // Check if we have enough space in s.out ADD R12, R0, R13 + ADD $16, R13, R13 ADD R9, R13, R13 - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 CMP R16, R13 BHI error_not_enough_space @@ -1697,11 +1723,11 @@ copy_1: // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVD R11, R0 - MOVD 40(RSP), R16 + MOVD 48(RSP), R16 ADD R16, R0, R0 CMP R0, R1 BGT error_match_off_too_big - MOVD 56(RSP), R16 + MOVD 64(RSP), R16 CMP R16, R1 BGT error_match_off_too_big @@ -1709,7 +1735,7 @@ check_offset: MOVD R1, R0 SUBS R11, R0, R0 BLS copy_match - MOVD 48(RSP), R13 + MOVD 56(RSP), R13 SUB R0, R13, R13 CMP R0, R12 BGT copy_all_from_history @@ -1742,13 +1768,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R0 - MOVB 2(R13), R1 - MOVH R0, (R9) - MOVB R1, 2(R9) - ADD R12, R13, R13 - ADD R12, R9, R9 - JMP copy_4_end + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R0 @@ -1807,24 +1834,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R0, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R9) - ADD R0, R9, R15 - MOVB R4, -1(R15) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R9) - MOVB R4, 2(R9) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -1879,12 +1909,13 @@ copy_overlapping_match: ADD R12, R11, R11 copy_slow_3: - MOVB (R0), R1 - MOVB R1, (R9) - ADD $1, R0, R0 - ADD $1, R9, R9 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: MOVD ctx+16(FP), R0 @@ -1913,7 +1944,7 @@ loop_finished: // Return with match length error sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: - MOVD 16(RSP), R0 + MOVD 24(RSP), R0 MOVD ctx+16(FP), R1 MOVD R0, 216(R1) MOVD $0x00000001, R16 @@ -1923,7 +1954,7 @@ sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: // Return with match too long error sequenceDecs_decodeSync_amd64_error_match_len_too_big: MOVD ctx+16(FP), R0 - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD $0x00000002, R16 MOVD R16, ret+24(FP) @@ -1932,7 +1963,7 @@ sequenceDecs_decodeSync_amd64_error_match_len_too_big: // Return with match offset too long error error_match_off_too_big: MOVD ctx+16(FP), R0 - MOVD 8(RSP), R1 + MOVD 16(RSP), R1 MOVD R1, 224(R0) MOVD R11, 136(R0) MOVD $0x00000003, R16 @@ -1942,7 +1973,7 @@ error_match_off_too_big: // Return with not enough literals error error_not_enough_literals: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) MOVD $0x00000004, R16 MOVD R16, ret+24(FP) @@ -1957,9 +1988,9 @@ error_overread: // Return with not enough output space error error_not_enough_space: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD R11, 136(R0) MOVD $0x00000005, R16 @@ -1977,41 +2008,41 @@ TEXT ·sequenceDecs_decodeSync_safe_arm64(SB), $64-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 MOVD 88(R0), R8 MOVD $0, R1 - MOVD R1, 8(RSP) MOVD R1, 16(RSP) MOVD R1, 24(RSP) + MOVD R1, 32(RSP) MOVD 112(R0), R9 MOVD 128(R0), R1 - MOVD R1, 32(RSP) + MOVD R1, 40(RSP) MOVD 144(R0), R10 MOVD 136(R0), R11 MOVD 200(R0), R1 - MOVD R1, 56(RSP) + MOVD R1, 64(RSP) MOVD 176(R0), R1 - MOVD R1, 48(RSP) + MOVD R1, 56(RSP) MOVD 184(R0), R0 - MOVD R0, 40(RSP) - MOVD 40(RSP), R0 - MOVD 48(RSP), R16 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 ADD R0, R16, R16 - MOVD R16, 48(RSP) + MOVD R16, 56(RSP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 ADD R9, R16, R16 - MOVD R16, 32(RSP) + MOVD R16, 40(RSP) // outBase += outPosition ADD R11, R9, R9 sequenceDecs_decodeSync_safe_amd64_main_loop: - MOVD (RSP), R12 + MOVD 8(RSP), R12 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -2047,7 +2078,8 @@ sequenceDecs_decodeSync_safe_amd64_fill_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_safe_amd64_of_update_zero @@ -2061,14 +2093,15 @@ sequenceDecs_decodeSync_safe_amd64_fill_end: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_of_update_zero: - MOVD R0, 8(RSP) + MOVD R0, 16(RSP) // Update match length MOVD R7, R0 MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_safe_amd64_ml_update_zero @@ -2082,7 +2115,7 @@ sequenceDecs_decodeSync_safe_amd64_of_update_zero: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_ml_update_zero: - MOVD R0, 16(RSP) + MOVD R0, 24(RSP) // Fill bitreader to have enough for the remaining CMP $0x08, R5 @@ -2118,7 +2151,8 @@ sequenceDecs_decodeSync_safe_amd64_fill_2_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_safe_amd64_ll_update_zero @@ -2132,10 +2166,10 @@ sequenceDecs_decodeSync_safe_amd64_fill_2_end: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_ll_update_zero: - MOVD R0, 24(RSP) + MOVD R0, 32(RSP) // Fill bitreader for state updates - MOVD R12, (RSP) + MOVD R12, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -2153,7 +2187,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2174,7 +2208,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2195,7 +2229,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2210,7 +2244,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: sequenceDecs_decodeSync_safe_amd64_skip_update: // Adjust offset MOVD s+0(FP), R1 - MOVD 8(RSP), R12 + MOVD 16(RSP), R12 CMP $0x01, R0 BLS sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 ADD $144, R1, R15 @@ -2221,7 +2255,7 @@ sequenceDecs_decodeSync_safe_amd64_skip_update: JMP sequenceDecs_decodeSync_safe_amd64_after_adjust sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0: - MOVD 24(RSP), R16 + MOVD 32(RSP), R16 CMP $0x00000000, R16 BNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero ADD $1, R12, R12 @@ -2259,11 +2293,11 @@ sequenceDecs_decodeSync_safe_amd64_adjust_skip: MOVD R13, R12 sequenceDecs_decodeSync_safe_amd64_after_adjust: - MOVD R12, 8(RSP) + MOVD R12, 16(RSP) // Check values - MOVD 16(RSP), R0 - MOVD 24(RSP), R1 + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 ADD R1, R0, R13 MOVD s+0(FP), R14 MOVD 256(R14), R16 @@ -2282,14 +2316,14 @@ sequenceDecs_decodeSync_safe_amd64_after_adjust: BNE sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: - MOVD 24(RSP), R0 - MOVD 8(RSP), R1 - MOVD 16(RSP), R12 + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 // Check if we have enough space in s.out ADD R12, R0, R13 ADD R9, R13, R13 - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 CMP R16, R13 BHI error_not_enough_space @@ -2326,24 +2360,27 @@ copy_1_small: JMP copy_1_move_8through16 copy_1_move_1or2: - MOVB (R10), R13 - ADD R0, R10, R15 - MOVB -1(R15), R14 - MOVB R13, (R9) - ADD R0, R9, R15 - MOVB R14, -1(R15) - ADD R0, R10, R10 - ADD R0, R9, R9 - JMP copy_1_end + MOVBU (R10), R16 + BFI $0, R16, $8, R13 + ADD R0, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R9) + ADD R0, R9, R15 + MOVB R14, -1(R15) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end copy_1_move_3: - MOVH (R10), R13 - MOVB 2(R10), R14 - MOVH R13, (R9) - MOVB R14, 2(R9) - ADD R0, R10, R10 - ADD R0, R9, R9 - JMP copy_1_end + MOVHU (R10), R13 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R9) + MOVB R14, 2(R9) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end copy_1_move_4through7: MOVWU (R10), R13 @@ -2372,11 +2409,11 @@ copy_1_end: // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVD R11, R0 - MOVD 40(RSP), R16 + MOVD 48(RSP), R16 ADD R16, R0, R0 CMP R0, R1 BGT error_match_off_too_big - MOVD 56(RSP), R16 + MOVD 64(RSP), R16 CMP R16, R1 BGT error_match_off_too_big @@ -2384,7 +2421,7 @@ check_offset: MOVD R1, R0 SUBS R11, R0, R0 BLS copy_match - MOVD 48(RSP), R13 + MOVD 56(RSP), R13 SUB R0, R13, R13 CMP R0, R12 BGT copy_all_from_history @@ -2417,13 +2454,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R0 - MOVB 2(R13), R1 - MOVH R0, (R9) - MOVB R1, 2(R9) - ADD R12, R13, R13 - ADD R12, R9, R9 - JMP copy_4_end + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R0 @@ -2482,24 +2520,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R0, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R9) - ADD R0, R9, R15 - MOVB R4, -1(R15) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R9) - MOVB R4, 2(R9) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -2567,24 +2608,27 @@ copy_2_small: JMP copy_2_move_8through16 copy_2_move_1or2: - MOVB (R0), R1 - ADD R12, R0, R15 - MOVB -1(R15), R13 - MOVB R1, (R9) - ADD R12, R9, R15 - MOVB R13, -1(R15) - ADD R12, R0, R0 - ADD R12, R9, R9 - JMP copy_2_end + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + ADD R12, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R1, (R9) + ADD R12, R9, R15 + MOVB R13, -1(R15) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end copy_2_move_3: - MOVH (R0), R1 - MOVB 2(R0), R13 - MOVH R1, (R9) - MOVB R13, 2(R9) - ADD R12, R0, R0 - ADD R12, R9, R9 - JMP copy_2_end + MOVHU (R0), R1 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R13 + MOVH R1, (R9) + MOVB R13, 2(R9) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end copy_2_move_4through7: MOVWU (R0), R1 @@ -2615,12 +2659,13 @@ copy_overlapping_match: ADD R12, R11, R11 copy_slow_3: - MOVB (R0), R1 - MOVB R1, (R9) - ADD $1, R0, R0 - ADD $1, R9, R9 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: MOVD ctx+16(FP), R0 @@ -2649,7 +2694,7 @@ loop_finished: // Return with match length error sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: - MOVD 16(RSP), R0 + MOVD 24(RSP), R0 MOVD ctx+16(FP), R1 MOVD R0, 216(R1) MOVD $0x00000001, R16 @@ -2659,7 +2704,7 @@ sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: // Return with match too long error sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: MOVD ctx+16(FP), R0 - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD $0x00000002, R16 MOVD R16, ret+24(FP) @@ -2668,7 +2713,7 @@ sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: // Return with match offset too long error error_match_off_too_big: MOVD ctx+16(FP), R0 - MOVD 8(RSP), R1 + MOVD 16(RSP), R1 MOVD R1, 224(R0) MOVD R11, 136(R0) MOVD $0x00000003, R16 @@ -2678,7 +2723,7 @@ error_match_off_too_big: // Return with not enough literals error error_not_enough_literals: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) MOVD $0x00000004, R16 MOVD R16, ret+24(FP) @@ -2693,9 +2738,9 @@ error_overread: // Return with not enough output space error error_not_enough_space: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD R11, 136(R0) MOVD $0x00000005, R16 diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go b/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go index 55405f39..42ce5de7 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go @@ -77,6 +77,35 @@ const errorNotEnoughSpace = 5 // error reported when bits are overread. const errorOverread = 6 +// useSafeDecodeSync reports whether decodeSyncSimple must use the bounds-exact +// ("safe") copy variants for the current buffer geometry. +// +// When the output and literal buffers have compressedBlockOverAlloc (16) +// bytes of slack past their logical use, the assembly may use extended +// memory copies that read and write in 16-byte blocks, overrunning the end +// of a literal run or match by up to 15 bytes. Otherwise it must use the +// bounds-exact ("safe") copies. This mirrors the analogous, always-dynamic +// selection in executeSimple below. +// +// The unsafe copies were disabled in #644 (2022) as a mitigation for a +// crash, but that crash's root cause — an unguarded bitReader overread that +// produced out-of-range match offsets/lengths — was fixed three days later +// in #645, which also added the fuzz corpus that has guarded this path since. +// See #1168. An asan-instrumented fuzz job (see .github/workflows/go.yml) +// covers the extended-copy path, which -race and plain fuzzing cannot. +func (s *sequenceDecs) useSafeDecodeSync() bool { + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc { + return true + } + if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) { + return true + } + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + return true + } + return false +} + // decode sequences from the stream with the provided history but without a dictionary. func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { if len(s.dict) > 0 { @@ -86,9 +115,7 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { return false, nil } - // FIXME: Using unsafe memory copies leads to rare, random crashes - // with fuzz testing. It is therefore disabled for now. - const useSafe = true + useSafe := s.useSafeDecodeSync() br := s.br diff --git a/vendor/github.com/mailru/easyjson/LICENSE b/vendor/github.com/mailru/easyjson/LICENSE deleted file mode 100644 index fbff658f..00000000 --- a/vendor/github.com/mailru/easyjson/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2016 Mail.Ru Group - -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/mailru/easyjson/buffer/pool.go b/vendor/github.com/mailru/easyjson/buffer/pool.go deleted file mode 100644 index 598a54af..00000000 --- a/vendor/github.com/mailru/easyjson/buffer/pool.go +++ /dev/null @@ -1,278 +0,0 @@ -// Package buffer implements a buffer for serialization, consisting of a chain of []byte-s to -// reduce copying and to allow reuse of individual chunks. -package buffer - -import ( - "io" - "net" - "sync" -) - -// PoolConfig contains configuration for the allocation and reuse strategy. -type PoolConfig struct { - StartSize int // Minimum chunk size that is allocated. - PooledSize int // Minimum chunk size that is reused, reusing chunks too small will result in overhead. - MaxSize int // Maximum chunk size that will be allocated. -} - -var config = PoolConfig{ - StartSize: 128, - PooledSize: 512, - MaxSize: 32768, -} - -// Reuse pool: chunk size -> pool. -var buffers = map[int]*sync.Pool{} - -func initBuffers() { - for l := config.PooledSize; l <= config.MaxSize; l *= 2 { - buffers[l] = new(sync.Pool) - } -} - -func init() { - initBuffers() -} - -// Init sets up a non-default pooling and allocation strategy. Should be run before serialization is done. -func Init(cfg PoolConfig) { - config = cfg - initBuffers() -} - -// putBuf puts a chunk to reuse pool if it can be reused. -func putBuf(buf []byte) { - size := cap(buf) - if size < config.PooledSize { - return - } - if c := buffers[size]; c != nil { - c.Put(buf[:0]) - } -} - -// getBuf gets a chunk from reuse pool or creates a new one if reuse failed. -func getBuf(size int) []byte { - if size >= config.PooledSize { - if c := buffers[size]; c != nil { - v := c.Get() - if v != nil { - return v.([]byte) - } - } - } - return make([]byte, 0, size) -} - -// Buffer is a buffer optimized for serialization without extra copying. -type Buffer struct { - - // Buf is the current chunk that can be used for serialization. - Buf []byte - - toPool []byte - bufs [][]byte -} - -// EnsureSpace makes sure that the current chunk contains at least s free bytes, -// possibly creating a new chunk. -func (b *Buffer) EnsureSpace(s int) { - if cap(b.Buf)-len(b.Buf) < s { - b.ensureSpaceSlow(s) - } -} - -func (b *Buffer) ensureSpaceSlow(s int) { - l := len(b.Buf) - if l > 0 { - if cap(b.toPool) != cap(b.Buf) { - // Chunk was reallocated, toPool can be pooled. - putBuf(b.toPool) - } - if cap(b.bufs) == 0 { - b.bufs = make([][]byte, 0, 8) - } - b.bufs = append(b.bufs, b.Buf) - l = cap(b.toPool) * 2 - } else { - l = config.StartSize - } - - if l > config.MaxSize { - l = config.MaxSize - } - b.Buf = getBuf(l) - b.toPool = b.Buf -} - -// AppendByte appends a single byte to buffer. -func (b *Buffer) AppendByte(data byte) { - b.EnsureSpace(1) - b.Buf = append(b.Buf, data) -} - -// AppendBytes appends a byte slice to buffer. -func (b *Buffer) AppendBytes(data []byte) { - if len(data) <= cap(b.Buf)-len(b.Buf) { - b.Buf = append(b.Buf, data...) // fast path - } else { - b.appendBytesSlow(data) - } -} - -func (b *Buffer) appendBytesSlow(data []byte) { - for len(data) > 0 { - b.EnsureSpace(1) - - sz := cap(b.Buf) - len(b.Buf) - if sz > len(data) { - sz = len(data) - } - - b.Buf = append(b.Buf, data[:sz]...) - data = data[sz:] - } -} - -// AppendString appends a string to buffer. -func (b *Buffer) AppendString(data string) { - if len(data) <= cap(b.Buf)-len(b.Buf) { - b.Buf = append(b.Buf, data...) // fast path - } else { - b.appendStringSlow(data) - } -} - -func (b *Buffer) appendStringSlow(data string) { - for len(data) > 0 { - b.EnsureSpace(1) - - sz := cap(b.Buf) - len(b.Buf) - if sz > len(data) { - sz = len(data) - } - - b.Buf = append(b.Buf, data[:sz]...) - data = data[sz:] - } -} - -// Size computes the size of a buffer by adding sizes of every chunk. -func (b *Buffer) Size() int { - size := len(b.Buf) - for _, buf := range b.bufs { - size += len(buf) - } - return size -} - -// DumpTo outputs the contents of a buffer to a writer and resets the buffer. -func (b *Buffer) DumpTo(w io.Writer) (written int, err error) { - bufs := net.Buffers(b.bufs) - if len(b.Buf) > 0 { - bufs = append(bufs, b.Buf) - } - n, err := bufs.WriteTo(w) - - for _, buf := range b.bufs { - putBuf(buf) - } - putBuf(b.toPool) - - b.bufs = nil - b.Buf = nil - b.toPool = nil - - return int(n), err -} - -// BuildBytes creates a single byte slice with all the contents of the buffer. Data is -// copied if it does not fit in a single chunk. You can optionally provide one byte -// slice as argument that it will try to reuse. -func (b *Buffer) BuildBytes(reuse ...[]byte) []byte { - if len(b.bufs) == 0 { - ret := b.Buf - b.toPool = nil - b.Buf = nil - return ret - } - - var ret []byte - size := b.Size() - - // If we got a buffer as argument and it is big enough, reuse it. - if len(reuse) == 1 && cap(reuse[0]) >= size { - ret = reuse[0][:0] - } else { - ret = make([]byte, 0, size) - } - for _, buf := range b.bufs { - ret = append(ret, buf...) - putBuf(buf) - } - - ret = append(ret, b.Buf...) - putBuf(b.toPool) - - b.bufs = nil - b.toPool = nil - b.Buf = nil - - return ret -} - -type readCloser struct { - offset int - bufs [][]byte -} - -func (r *readCloser) Read(p []byte) (n int, err error) { - for _, buf := range r.bufs { - // Copy as much as we can. - x := copy(p[n:], buf[r.offset:]) - n += x // Increment how much we filled. - - // Did we empty the whole buffer? - if r.offset+x == len(buf) { - // On to the next buffer. - r.offset = 0 - r.bufs = r.bufs[1:] - - // We can release this buffer. - putBuf(buf) - } else { - r.offset += x - } - - if n == len(p) { - break - } - } - // No buffers left or nothing read? - if len(r.bufs) == 0 { - err = io.EOF - } - return -} - -func (r *readCloser) Close() error { - // Release all remaining buffers. - for _, buf := range r.bufs { - putBuf(buf) - } - // In case Close gets called multiple times. - r.bufs = nil - - return nil -} - -// ReadCloser creates an io.ReadCloser with all the contents of the buffer. -func (b *Buffer) ReadCloser() io.ReadCloser { - ret := &readCloser{0, append(b.bufs, b.Buf)} - - b.bufs = nil - b.toPool = nil - b.Buf = nil - - return ret -} diff --git a/vendor/github.com/mailru/easyjson/jlexer/bytestostr.go b/vendor/github.com/mailru/easyjson/jlexer/bytestostr.go deleted file mode 100644 index e68108f8..00000000 --- a/vendor/github.com/mailru/easyjson/jlexer/bytestostr.go +++ /dev/null @@ -1,21 +0,0 @@ -// This file will only be included to the build if neither -// easyjson_nounsafe nor appengine build tag is set. See README notes -// for more details. - -//+build !easyjson_nounsafe -//+build !appengine - -package jlexer - -import ( - "unsafe" -) - -// bytesToStr creates a string pointing at the slice to avoid copying. -// -// Warning: the string returned by the function should be used with care, as the whole input data -// chunk may be either blocked from being freed by GC because of a single string or the buffer.Data -// may be garbage-collected even when the string exists. -func bytesToStr(data []byte) string { - return *(*string)(unsafe.Pointer(&data)) -} diff --git a/vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go b/vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go deleted file mode 100644 index 864d1be6..00000000 --- a/vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go +++ /dev/null @@ -1,13 +0,0 @@ -// This file is included to the build if any of the buildtags below -// are defined. Refer to README notes for more details. - -//+build easyjson_nounsafe appengine - -package jlexer - -// bytesToStr creates a string normally from []byte -// -// Note that this method is roughly 1.5x slower than using the 'unsafe' method. -func bytesToStr(data []byte) string { - return string(data) -} diff --git a/vendor/github.com/mailru/easyjson/jlexer/error.go b/vendor/github.com/mailru/easyjson/jlexer/error.go deleted file mode 100644 index e90ec40d..00000000 --- a/vendor/github.com/mailru/easyjson/jlexer/error.go +++ /dev/null @@ -1,15 +0,0 @@ -package jlexer - -import "fmt" - -// LexerError implements the error interface and represents all possible errors that can be -// generated during parsing the JSON data. -type LexerError struct { - Reason string - Offset int - Data string -} - -func (l *LexerError) Error() string { - return fmt.Sprintf("parse error: %s near offset %d of '%s'", l.Reason, l.Offset, l.Data) -} diff --git a/vendor/github.com/mailru/easyjson/jlexer/lexer.go b/vendor/github.com/mailru/easyjson/jlexer/lexer.go deleted file mode 100644 index a27705b1..00000000 --- a/vendor/github.com/mailru/easyjson/jlexer/lexer.go +++ /dev/null @@ -1,1257 +0,0 @@ -// Package jlexer contains a JSON lexer implementation. -// -// It is expected that it is mostly used with generated parser code, so the interface is tuned -// for a parser that knows what kind of data is expected. -package jlexer - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "strconv" - "unicode" - "unicode/utf16" - "unicode/utf8" - - "github.com/josharian/intern" -) - -// TokenKind determines type of a token. -type TokenKind byte - -const ( - TokenUndef TokenKind = iota // No token. - TokenDelim // Delimiter: one of '{', '}', '[' or ']'. - TokenString // A string literal, e.g. "abc\u1234" - TokenNumber // Number literal, e.g. 1.5e5 - TokenBool // Boolean literal: true or false. - TokenNull // null keyword. -) - -// token describes a single token: type, position in the input and value. -type token struct { - kind TokenKind // Type of a token. - - boolValue bool // Value if a boolean literal token. - byteValueCloned bool // true if byteValue was allocated and does not refer to original json body - byteValue []byte // Raw value of a token. - delimValue byte -} - -// Lexer is a JSON lexer: it iterates over JSON tokens in a byte slice. -type Lexer struct { - Data []byte // Input data given to the lexer. - - start int // Start of the current token. - pos int // Current unscanned position in the input stream. - token token // Last scanned token, if token.kind != TokenUndef. - - firstElement bool // Whether current element is the first in array or an object. - wantSep byte // A comma or a colon character, which need to occur before a token. - - UseMultipleErrors bool // If we want to use multiple errors. - fatalError error // Fatal error occurred during lexing. It is usually a syntax error. - multipleErrors []*LexerError // Semantic errors occurred during lexing. Marshalling will be continued after finding this errors. -} - -// FetchToken scans the input for the next token. -func (r *Lexer) FetchToken() { - r.token.kind = TokenUndef - r.start = r.pos - - // Check if r.Data has r.pos element - // If it doesn't, it mean corrupted input data - if len(r.Data) < r.pos { - r.errParse("Unexpected end of data") - return - } - // Determine the type of a token by skipping whitespace and reading the - // first character. - for _, c := range r.Data[r.pos:] { - switch c { - case ':', ',': - if r.wantSep == c { - r.pos++ - r.start++ - r.wantSep = 0 - } else { - r.errSyntax() - } - - case ' ', '\t', '\r', '\n': - r.pos++ - r.start++ - - case '"': - if r.wantSep != 0 { - r.errSyntax() - } - - r.token.kind = TokenString - r.fetchString() - return - - case '{', '[': - if r.wantSep != 0 { - r.errSyntax() - } - r.firstElement = true - r.token.kind = TokenDelim - r.token.delimValue = r.Data[r.pos] - r.pos++ - return - - case '}', ']': - if !r.firstElement && (r.wantSep != ',') { - r.errSyntax() - } - r.wantSep = 0 - r.token.kind = TokenDelim - r.token.delimValue = r.Data[r.pos] - r.pos++ - return - - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': - if r.wantSep != 0 { - r.errSyntax() - } - r.token.kind = TokenNumber - r.fetchNumber() - return - - case 'n': - if r.wantSep != 0 { - r.errSyntax() - } - - r.token.kind = TokenNull - r.fetchNull() - return - - case 't': - if r.wantSep != 0 { - r.errSyntax() - } - - r.token.kind = TokenBool - r.token.boolValue = true - r.fetchTrue() - return - - case 'f': - if r.wantSep != 0 { - r.errSyntax() - } - - r.token.kind = TokenBool - r.token.boolValue = false - r.fetchFalse() - return - - default: - r.errSyntax() - return - } - } - r.fatalError = io.EOF - return -} - -// isTokenEnd returns true if the char can follow a non-delimiter token -func isTokenEnd(c byte) bool { - return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '[' || c == ']' || c == '{' || c == '}' || c == ',' || c == ':' -} - -// fetchNull fetches and checks remaining bytes of null keyword. -func (r *Lexer) fetchNull() { - r.pos += 4 - if r.pos > len(r.Data) || - r.Data[r.pos-3] != 'u' || - r.Data[r.pos-2] != 'l' || - r.Data[r.pos-1] != 'l' || - (r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) { - - r.pos -= 4 - r.errSyntax() - } -} - -// fetchTrue fetches and checks remaining bytes of true keyword. -func (r *Lexer) fetchTrue() { - r.pos += 4 - if r.pos > len(r.Data) || - r.Data[r.pos-3] != 'r' || - r.Data[r.pos-2] != 'u' || - r.Data[r.pos-1] != 'e' || - (r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) { - - r.pos -= 4 - r.errSyntax() - } -} - -// fetchFalse fetches and checks remaining bytes of false keyword. -func (r *Lexer) fetchFalse() { - r.pos += 5 - if r.pos > len(r.Data) || - r.Data[r.pos-4] != 'a' || - r.Data[r.pos-3] != 'l' || - r.Data[r.pos-2] != 's' || - r.Data[r.pos-1] != 'e' || - (r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) { - - r.pos -= 5 - r.errSyntax() - } -} - -// fetchNumber scans a number literal token. -func (r *Lexer) fetchNumber() { - hasE := false - afterE := false - hasDot := false - - r.pos++ - for i, c := range r.Data[r.pos:] { - switch { - case c >= '0' && c <= '9': - afterE = false - case c == '.' && !hasDot: - hasDot = true - case (c == 'e' || c == 'E') && !hasE: - hasE = true - hasDot = true - afterE = true - case (c == '+' || c == '-') && afterE: - afterE = false - default: - r.pos += i - if !isTokenEnd(c) { - r.errSyntax() - } else { - r.token.byteValue = r.Data[r.start:r.pos] - } - return - } - } - - r.pos = len(r.Data) - r.token.byteValue = r.Data[r.start:] -} - -// findStringLen tries to scan into the string literal for ending quote char to determine required size. -// The size will be exact if no escapes are present and may be inexact if there are escaped chars. -func findStringLen(data []byte) (isValid bool, length int) { - for { - idx := bytes.IndexByte(data, '"') - if idx == -1 { - return false, len(data) - } - if idx == 0 || (idx > 0 && data[idx-1] != '\\') { - return true, length + idx - } - - // count \\\\\\\ sequences. even number of slashes means quote is not really escaped - cnt := 1 - for idx-cnt-1 >= 0 && data[idx-cnt-1] == '\\' { - cnt++ - } - if cnt%2 == 0 { - return true, length + idx - } - - length += idx + 1 - data = data[idx+1:] - } -} - -// unescapeStringToken performs unescaping of string token. -// if no escaping is needed, original string is returned, otherwise - a new one allocated -func (r *Lexer) unescapeStringToken() (err error) { - data := r.token.byteValue - var unescapedData []byte - - for { - i := bytes.IndexByte(data, '\\') - if i == -1 { - break - } - - escapedRune, escapedBytes, err := decodeEscape(data[i:]) - if err != nil { - r.errParse(err.Error()) - return err - } - - if unescapedData == nil { - unescapedData = make([]byte, 0, len(r.token.byteValue)) - } - - var d [4]byte - s := utf8.EncodeRune(d[:], escapedRune) - unescapedData = append(unescapedData, data[:i]...) - unescapedData = append(unescapedData, d[:s]...) - - data = data[i+escapedBytes:] - } - - if unescapedData != nil { - r.token.byteValue = append(unescapedData, data...) - r.token.byteValueCloned = true - } - return -} - -// getu4 decodes \uXXXX from the beginning of s, returning the hex value, -// or it returns -1. -func getu4(s []byte) rune { - if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { - return -1 - } - var val rune - for i := 2; i < len(s) && i < 6; i++ { - var v byte - c := s[i] - switch c { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - v = c - '0' - case 'a', 'b', 'c', 'd', 'e', 'f': - v = c - 'a' + 10 - case 'A', 'B', 'C', 'D', 'E', 'F': - v = c - 'A' + 10 - default: - return -1 - } - - val <<= 4 - val |= rune(v) - } - return val -} - -// decodeEscape processes a single escape sequence and returns number of bytes processed. -func decodeEscape(data []byte) (decoded rune, bytesProcessed int, err error) { - if len(data) < 2 { - return 0, 0, errors.New("incorrect escape symbol \\ at the end of token") - } - - c := data[1] - switch c { - case '"', '/', '\\': - return rune(c), 2, nil - case 'b': - return '\b', 2, nil - case 'f': - return '\f', 2, nil - case 'n': - return '\n', 2, nil - case 'r': - return '\r', 2, nil - case 't': - return '\t', 2, nil - case 'u': - rr := getu4(data) - if rr < 0 { - return 0, 0, errors.New("incorrectly escaped \\uXXXX sequence") - } - - read := 6 - if utf16.IsSurrogate(rr) { - rr1 := getu4(data[read:]) - if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { - read += 6 - rr = dec - } else { - rr = unicode.ReplacementChar - } - } - return rr, read, nil - } - - return 0, 0, errors.New("incorrectly escaped bytes") -} - -// fetchString scans a string literal token. -func (r *Lexer) fetchString() { - r.pos++ - data := r.Data[r.pos:] - - isValid, length := findStringLen(data) - if !isValid { - r.pos += length - r.errParse("unterminated string literal") - return - } - r.token.byteValue = data[:length] - r.pos += length + 1 // skip closing '"' as well -} - -// scanToken scans the next token if no token is currently available in the lexer. -func (r *Lexer) scanToken() { - if r.token.kind != TokenUndef || r.fatalError != nil { - return - } - - r.FetchToken() -} - -// consume resets the current token to allow scanning the next one. -func (r *Lexer) consume() { - r.token.kind = TokenUndef - r.token.byteValueCloned = false - r.token.delimValue = 0 -} - -// Ok returns true if no error (including io.EOF) was encountered during scanning. -func (r *Lexer) Ok() bool { - return r.fatalError == nil -} - -const maxErrorContextLen = 13 - -func (r *Lexer) errParse(what string) { - if r.fatalError == nil { - var str string - if len(r.Data)-r.pos <= maxErrorContextLen { - str = string(r.Data) - } else { - str = string(r.Data[r.pos:r.pos+maxErrorContextLen-3]) + "..." - } - r.fatalError = &LexerError{ - Reason: what, - Offset: r.pos, - Data: str, - } - } -} - -func (r *Lexer) errSyntax() { - r.errParse("syntax error") -} - -func (r *Lexer) errInvalidToken(expected string) { - if r.fatalError != nil { - return - } - if r.UseMultipleErrors { - r.pos = r.start - r.consume() - r.SkipRecursive() - switch expected { - case "[": - r.token.delimValue = ']' - r.token.kind = TokenDelim - case "{": - r.token.delimValue = '}' - r.token.kind = TokenDelim - } - r.addNonfatalError(&LexerError{ - Reason: fmt.Sprintf("expected %s", expected), - Offset: r.start, - Data: string(r.Data[r.start:r.pos]), - }) - return - } - - var str string - if len(r.token.byteValue) <= maxErrorContextLen { - str = string(r.token.byteValue) - } else { - str = string(r.token.byteValue[:maxErrorContextLen-3]) + "..." - } - r.fatalError = &LexerError{ - Reason: fmt.Sprintf("expected %s", expected), - Offset: r.pos, - Data: str, - } -} - -func (r *Lexer) GetPos() int { - return r.pos -} - -// Delim consumes a token and verifies that it is the given delimiter. -func (r *Lexer) Delim(c byte) { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - - if !r.Ok() || r.token.delimValue != c { - r.consume() // errInvalidToken can change token if UseMultipleErrors is enabled. - r.errInvalidToken(string([]byte{c})) - } else { - r.consume() - } -} - -// IsDelim returns true if there was no scanning error and next token is the given delimiter. -func (r *Lexer) IsDelim(c byte) bool { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - return !r.Ok() || r.token.delimValue == c -} - -// Null verifies that the next token is null and consumes it. -func (r *Lexer) Null() { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() || r.token.kind != TokenNull { - r.errInvalidToken("null") - } - r.consume() -} - -// IsNull returns true if the next token is a null keyword. -func (r *Lexer) IsNull() bool { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - return r.Ok() && r.token.kind == TokenNull -} - -// Skip skips a single token. -func (r *Lexer) Skip() { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - r.consume() -} - -// SkipRecursive skips next array or object completely, or just skips a single token if not -// an array/object. -// -// Note: no syntax validation is performed on the skipped data. -func (r *Lexer) SkipRecursive() { - r.scanToken() - var start, end byte - startPos := r.start - - switch r.token.delimValue { - case '{': - start, end = '{', '}' - case '[': - start, end = '[', ']' - default: - r.consume() - return - } - - r.consume() - - level := 1 - inQuotes := false - wasEscape := false - - for i, c := range r.Data[r.pos:] { - switch { - case c == start && !inQuotes: - level++ - case c == end && !inQuotes: - level-- - if level == 0 { - r.pos += i + 1 - if !json.Valid(r.Data[startPos:r.pos]) { - r.pos = len(r.Data) - r.fatalError = &LexerError{ - Reason: "skipped array/object json value is invalid", - Offset: r.pos, - Data: string(r.Data[r.pos:]), - } - } - return - } - case c == '\\' && inQuotes: - wasEscape = !wasEscape - continue - case c == '"' && inQuotes: - inQuotes = wasEscape - case c == '"': - inQuotes = true - } - wasEscape = false - } - r.pos = len(r.Data) - r.fatalError = &LexerError{ - Reason: "EOF reached while skipping array/object or token", - Offset: r.pos, - Data: string(r.Data[r.pos:]), - } -} - -// Raw fetches the next item recursively as a data slice -func (r *Lexer) Raw() []byte { - r.SkipRecursive() - if !r.Ok() { - return nil - } - return r.Data[r.start:r.pos] -} - -// IsStart returns whether the lexer is positioned at the start -// of an input string. -func (r *Lexer) IsStart() bool { - return r.pos == 0 -} - -// Consumed reads all remaining bytes from the input, publishing an error if -// there is anything but whitespace remaining. -func (r *Lexer) Consumed() { - if r.pos > len(r.Data) || !r.Ok() { - return - } - - for _, c := range r.Data[r.pos:] { - if c != ' ' && c != '\t' && c != '\r' && c != '\n' { - r.AddError(&LexerError{ - Reason: "invalid character '" + string(c) + "' after top-level value", - Offset: r.pos, - Data: string(r.Data[r.pos:]), - }) - return - } - - r.pos++ - r.start++ - } -} - -func (r *Lexer) unsafeString(skipUnescape bool) (string, []byte) { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() || r.token.kind != TokenString { - r.errInvalidToken("string") - return "", nil - } - if !skipUnescape { - if err := r.unescapeStringToken(); err != nil { - r.errInvalidToken("string") - return "", nil - } - } - - bytes := r.token.byteValue - ret := bytesToStr(r.token.byteValue) - r.consume() - return ret, bytes -} - -// UnsafeString returns the string value if the token is a string literal. -// -// Warning: returned string may point to the input buffer, so the string should not outlive -// the input buffer. Intended pattern of usage is as an argument to a switch statement. -func (r *Lexer) UnsafeString() string { - ret, _ := r.unsafeString(false) - return ret -} - -// UnsafeBytes returns the byte slice if the token is a string literal. -func (r *Lexer) UnsafeBytes() []byte { - _, ret := r.unsafeString(false) - return ret -} - -// UnsafeFieldName returns current member name string token -func (r *Lexer) UnsafeFieldName(skipUnescape bool) string { - ret, _ := r.unsafeString(skipUnescape) - return ret -} - -// String reads a string literal. -func (r *Lexer) String() string { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() || r.token.kind != TokenString { - r.errInvalidToken("string") - return "" - } - if err := r.unescapeStringToken(); err != nil { - r.errInvalidToken("string") - return "" - } - var ret string - if r.token.byteValueCloned { - ret = bytesToStr(r.token.byteValue) - } else { - ret = string(r.token.byteValue) - } - r.consume() - return ret -} - -// StringIntern reads a string literal, and performs string interning on it. -func (r *Lexer) StringIntern() string { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() || r.token.kind != TokenString { - r.errInvalidToken("string") - return "" - } - if err := r.unescapeStringToken(); err != nil { - r.errInvalidToken("string") - return "" - } - ret := intern.Bytes(r.token.byteValue) - r.consume() - return ret -} - -// Bytes reads a string literal and base64 decodes it into a byte slice. -func (r *Lexer) Bytes() []byte { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() || r.token.kind != TokenString { - r.errInvalidToken("string") - return nil - } - if err := r.unescapeStringToken(); err != nil { - r.errInvalidToken("string") - return nil - } - ret := make([]byte, base64.StdEncoding.DecodedLen(len(r.token.byteValue))) - n, err := base64.StdEncoding.Decode(ret, r.token.byteValue) - if err != nil { - r.fatalError = &LexerError{ - Reason: err.Error(), - } - return nil - } - - r.consume() - return ret[:n] -} - -// Bool reads a true or false boolean keyword. -func (r *Lexer) Bool() bool { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() || r.token.kind != TokenBool { - r.errInvalidToken("bool") - return false - } - ret := r.token.boolValue - r.consume() - return ret -} - -func (r *Lexer) number() string { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() || r.token.kind != TokenNumber { - r.errInvalidToken("number") - return "" - } - ret := bytesToStr(r.token.byteValue) - r.consume() - return ret -} - -func (r *Lexer) Uint8() uint8 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 8) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return uint8(n) -} - -func (r *Lexer) Uint16() uint16 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 16) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return uint16(n) -} - -func (r *Lexer) Uint32() uint32 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 32) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return uint32(n) -} - -func (r *Lexer) Uint64() uint64 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 64) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return n -} - -func (r *Lexer) Uint() uint { - return uint(r.Uint64()) -} - -func (r *Lexer) Int8() int8 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 8) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return int8(n) -} - -func (r *Lexer) Int16() int16 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 16) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return int16(n) -} - -func (r *Lexer) Int32() int32 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 32) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return int32(n) -} - -func (r *Lexer) Int64() int64 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 64) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return n -} - -func (r *Lexer) Int() int { - return int(r.Int64()) -} - -func (r *Lexer) Uint8Str() uint8 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 8) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return uint8(n) -} - -func (r *Lexer) Uint16Str() uint16 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 16) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return uint16(n) -} - -func (r *Lexer) Uint32Str() uint32 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 32) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return uint32(n) -} - -func (r *Lexer) Uint64Str() uint64 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseUint(s, 10, 64) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return n -} - -func (r *Lexer) UintStr() uint { - return uint(r.Uint64Str()) -} - -func (r *Lexer) UintptrStr() uintptr { - return uintptr(r.Uint64Str()) -} - -func (r *Lexer) Int8Str() int8 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 8) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return int8(n) -} - -func (r *Lexer) Int16Str() int16 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 16) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return int16(n) -} - -func (r *Lexer) Int32Str() int32 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 32) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return int32(n) -} - -func (r *Lexer) Int64Str() int64 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseInt(s, 10, 64) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return n -} - -func (r *Lexer) IntStr() int { - return int(r.Int64Str()) -} - -func (r *Lexer) Float32() float32 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseFloat(s, 32) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return float32(n) -} - -func (r *Lexer) Float32Str() float32 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - n, err := strconv.ParseFloat(s, 32) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return float32(n) -} - -func (r *Lexer) Float64() float64 { - s := r.number() - if !r.Ok() { - return 0 - } - - n, err := strconv.ParseFloat(s, 64) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: s, - }) - } - return n -} - -func (r *Lexer) Float64Str() float64 { - s, b := r.unsafeString(false) - if !r.Ok() { - return 0 - } - n, err := strconv.ParseFloat(s, 64) - if err != nil { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Reason: err.Error(), - Data: string(b), - }) - } - return n -} - -func (r *Lexer) Error() error { - return r.fatalError -} - -func (r *Lexer) AddError(e error) { - if r.fatalError == nil { - r.fatalError = e - } -} - -func (r *Lexer) AddNonFatalError(e error) { - r.addNonfatalError(&LexerError{ - Offset: r.start, - Data: string(r.Data[r.start:r.pos]), - Reason: e.Error(), - }) -} - -func (r *Lexer) addNonfatalError(err *LexerError) { - if r.UseMultipleErrors { - // We don't want to add errors with the same offset. - if len(r.multipleErrors) != 0 && r.multipleErrors[len(r.multipleErrors)-1].Offset == err.Offset { - return - } - r.multipleErrors = append(r.multipleErrors, err) - return - } - r.fatalError = err -} - -func (r *Lexer) GetNonFatalErrors() []*LexerError { - return r.multipleErrors -} - -// JsonNumber fetches and json.Number from 'encoding/json' package. -// Both int, float or string, contains them are valid values -func (r *Lexer) JsonNumber() json.Number { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - if !r.Ok() { - r.errInvalidToken("json.Number") - return json.Number("") - } - - switch r.token.kind { - case TokenString: - return json.Number(r.String()) - case TokenNumber: - return json.Number(r.Raw()) - case TokenNull: - r.Null() - return json.Number("") - default: - r.errSyntax() - return json.Number("") - } -} - -// Interface fetches an interface{} analogous to the 'encoding/json' package. -func (r *Lexer) Interface() interface{} { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - - if !r.Ok() { - return nil - } - switch r.token.kind { - case TokenString: - return r.String() - case TokenNumber: - return r.Float64() - case TokenBool: - return r.Bool() - case TokenNull: - r.Null() - return nil - } - - if r.token.delimValue == '{' { - r.consume() - - ret := map[string]interface{}{} - for !r.IsDelim('}') { - key := r.String() - r.WantColon() - ret[key] = r.Interface() - r.WantComma() - } - r.Delim('}') - - if r.Ok() { - return ret - } else { - return nil - } - } else if r.token.delimValue == '[' { - r.consume() - - ret := []interface{}{} - for !r.IsDelim(']') { - ret = append(ret, r.Interface()) - r.WantComma() - } - r.Delim(']') - - if r.Ok() { - return ret - } else { - return nil - } - } - r.errSyntax() - return nil -} - -// WantComma requires a comma to be present before fetching next token. -func (r *Lexer) WantComma() { - r.wantSep = ',' - r.firstElement = false -} - -// WantColon requires a colon to be present before fetching next token. -func (r *Lexer) WantColon() { - r.wantSep = ':' - r.firstElement = false -} - -// CurrentToken returns current token kind if there were no errors and TokenUndef otherwise -func (r *Lexer) CurrentToken() TokenKind { - if r.token.kind == TokenUndef && r.Ok() { - r.FetchToken() - } - - if !r.Ok() { - return TokenUndef - } - - return r.token.kind -} diff --git a/vendor/github.com/mailru/easyjson/jwriter/writer.go b/vendor/github.com/mailru/easyjson/jwriter/writer.go deleted file mode 100644 index 34b0ade4..00000000 --- a/vendor/github.com/mailru/easyjson/jwriter/writer.go +++ /dev/null @@ -1,417 +0,0 @@ -// Package jwriter contains a JSON writer. -package jwriter - -import ( - "io" - "strconv" - "unicode/utf8" - - "github.com/mailru/easyjson/buffer" -) - -// Flags describe various encoding options. The behavior may be actually implemented in the encoder, but -// Flags field in Writer is used to set and pass them around. -type Flags int - -const ( - NilMapAsEmpty Flags = 1 << iota // Encode nil map as '{}' rather than 'null'. - NilSliceAsEmpty // Encode nil slice as '[]' rather than 'null'. -) - -// Writer is a JSON writer. -type Writer struct { - Flags Flags - - Error error - Buffer buffer.Buffer - NoEscapeHTML bool -} - -// Size returns the size of the data that was written out. -func (w *Writer) Size() int { - return w.Buffer.Size() -} - -// DumpTo outputs the data to given io.Writer, resetting the buffer. -func (w *Writer) DumpTo(out io.Writer) (written int, err error) { - return w.Buffer.DumpTo(out) -} - -// BuildBytes returns writer data as a single byte slice. You can optionally provide one byte slice -// as argument that it will try to reuse. -func (w *Writer) BuildBytes(reuse ...[]byte) ([]byte, error) { - if w.Error != nil { - return nil, w.Error - } - - return w.Buffer.BuildBytes(reuse...), nil -} - -// ReadCloser returns an io.ReadCloser that can be used to read the data. -// ReadCloser also resets the buffer. -func (w *Writer) ReadCloser() (io.ReadCloser, error) { - if w.Error != nil { - return nil, w.Error - } - - return w.Buffer.ReadCloser(), nil -} - -// RawByte appends raw binary data to the buffer. -func (w *Writer) RawByte(c byte) { - w.Buffer.AppendByte(c) -} - -// RawByte appends raw binary data to the buffer. -func (w *Writer) RawString(s string) { - w.Buffer.AppendString(s) -} - -// RawBytesString appends string from bytes to the buffer. -func (w *Writer) RawBytesString(data []byte, err error) { - switch { - case w.Error != nil: - return - case err != nil: - w.Error = err - default: - w.String(string(data)) - } -} - -// Raw appends raw binary data to the buffer or sets the error if it is given. Useful for -// calling with results of MarshalJSON-like functions. -func (w *Writer) Raw(data []byte, err error) { - switch { - case w.Error != nil: - return - case err != nil: - w.Error = err - case len(data) > 0: - w.Buffer.AppendBytes(data) - default: - w.RawString("null") - } -} - -// RawText encloses raw binary data in quotes and appends in to the buffer. -// Useful for calling with results of MarshalText-like functions. -func (w *Writer) RawText(data []byte, err error) { - switch { - case w.Error != nil: - return - case err != nil: - w.Error = err - case len(data) > 0: - w.String(string(data)) - default: - w.RawString("null") - } -} - -// Base64Bytes appends data to the buffer after base64 encoding it -func (w *Writer) Base64Bytes(data []byte) { - if data == nil { - w.Buffer.AppendString("null") - return - } - w.Buffer.AppendByte('"') - w.base64(data) - w.Buffer.AppendByte('"') -} - -func (w *Writer) Uint8(n uint8) { - w.Buffer.EnsureSpace(3) - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) -} - -func (w *Writer) Uint16(n uint16) { - w.Buffer.EnsureSpace(5) - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) -} - -func (w *Writer) Uint32(n uint32) { - w.Buffer.EnsureSpace(10) - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) -} - -func (w *Writer) Uint(n uint) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) -} - -func (w *Writer) Uint64(n uint64) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10) -} - -func (w *Writer) Int8(n int8) { - w.Buffer.EnsureSpace(4) - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) -} - -func (w *Writer) Int16(n int16) { - w.Buffer.EnsureSpace(6) - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) -} - -func (w *Writer) Int32(n int32) { - w.Buffer.EnsureSpace(11) - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) -} - -func (w *Writer) Int(n int) { - w.Buffer.EnsureSpace(21) - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) -} - -func (w *Writer) Int64(n int64) { - w.Buffer.EnsureSpace(21) - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10) -} - -func (w *Writer) Uint8Str(n uint8) { - w.Buffer.EnsureSpace(3) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Uint16Str(n uint16) { - w.Buffer.EnsureSpace(5) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Uint32Str(n uint32) { - w.Buffer.EnsureSpace(10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) UintStr(n uint) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Uint64Str(n uint64) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) UintptrStr(n uintptr) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Int8Str(n int8) { - w.Buffer.EnsureSpace(4) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Int16Str(n int16) { - w.Buffer.EnsureSpace(6) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Int32Str(n int32) { - w.Buffer.EnsureSpace(11) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) IntStr(n int) { - w.Buffer.EnsureSpace(21) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Int64Str(n int64) { - w.Buffer.EnsureSpace(21) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Float32(n float32) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32) -} - -func (w *Writer) Float32Str(n float32) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Float64(n float64) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, 'g', -1, 64) -} - -func (w *Writer) Float64Str(n float64) { - w.Buffer.EnsureSpace(20) - w.Buffer.Buf = append(w.Buffer.Buf, '"') - w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 64) - w.Buffer.Buf = append(w.Buffer.Buf, '"') -} - -func (w *Writer) Bool(v bool) { - w.Buffer.EnsureSpace(5) - if v { - w.Buffer.Buf = append(w.Buffer.Buf, "true"...) - } else { - w.Buffer.Buf = append(w.Buffer.Buf, "false"...) - } -} - -const chars = "0123456789abcdef" - -func getTable(falseValues ...int) [128]bool { - table := [128]bool{} - - for i := 0; i < 128; i++ { - table[i] = true - } - - for _, v := range falseValues { - table[v] = false - } - - return table -} - -var ( - htmlEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '&', '<', '>', '\\') - htmlNoEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '\\') -) - -func (w *Writer) String(s string) { - w.Buffer.AppendByte('"') - - // Portions of the string that contain no escapes are appended as - // byte slices. - - p := 0 // last non-escape symbol - - escapeTable := &htmlEscapeTable - if w.NoEscapeHTML { - escapeTable = &htmlNoEscapeTable - } - - for i := 0; i < len(s); { - c := s[i] - - if c < utf8.RuneSelf { - if escapeTable[c] { - // single-width character, no escaping is required - i++ - continue - } - - w.Buffer.AppendString(s[p:i]) - switch c { - case '\t': - w.Buffer.AppendString(`\t`) - case '\r': - w.Buffer.AppendString(`\r`) - case '\n': - w.Buffer.AppendString(`\n`) - case '\\': - w.Buffer.AppendString(`\\`) - case '"': - w.Buffer.AppendString(`\"`) - default: - w.Buffer.AppendString(`\u00`) - w.Buffer.AppendByte(chars[c>>4]) - w.Buffer.AppendByte(chars[c&0xf]) - } - - i++ - p = i - continue - } - - // broken utf - runeValue, runeWidth := utf8.DecodeRuneInString(s[i:]) - if runeValue == utf8.RuneError && runeWidth == 1 { - w.Buffer.AppendString(s[p:i]) - w.Buffer.AppendString(`\ufffd`) - i++ - p = i - continue - } - - // jsonp stuff - tab separator and line separator - if runeValue == '\u2028' || runeValue == '\u2029' { - w.Buffer.AppendString(s[p:i]) - w.Buffer.AppendString(`\u202`) - w.Buffer.AppendByte(chars[runeValue&0xf]) - i += runeWidth - p = i - continue - } - i += runeWidth - } - w.Buffer.AppendString(s[p:]) - w.Buffer.AppendByte('"') -} - -const encode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -const padChar = '=' - -func (w *Writer) base64(in []byte) { - - if len(in) == 0 { - return - } - - w.Buffer.EnsureSpace(((len(in)-1)/3 + 1) * 4) - - si := 0 - n := (len(in) / 3) * 3 - - for si < n { - // Convert 3x 8bit source bytes into 4 bytes - val := uint(in[si+0])<<16 | uint(in[si+1])<<8 | uint(in[si+2]) - - w.Buffer.Buf = append(w.Buffer.Buf, encode[val>>18&0x3F], encode[val>>12&0x3F], encode[val>>6&0x3F], encode[val&0x3F]) - - si += 3 - } - - remain := len(in) - si - if remain == 0 { - return - } - - // Add the remaining small block - val := uint(in[si+0]) << 16 - if remain == 2 { - val |= uint(in[si+1]) << 8 - } - - w.Buffer.Buf = append(w.Buffer.Buf, encode[val>>18&0x3F], encode[val>>12&0x3F]) - - switch remain { - case 2: - w.Buffer.Buf = append(w.Buffer.Buf, encode[val>>6&0x3F], byte(padChar)) - case 1: - w.Buffer.Buf = append(w.Buffer.Buf, byte(padChar), byte(padChar)) - } -} diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go index 8f8dc65d..0339d8c1 100644 --- a/vendor/github.com/prometheus/common/expfmt/decode.go +++ b/vendor/github.com/prometheus/common/expfmt/decode.go @@ -72,13 +72,15 @@ func ResponseFormat(h http.Header) Format { // 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 +// escaping, traditional Prometheus 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. +// and Prometheus text format. For historical reasons, this decoder falls back +// to classic text decoding for other legacy formats, but returns an error for +// unsupported formats such as OpenMetrics 2.0. This decoder does not fully +// support OpenMetrics although it may often succeed for OpenMetrics 1.0 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 @@ -90,6 +92,11 @@ func NewDecoder(r io.Reader, format Format) Decoder { return &protoDecoder{r: bufio.NewReader(r), s: scheme} case TypeProtoText, TypeProtoCompact: return &errDecoder{err: fmt.Errorf("format %s not supported for decoding", format)} + case TypeOpenMetrics: + _, params, err := mime.ParseMediaType(string(format)) + if err == nil && params["version"] == OpenMetricsVersion_2_0_0 { + return &errDecoder{err: fmt.Errorf("format %s not supported for decoding", format)} + } } return &textDecoder{r: r, s: scheme} } diff --git a/vendor/github.com/prometheus/common/expfmt/encode.go b/vendor/github.com/prometheus/common/expfmt/encode.go index 73c24dfb..6945356c 100644 --- a/vendor/github.com/prometheus/common/expfmt/encode.go +++ b/vendor/github.com/prometheus/common/expfmt/encode.go @@ -16,6 +16,7 @@ package expfmt import ( "fmt" "io" + "mime" "net/http" "github.com/munnerz/goautoneg" @@ -26,6 +27,24 @@ import ( "github.com/prometheus/common/model" ) +var formatToAccept = map[Format]goautoneg.Accept{} + +func init() { + for _, f := range []Format{ + FmtText, + FmtProtoDelim, + FmtProtoText, + FmtProtoCompact, + FmtOpenMetrics_1_0_0, + fmtOpenMetrics_2_0_0, + FmtOpenMetrics_0_0_1, + } { + if parsed := goautoneg.ParseAccept(string(f)); len(parsed) > 0 { + formatToAccept[f] = parsed[0] + } + } +} + // Encoder types encode metric families into an underlying wire protocol. type Encoder interface { Encode(*dto.MetricFamily) error @@ -57,11 +76,30 @@ func (ec encoderCloser) Close() error { // 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. +// Prometheus text format). +// +// Deprecated: Use NegotiateAccept(h, FmtProtoDelim, FmtProtoText, FmtProtoCompact, FmtText) +// or specify only the formats supported by your server. func Negotiate(h http.Header) Format { - escapingScheme := Format(fmt.Sprintf("; escaping=%s", Format(model.NameEscapingScheme.String()))) + return NegotiateAccept(h, FmtProtoDelim, FmtProtoText, FmtProtoCompact, FmtText) +} + +// NegotiateIncludingOpenMetrics works like Negotiate but includes +// FmtOpenMetrics as an option for the result. +// +// Deprecated: Use NegotiateAccept(h, FmtOpenMetrics_1_0_0, FmtOpenMetrics_0_0_1, FmtProtoDelim, FmtProtoText, FmtProtoCompact, FmtText) +// or specify only the formats supported by your server. +func NegotiateIncludingOpenMetrics(h http.Header) Format { + return NegotiateAccept(h, FmtOpenMetrics_1_0_0, FmtOpenMetrics_0_0_1, FmtProtoDelim, FmtProtoText, FmtProtoCompact, FmtText) +} + +// NegotiateAccept returns the Content-Type based on the given Accept header +// and the list of accepted Formats provided by the caller, in order of preference. +// If no accepted format matches the Accept header, it falls back to the text +// format if present in the accepted list, or the first accepted format (or FmtText +// if accepted is empty). +func NegotiateAccept(h http.Header, accepted ...Format) Format { + escapingScheme := Format("; escaping=" + model.NameEscapingScheme.String()) for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) { if escapeParam := ac.Params[model.EscapingKey]; escapeParam != "" { switch Format(escapeParam) { @@ -71,63 +109,66 @@ func Negotiate(h http.Header) Format { // 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 + + for _, f := range accepted { + if matchFormat(ac, f) { + return f + escapingScheme } } - if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { - return FmtText + escapingScheme + } + for _, f := range accepted { + if f.FormatType() == TypeTextPlain { + return f + escapingScheme } } + if len(accepted) > 0 { + return accepted[0] + 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. - } +// matchFormat checks if a parsed accept clause matches a given Format. +func matchFormat(ac goautoneg.Accept, f Format) bool { + target, ok := formatToAccept[f] + if !ok { + parsed := goautoneg.ParseAccept(string(f)) + if len(parsed) == 0 { + return false } - 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 - } + target = parsed[0] + } + + if ac.Type != "*" && ac.Type != target.Type { + return false + } + if ac.SubType != "*" && ac.SubType != target.SubType { + return false + } + + // Default OpenMetrics version to OpenMetricsVersion_0_0_1. + acVersion := ac.Params["version"] + if acVersion == "" && ac.Type+"/"+ac.SubType == OpenMetricsType { + acVersion = OpenMetricsVersion_0_0_1 + } + if acVersion == "" && ac.Type == "text" && ac.SubType == "plain" { + acVersion = TextVersion + } + + // General param matching. + for k, v := range target.Params { + if k == "charset" { + continue } - if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { - return FmtText + escapingScheme + acVal := ac.Params[k] + if k == "version" { + acVal = acVersion } - 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 - } + if acVal != v { + return false } } - return FmtText + escapingScheme + + return true } // NewEncoder returns a new encoder based on content type negotiation. All @@ -181,6 +222,19 @@ func NewEncoder(w io.Writer, format Format, options ...EncoderOption) Encoder { close: func() error { return nil }, } case TypeOpenMetrics: + _, params, err := mime.ParseMediaType(string(format)) + if err == nil && params["version"] == OpenMetricsVersion_2_0_0 { + return encoderCloser{ + encode: func(v *dto.MetricFamily) error { + _, err := MetricFamilyToOpenMetrics20(w, model.EscapeMetricFamily(v, escapingScheme), options...) + return err + }, + close: func() error { + _, err := FinalizeOpenMetrics(w) + return err + }, + } + } return encoderCloser{ encode: func(v *dto.MetricFamily) error { _, err := MetricFamilyToOpenMetrics(w, model.EscapeMetricFamily(v, escapingScheme), options...) diff --git a/vendor/github.com/prometheus/common/expfmt/expfmt.go b/vendor/github.com/prometheus/common/expfmt/expfmt.go index 10bf3570..40035f20 100644 --- a/vendor/github.com/prometheus/common/expfmt/expfmt.go +++ b/vendor/github.com/prometheus/common/expfmt/expfmt.go @@ -42,6 +42,8 @@ const ( OpenMetricsVersion_0_0_1 = "0.0.1" //nolint:revive // Allow for underscores. OpenMetricsVersion_1_0_0 = "1.0.0" + //nolint:revive // Allow for underscores. + OpenMetricsVersion_2_0_0 = "2.0.0" // The Content-Type values for the different wire protocols. Do not do direct // comparisons to these constants, instead use the comparison functions. @@ -59,6 +61,8 @@ const ( // 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` + //nolint:revive // Allow for underscores. + fmtOpenMetrics_2_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_2_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` @@ -107,6 +111,9 @@ func NewFormat(t FormatType) Format { // NewOpenMetricsFormat generates a new OpenMetrics format matching the // specified version number. +// +// Note: OpenMetrics version 2.0.0 is experimental and encode-only (currently +// supporting counter, gauge, and untyped metric types). func NewOpenMetricsFormat(version string) (Format, error) { if version == OpenMetricsVersion_0_0_1 { return FmtOpenMetrics_0_0_1, nil @@ -114,6 +121,10 @@ func NewOpenMetricsFormat(version string) (Format, error) { if version == OpenMetricsVersion_1_0_0 { return FmtOpenMetrics_1_0_0, nil } + if version == OpenMetricsVersion_2_0_0 { + // OpenMetrics 2.0.0 is experimental and encode-only (counter/gauge/untyped). + return fmtOpenMetrics_2_0_0, nil + } return FmtUnknown, errors.New("unknown open metrics version string") } diff --git a/vendor/github.com/prometheus/common/expfmt/openmetrics_2_0_create.go b/vendor/github.com/prometheus/common/expfmt/openmetrics_2_0_create.go new file mode 100644 index 00000000..8ca9b6be --- /dev/null +++ b/vendor/github.com/prometheus/common/expfmt/openmetrics_2_0_create.go @@ -0,0 +1,425 @@ +// 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 expfmt + +import ( + "bufio" + "errors" + "fmt" + "io" + "math" + "strconv" + "strings" + + dto "github.com/prometheus/client_model/go" + "google.golang.org/protobuf/types/known/timestamppb" +) + +// MetricFamilyToOpenMetrics20 converts a MetricFamily proto message into the +// OpenMetrics text format version 2.0.0 and writes the resulting lines to 'out'. +// It returns the number of bytes written and any error encountered. +// +// NOTE: This method targets OpenMetrics 2.0.0 (currently aligned with 2.0-rc.0) which is experimental and +// encode-only (currently supporting counter, gauge, and untyped metric types). +// Breaking changes might happen in the future. This implementation is still a +// work-in-progress, and does not yet support all features of the format. +// EncoderOptions are accepted for signature compatibility with +// MetricFamilyToOpenMetrics and are currently ignored. +func MetricFamilyToOpenMetrics20(out io.Writer, in *dto.MetricFamily, options ...EncoderOption) (written int, err error) { + // Options are accepted for signature compatibility and ignored. + _ = options + name := in.GetName() + if name == "" { + return 0, fmt.Errorf("MetricFamily has no name: %s", in) + } + if containsRawNewline(name) { + return 0, fmt.Errorf("MetricFamily name %q contains raw newlines", name) + } + if in.Unit != nil && containsRawNewline(*in.Unit) { + return 0, fmt.Errorf("MetricFamily unit %q contains raw newlines", *in.Unit) + } + + // 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() + ) + + // 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, 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, name) + written += n + if err != nil { + return written, err + } + 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(" unknown\n") + case dto.MetricType_HISTOGRAM: + n, err = w.WriteString(" histogram\n") + case dto.MetricType_GAUGE_HISTOGRAM: + n, err = w.WriteString(" gaugehistogram\n") + default: + // TODO: Support Info and StateSet once they are supported in the + // Prometheus protobuf format. + return written, fmt.Errorf("unknown metric type %s", metricType.String()) + } + written += n + if err != nil { + return written, err + } + if in.Unit != nil { + n, err = w.WriteString("# UNIT ") + 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.Unit, true) + written += n + if err != nil { + return written, err + } + err = w.WriteByte('\n') + written++ + if err != nil { + return written, err + } + } + + // Finally the samples, one line for each. + for _, metric := range in.Metric { + if metric == nil { + return written, fmt.Errorf("expected non-nil metric in MetricFamily %s", name) + } + switch metricType { + case dto.MetricType_COUNTER: + if metric.Counter == nil { + return written, fmt.Errorf("expected counter in metric %s %s", name, metric) + } + val := metric.Counter.GetValue() + if math.IsNaN(val) { + return written, fmt.Errorf("counter value cannot be NaN in metric %s", name) + } + if val < 0 { + return written, fmt.Errorf("counter value cannot be negative (%g) in metric %s", val, name) + } + n, err = writeOpenMetrics20Sample(w, name, metric, val, 0, false, metric.Counter.CreatedTimestamp, metric.Counter.Exemplar) + case dto.MetricType_GAUGE: + if metric.Gauge == nil { + return written, fmt.Errorf("expected gauge in metric %s %s", name, metric) + } + n, err = writeOpenMetrics20Sample(w, name, metric, metric.Gauge.GetValue(), 0, false, nil, nil) + case dto.MetricType_UNTYPED: + if metric.Untyped == nil { + return written, fmt.Errorf("expected untyped in metric %s %s", name, metric) + } + n, err = writeOpenMetrics20Sample(w, name, metric, metric.Untyped.GetValue(), 0, false, nil, nil) + case dto.MetricType_SUMMARY: + if metric.Summary == nil { + return written, fmt.Errorf("expected summary in metric %s %s", name, metric) + } + n, err = writeCompositeSummary(w, name, metric) + case dto.MetricType_HISTOGRAM, dto.MetricType_GAUGE_HISTOGRAM: + if metric.Histogram == nil { + return written, fmt.Errorf("expected histogram in metric %s %s", name, metric) + } + n, err = writeCompositeHistogram(w, name, metric, metricType == dto.MetricType_GAUGE_HISTOGRAM) + default: + return written, fmt.Errorf("unexpected type in metric %s %s", name, metric) + } + written += n + if err != nil { + return written, err + } + } + return written, nil +} + +// writeOpenMetrics20Sample writes a single sample for simple types (Counter, Gauge, Untyped). +func writeOpenMetrics20Sample(w enhancedWriter, name string, metric *dto.Metric, floatValue float64, intValue uint64, useIntValue bool, startTimestamp *timestamppb.Timestamp, exemplar *dto.Exemplar) (int, error) { + if err := validateLabels20(metric.Label); err != nil { + return 0, err + } + written := 0 + n, err := writeOpenMetricsNameAndLabelPairs(w, name, metric.Label, "", 0) + 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 + } + n, err = writeOpenMetrics20Timestamp(w, float64(*metric.TimestampMs)/1000) + written += n + if err != nil { + return written, err + } + } + + // Start Timestamp + if startTimestamp != nil { + if err := startTimestamp.CheckValid(); err != nil { + return written, fmt.Errorf("invalid created timestamp in metric %s: %w", name, err) + } + n, err = w.WriteString(" st@") + written += n + if err != nil { + return written, err + } + n, err = writeProtoTimestamp(w, startTimestamp) + written += n + if err != nil { + return written, err + } + } + + if exemplar != nil { + n, err = writeExemplar20(w, exemplar) + written += n + if err != nil { + return written, err + } + } + + err = w.WriteByte('\n') + written++ + if err != nil { + return written, err + } + return written, nil +} + +// writeExemplar20 writes the provided exemplar in OpenMetrics 2.0 format to w. +// In OpenMetrics 2.0, invalid exemplars or exemplars without a timestamp are dropped. +func writeExemplar20(w enhancedWriter, e *dto.Exemplar) (int, error) { + if e == nil { + return 0, nil + } + // In OpenMetrics 2.0, invalid exemplars are dropped rather than failing the entire exposition. + if err := validateExemplar20(e); err != nil { + return 0, nil + } + written := 0 + n, err := w.WriteString(" # ") + written += n + if err != nil { + return written, err + } + if len(e.Label) == 0 { + n, err = w.WriteString("{}") + } else { + 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 + } + err = w.WriteByte(' ') + written++ + if err != nil { + return written, err + } + ts := e.Timestamp + n, err = writeProtoTimestamp(w, ts) + written += n + if err != nil { + return written, err + } + return written, nil +} + +// writeOpenMetrics20Timestamp writes a float64 as a timestamp without scientific notation. +func writeOpenMetrics20Timestamp(w enhancedWriter, f float64) (int, error) { + bp := numBufPool.Get().(*[]byte) + *bp = strconv.AppendFloat((*bp)[:0], f, 'f', -1, 64) + written, err := w.Write(*bp) + numBufPool.Put(bp) + return written, err +} + +// Stubs for Summary and Histogram + +func writeCompositeSummary(w enhancedWriter, name string, metric *dto.Metric) (int, error) { + _ = w + _ = name + _ = metric + return 0, errors.New("summary not implemented yet") +} + +func writeCompositeHistogram(w enhancedWriter, name string, metric *dto.Metric, isGauge bool) (int, error) { + _ = w + _ = name + _ = metric + _ = isGauge + return 0, errors.New("histogram not implemented yet") +} + +func validateLabels20(labels []*dto.LabelPair) error { + for _, lp := range labels { + if lp == nil { + return errors.New("expected non-nil label pair") + } + lname := lp.GetName() + if lname == "" { + return errors.New("label name cannot be empty") + } + if containsRawNewline(lname) { + return fmt.Errorf("label name %q contains raw newlines", lname) + } + } + return nil +} + +func containsRawNewline(s string) bool { + return strings.IndexByte(s, '\n') >= 0 || strings.IndexByte(s, '\r') >= 0 +} + +func validateExemplar20(e *dto.Exemplar) error { + if e.Timestamp == nil { + return errors.New("exemplar timestamp is required") + } + if err := e.Timestamp.CheckValid(); err != nil { + return err + } + return validateLabels20(e.Label) +} + +func writeProtoTimestamp(w enhancedWriter, ts *timestamppb.Timestamp) (int, error) { + if err := ts.CheckValid(); err != nil { + return 0, err + } + n, err := writeInt(w, ts.Seconds) + if err != nil { + return n, err + } + if ts.Nanos == 0 { + return n, nil + } + err = w.WriteByte('.') + written := n + 1 + if err != nil { + return written, err + } + bp := numBufPool.Get().(*[]byte) + *bp = strconv.AppendInt((*bp)[:0], int64(ts.Nanos), 10) + pad := 9 - len(*bp) + for range pad { + err = w.WriteByte('0') + written++ + if err != nil { + numBufPool.Put(bp) + return written, err + } + } + val := *bp + for len(val) > 0 && val[len(val)-1] == '0' { + val = val[:len(val)-1] + } + n2, err := w.Write(val) + written += n2 + numBufPool.Put(bp) + return written, err +} diff --git a/vendor/github.com/prometheus/common/model/signature.go b/vendor/github.com/prometheus/common/model/signature.go index dc8a0026..b723e3bb 100644 --- a/vendor/github.com/prometheus/common/model/signature.go +++ b/vendor/github.com/prometheus/common/model/signature.go @@ -14,7 +14,7 @@ package model import ( - "sort" + "slices" ) // SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is @@ -37,7 +37,7 @@ func LabelsToSignature(labels map[string]string) uint64 { for labelName := range labels { labelNames = append(labelNames, labelName) } - sort.Strings(labelNames) + slices.Sort(labelNames) sum := hashNew() for _, labelName := range labelNames { @@ -60,7 +60,7 @@ func labelSetToFingerprint(ls LabelSet) Fingerprint { for labelName := range ls { labelNames = append(labelNames, labelName) } - sort.Sort(labelNames) + slices.Sort(labelNames) sum := hashNew() for _, labelName := range labelNames { @@ -100,7 +100,7 @@ func SignatureForLabels(m Metric, labels ...LabelName) uint64 { return emptyLabelSignature } - sort.Sort(LabelNames(labels)) + slices.Sort(labels) sum := hashNew() for _, label := range labels { @@ -129,7 +129,7 @@ func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { if len(labelNames) == 0 { return emptyLabelSignature } - sort.Sort(labelNames) + slices.Sort(labelNames) sum := hashNew() for _, labelName := range labelNames { diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go index 0854753f..98607174 100644 --- a/vendor/github.com/prometheus/common/model/time.go +++ b/vendor/github.com/prometheus/common/model/time.go @@ -164,6 +164,34 @@ func (t *Time) UnmarshalJSON(b []byte) error { // This type should not propagate beyond the scope of input/output processing. type Duration time.Duration +// Common durations. Day and Week are included because ParseDuration supports +// those units (unlike the standard time package). +// +// To count the number of units in a Duration, divide: +// +// second := model.Second +// fmt.Print(int64(second/model.Millisecond)) // prints 1000 +// +// To convert an integer number of units to a Duration, multiply: +// +// seconds := 10 +// fmt.Print(model.Duration(seconds)*model.Second) // prints 10s +const ( + Nanosecond Duration = 1 + Microsecond = 1000 * Nanosecond + Millisecond = 1000 * Microsecond + Second = 1000 * Millisecond + Minute = 60 * Second + Hour = 60 * Minute + Day = 24 * Hour + Week = 7 * Day +) + +// Milliseconds returns the duration as an integer millisecond count. +// Prometheus stores timestamps in milliseconds; time.Duration already +// covers the other units. +func (d Duration) Milliseconds() int64 { return time.Duration(d).Milliseconds() } + // Set implements pflag/flag.Value. func (d *Duration) Set(s string) error { var err error diff --git a/vendor/github.com/sirupsen/logrus/.golangci.yml b/vendor/github.com/sirupsen/logrus/.golangci.yml index 792db361..c9a840e0 100644 --- a/vendor/github.com/sirupsen/logrus/.golangci.yml +++ b/vendor/github.com/sirupsen/logrus/.golangci.yml @@ -1,12 +1,9 @@ version: "2" -run: - tests: false linters: enable: - asasalint - asciicheck - bidichk - - bodyclose - contextcheck - durationcheck - errchkjson @@ -22,46 +19,21 @@ linters: - nilerr - nilnesserr - noctx - - protogetter - reassign - recvcheck - - rowserrcheck - - spancheck - - sqlclosecheck - testifylint - unparam - - zerologlint - disable: - - prealloc - settings: - errcheck: - check-type-assertions: false - check-blank: false - lll: - line-length: 100 - tab-width: 4 - prealloc: - simple: false - range-loops: false - for-loops: false - whitespace: - multi-if: false - multi-func: false exclusions: - generated: lax presets: - - comments - - common-false-positives - legacy - std-error-handling - paths: - - third_party$ - - builtin$ - - examples$ -formatters: - exclusions: - generated: lax - paths: - - third_party$ - - builtin$ - - examples$ + rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - gosec + - musttag + - noctx # TODO: enable once we switch to Go 1.24+. + - linters: # TODO: remove once golangci-lint is updated with https://github.com/golangci/golangci-lint/pull/6584 + - gocheckcompilerdirectives + text: 'compiler directive unrecognized: //go:fix' diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml deleted file mode 100644 index c1dbd5a3..00000000 --- a/vendor/github.com/sirupsen/logrus/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -go_import_path: github.com/sirupsen/logrus -git: - depth: 1 -env: - - GO111MODULE=on -go: 1.15.x -os: linux -install: - - ./travis/install.sh -script: - - cd ci - - go run mage.go -v -w ../ crossBuild - - go run mage.go -v -w ../ lint - - go run mage.go -v -w ../ test diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md index 098608ff..683cec90 100644 --- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md +++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -1,90 +1,253 @@ -# 1.8.1 +# Changelog + +All notable changes to this project will be documented in this file. + +## 1.10.2 + +Changed: + + * Update `github.com/stretchr/testify` to v1.12.1, removing the legacy + `gopkg.in/yaml.v3` dependency. + +## 1.10.1 + +Fixes: + + * Fix a regression introduced in v1.10.0 where `TextFormatter` could panic + when formatting nil or panicking `error` and `fmt.Stringer` values. + * Allow function-backed implementations of `error` as field values. + +## 1.10.0 + +Fixes: + + * Fix reentrant logging deadlocks in formatter paths. + * Fix race conditions in formatter and entry handling. + * Fix generic `Log`, `Logf`, `Logln`, and `LogFn` methods unexpectedly + panicking when called with `PanicLevel`. Use the corresponding `Panic` + methods when panic behavior is desired. + * Improve concurrency safety around formatter and hook access. + +Features: + + * Add `slog` hook for forwarding Logrus entries to `log/slog`. + * Add `slog.Handler` for forwarding `log/slog` records to a Logrus logger, + including levels, fields, groups, context, time, and optional caller + reporting. The hook and handler can also be combined to help migrate + between Logrus and `log/slog`. + * Add minimal, composable logging interfaces for each log level. This enables + consumers to depend on narrower interfaces, making it easier to substitute + or adapt logging implementations. + * Allow `Entry.Caller` to be set explicitly and preserve it across derived + entries, enabling custom caller detection without Logrus overwriting + caller information when `ReportCaller` is enabled. + +Changed: + + * Raise minimum supported Go version to 1.23. + * TextFormatter now renders `[]byte` values as raw/quoted strings instead of slice-of-ints. + * TextFormatter now uses distinct dimmed colors for debug and trace output. + * TextFormatter now automatically enables colors on Windows terminals with ANSI support, + matching the behavior on other platforms. + * `Entry.HasCaller` is now deprecated in favor of checking `Entry.Caller` directly. + * Deprecated `MutexWrap`, which was unintentionally exposed as public API. + It remains available as an alias for compatibility but should not be used + directly. + +Performance: + + * Significantly improve TextFormatter performance and reduce allocations. + * Optimize common Entry and Logger hot paths. + * Reduce allocations in caller reporting. + * ~17% lower geomean runtime and ~27% higher formatter throughput overall. + * Common enabled logging paths are ~30–44% faster. + * TextFormatter paths are up to ~40% faster, with allocation counts reduced + by 25–74% across the measured formatter cases. + + +## 1.9.4 + +Fixes: + + * Remove uses of deprecated `ioutil` package + +Features: + + * Add GNU/Hurd support + * Add WASI wasip1 support + +Code quality: + + * Update minimum supported Go version to 1.17 + * Documentation updates + + +## 1.9.3 + +Fixes: + + * Re-apply fix for potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376) + * Fix panic in Writer + + +## 1.9.2 + +Fixes: + + * Revert Writer DoS fix (#1376) due to regression + + +## 1.9.1 + +Fixes: + + * Fix potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376) + + +## 1.9.0 + +Fixes: + + * Multiple concurrency and race condition fixes + * Improve Windows terminal and ANSI handling + Code quality: + + * Internal cleanups and modernization + + +## 1.8.3 + +Fixes: + + * Fix potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376) + + +## 1.8.2 + +Features: + + * Add support for the logger private buffer pool (#1253) + +Fixes: + + * Fix race condition for SetFormatter and SetReportCaller + * Fix data race in hooks test package + +## 1.8.1 + +Code quality: + * move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer * improve timestamp format documentation Fixes: + * fix race condition on logger hooks -# 1.8.0 +## 1.8.0 Correct versioning number replacing v1.7.1. -# 1.7.1 +## 1.7.1 Beware this release has introduced a new public API and its semver is therefore incorrect. Code quality: + * use go 1.15 in travis * use magefile as task runner Fixes: + * small fixes about new go 1.13 error formatting system * Fix for long time race condiction with mutating data hooks Features: + * build support for zos -# 1.7.0 +## 1.7.0 + Fixes: + * the dependency toward a windows terminal library has been removed Features: + * a new buffer pool management API has been added * a set of `Fn()` functions have been added -# 1.6.0 +## 1.6.0 + Fixes: + * end of line cleanup * revert the entry concurrency bug fix which leads to deadlock under some circumstances * update dependency on go-windows-terminal-sequences to fix a crash with go 1.14 Features: + * add an option to the `TextFormatter` to completely disable fields quoting -# 1.5.0 +## 1.5.0 + Code quality: + * add golangci linter run on travis Fixes: + * add mutex for hooks concurrent access on `Entry` data * caller function field for go1.14 * fix build issue for gopherjs target Feature: + * add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level * add a `DisableHTMLEscape` option in the `JSONFormatter` * add `ForceQuote` and `PadLevelText` options in the `TextFormatter` -# 1.4.2 +## 1.4.2 + * Fixes build break for plan9, nacl, solaris -# 1.4.1 + +## 1.4.1 + This new release introduces: + * Enhance TextFormatter to not print caller information when they are empty (#944) * Remove dependency on golang.org/x/crypto (#932, #943) Fixes: + * Fix Entry.WithContext method to return a copy of the initial entry (#941) -# 1.4.0 +## 1.4.0 + This new release introduces: + * Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848). * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911) * Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919). Fixes: + * Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893). * Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903) * Fix infinite recursion on unknown `Level.String()` (#907) * Fix race condition in `getCaller` (#916). -# 1.3.0 +## 1.3.0 + This new release introduces: + * Log, Logf, Logln functions for Logger and Entry that take a Level Fixes: + * Building prometheus node_exporter on AIX (#840) * Race condition in TextFormatter (#468) * Travis CI import path (#868) @@ -92,20 +255,26 @@ Fixes: * Pointer to func as field in JSONFormatter (#870) * Properly marshal Levels (#873) -# 1.2.0 +## 1.2.0 + This new release introduces: + * A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued * A new trace level named `Trace` whose level is below `Debug` * A configurable exit function to be called upon a Fatal trace * The `Level` object now implements `encoding.TextUnmarshaler` interface -# 1.1.1 +## 1.1.1 + This is a bug fix release. + * fix the build break on Solaris * don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized -# 1.1.0 +## 1.1.0 + This new release introduces: + * several fixes: * a fix for a race condition on entry formatting * proper cleanup of previously used entries before putting them back in the pool @@ -122,9 +291,10 @@ This new release introduces: * the field sort function is now configurable for text formatter * the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater -# 1.0.6 +## 1.0.6 This new release introduces: + * a new api WithTime which allows to easily force the time of the log entry which is mostly useful for logger wrapper * a fix reverting the immutability of the entry given as parameter to the hooks @@ -134,71 +304,71 @@ This new release introduces: * a new configuration of the textformatter to configure the name of the default keys * a new configuration of the text formatter to disable the level truncation -# 1.0.5 +## 1.0.5 * Fix hooks race (#707) * Fix panic deadlock (#695) -# 1.0.4 +## 1.0.4 * Fix race when adding hooks (#612) * Fix terminal check in AppEngine (#635) -# 1.0.3 +## 1.0.3 * Replace example files with testable examples -# 1.0.2 +## 1.0.2 * bug: quote non-string values in text formatter (#583) * Make (*Logger) SetLevel a public method -# 1.0.1 +## 1.0.1 * bug: fix escaping in text formatter (#575) -# 1.0.0 +## 1.0.0 * Officially changed name to lower-case * bug: colors on Windows 10 (#541) * bug: fix race in accessing level (#512) -# 0.11.5 +## 0.11.5 * feature: add writer and writerlevel to entry (#372) -# 0.11.4 +## 0.11.4 * bug: fix undefined variable on solaris (#493) -# 0.11.3 +## 0.11.3 * formatter: configure quoting of empty values (#484) * formatter: configure quoting character (default is `"`) (#484) * bug: fix not importing io correctly in non-linux environments (#481) -# 0.11.2 +## 0.11.2 * bug: fix windows terminal detection (#476) -# 0.11.1 +## 0.11.1 * bug: fix tty detection with custom out (#471) -# 0.11.0 +## 0.11.0 * performance: Use bufferpool to allocate (#370) * terminal: terminal detection for app-engine (#343) * feature: exit handler (#375) -# 0.10.0 +## 0.10.0 * feature: Add a test hook (#180) * feature: `ParseLevel` is now case-insensitive (#326) * feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308) * performance: avoid re-allocations on `WithFields` (#335) -# 0.9.0 +## 0.9.0 * logrus/text_formatter: don't emit empty msg * logrus/hooks/airbrake: move out of main repository @@ -210,25 +380,25 @@ This new release introduces: * logrus/core: support `WithError` on logger * logrus/core: Solaris support -# 0.8.7 +## 0.8.7 * logrus/core: fix possible race (#216) * logrus/doc: small typo fixes and doc improvements -# 0.8.6 +## 0.8.6 * hooks/raven: allow passing an initialized client -# 0.8.5 +## 0.8.5 * logrus/core: revert #208 -# 0.8.4 +## 0.8.4 * formatter/text: fix data race (#218) -# 0.8.3 +## 0.8.3 * logrus/core: fix entry log level (#208) * logrus/core: improve performance of text formatter by 40% @@ -236,24 +406,24 @@ This new release introduces: * logrus/core: add support for DragonflyBSD and NetBSD * formatter/text: print structs more verbosely -# 0.8.2 +## 0.8.2 * logrus: fix more Fatal family functions -# 0.8.1 +## 0.8.1 * logrus: fix not exiting on `Fatalf` and `Fatalln` -# 0.8.0 +## 0.8.0 * logrus: defaults to stderr instead of stdout * hooks/sentry: add special field for `*http.Request` * formatter/text: ignore Windows for colors -# 0.7.3 +## 0.7.3 * formatter/\*: allow configuration of timestamp layout -# 0.7.2 +## 0.7.2 * formatter/text: Add configuration option for time format (#158) diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md index cc5dab7e..b2ff7aff 100644 --- a/vendor/github.com/sirupsen/logrus/README.md +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -3,13 +3,10 @@ Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger. -**Logrus is in maintenance-mode.** We will not be introducing new features. It's -simply too hard to do in a way that won't break many people's projects, which is -the last thing you want from your Logging library (again...). - -This does not mean Logrus is dead. Logrus will continue to be maintained for -security, (backwards compatible) bug fixes, and performance (where we are -limited by the interface). +**Logrus is in maintenance mode.** The project focuses on security, bug fixes, +and performance improvements. New features are not planned, aside from changes +required to provide interoperability with other logging ecosystems (e.g., Go's +[log/slog](https://pkg.go.dev/log/slog)). I believe Logrus' biggest contribution is to have played a part in today's widespread use of structured logging in Golang. There doesn't seem to be a @@ -23,18 +20,6 @@ about structured logging in Go today. Check out, for example, [zap]: https://github.com/uber-go/zap [apex]: https://github.com/apex/log -**Seeing weird case-sensitive problems?** It's in the past been possible to -import Logrus as both upper- and lower-case. Due to the Go package environment, -this caused issues in the community and we needed a standard. Some environments -experienced problems with the upper-case variant, so the lower-case was decided. -Everything using `logrus` will need to use the lower-case: -`github.com/sirupsen/logrus`. Any package that isn't, should be changed. - -To fix Glide, see [these -comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). -For an in-depth explanation of the casing issue, see [this -comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276). - Nicely color-coded in development (when a TTY is attached, otherwise just plain text): @@ -43,35 +28,27 @@ plain text): With `logrus.SetFormatter(&logrus.JSONFormatter{})`, for easy parsing by logstash or Splunk: -```text -{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the -ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} - -{"level":"warning","msg":"The group's number increased tremendously!", -"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"A giant walrus appears!", -"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", -"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} - -{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, -"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} +```json lines +{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} +{"level":"warning","msg":"The group's number increased tremendously!","number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} +{"animal":"walrus","level":"info","msg":"A giant walrus appears!","size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} +{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.","size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} +{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} ``` With the default `logrus.SetFormatter(&logrus.TextFormatter{})` when a TTY is not attached, the output is compatible with the [logfmt](https://pkg.go.dev/github.com/kr/logfmt) format: -```text +```bash time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 -time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true +time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" animal=orca err="It's over 9000!" number=100 omg=true size=9009 ``` + To ensure this behaviour even if a TTY is attached, set your formatter as follows: ```go @@ -88,29 +65,32 @@ If you wish to add the calling method as a field, instruct the logger via: ```go logrus.SetReportCaller(true) ``` + This adds the caller as 'method' like so: ```json -{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by", -"time":"2014-03-10 19:57:38.562543129 -0400 EDT"} +{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by","time":"2014-03-10 19:57:38.562543129 -0400 EDT"} ``` -```text +```bash time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin ``` + Note that this does add measurable overhead - the cost will depend on the version of Go, but is between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your environment via benchmarks: ```bash -go test -bench=.*CallerTracing +go test -bench=ReportCaller ``` #### Case-sensitivity -The organization's name was changed to lower-case--and this will not be changed -back. If you are getting import conflicts due to case sensitivity, please use -the lower-case import: `github.com/sirupsen/logrus`. +The organization's name was [changed to lower-case][1]. If you are getting import +conflicts due to case sensitivity, please use the lower-case import: +`github.com/sirupsen/logrus`. + +[1]: https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276 #### Example @@ -289,6 +269,7 @@ func init() { } } ``` + Note: Syslog hooks also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) @@ -367,18 +348,21 @@ Splunk or Logstash. The built-in logging formatters are: -* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise - without colors. - * *Note:* to force colored output when there is no TTY, set the `ForceColors` +* [`logrus.TextFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter) + logs the event in colors if the logger output is a TTY, otherwise without colors. + * To force colored output when there is no TTY, set the `ForceColors` field to `true`. To force no colored output even if there is a TTY set the - `DisableColors` field to `true`. For Windows, see - [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). + `DisableColors` field to `true`. + * On modern Windows terminals with ANSI (Virtual Terminal) support, TextFormatter + automatically enables colored output. + * If your environment does not support ANSI escape sequences, wrap the logger output + using [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable) + and set `ForceColors` (or `CLICOLOR_FORCE=1`) to enable colors through the wrapper. * When colors are enabled, levels are truncated to 4 characters by default. To disable truncation set the `DisableLevelTruncation` field to `true`. * When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text. - * All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter). -* `logrus.JSONFormatter`. Logs fields as JSON. - * All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter). +* [`logrus.JSONFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter) + logs fields as JSON. Third-party logging formatters: @@ -390,10 +374,12 @@ Third-party logging formatters: * [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure. * [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Save log to files. * [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added. +* [`easy-logrus-formatter`](https://github.com/WeiZhixiong/easy-logrus-formatter). Provide a user-friendly formatter for logrus. +* [`redactrus`](https://github.com/ibreakthecloud/redactrus). Redacts sensitive information like password, apikeys, email, etc. from logs. You can define your formatter by implementing the `Formatter` interface, requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a -`Fields` type (`map[string]interface{}`) with all your fields as well as the +`Fields` type (`map[string]any`) with all your fields as well as the default ones (see Entries section above): ```go @@ -516,4 +502,4 @@ Situations when locking is not needed include: 2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing) - (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) + (Refer to ) diff --git a/vendor/github.com/sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go index 8fd189e1..1c35cf81 100644 --- a/vendor/github.com/sirupsen/logrus/alt_exit.go +++ b/vendor/github.com/sirupsen/logrus/alt_exit.go @@ -57,7 +57,7 @@ func Exit(code int) { // // This method is useful when a caller wishes to use logrus to log a fatal // message but also needs to gracefully shutdown. An example usecase could be -// closing database connections, or sending a alert that the application is +// closing database connections, or sending an alert that the application is // closing. func RegisterExitHandler(handler func()) { handlers = append(handlers, handler) @@ -69,7 +69,7 @@ func RegisterExitHandler(handler func()) { // // This method is useful when a caller wishes to use logrus to log a fatal // message but also needs to gracefully shutdown. An example usecase could be -// closing database connections, or sending a alert that the application is +// closing database connections, or sending an alert that the application is // closing. func DeferExitHandler(handler func()) { handlers = append([]func(){handler}, handlers...) diff --git a/vendor/github.com/sirupsen/logrus/buffer_pool.go b/vendor/github.com/sirupsen/logrus/buffer_pool.go index c7787f77..6b562d87 100644 --- a/vendor/github.com/sirupsen/logrus/buffer_pool.go +++ b/vendor/github.com/sirupsen/logrus/buffer_pool.go @@ -5,9 +5,13 @@ import ( "sync" ) -var ( - bufferPool BufferPool -) +var bufferPool BufferPool = &defaultPool{ + pool: &sync.Pool{ + New: func() any { + return new(bytes.Buffer) + }, + }, +} type BufferPool interface { Put(*bytes.Buffer) @@ -27,17 +31,7 @@ func (p *defaultPool) Get() *bytes.Buffer { } // SetBufferPool allows to replace the default logrus buffer pool -// to better meets the specific needs of an application. +// to better meet the specific needs of an application. func SetBufferPool(bp BufferPool) { bufferPool = bp } - -func init() { - SetBufferPool(&defaultPool{ - pool: &sync.Pool{ - New: func() interface{} { - return new(bytes.Buffer) - }, - }, - }) -} diff --git a/vendor/github.com/sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go index da67aba0..75186dc2 100644 --- a/vendor/github.com/sirupsen/logrus/doc.go +++ b/vendor/github.com/sirupsen/logrus/doc.go @@ -1,25 +1,25 @@ /* Package logrus is a structured logger for Go, completely API compatible with the standard library logger. - The simplest way to use Logrus is simply the package-level exported logger: - package main + package main - import ( - log "github.com/sirupsen/logrus" - ) + import ( + log "github.com/sirupsen/logrus" + ) - func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "number": 1, - "size": 10, - }).Info("A walrus appears") - } + func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "number": 1, + "size": 10, + }).Info("A walrus appears") + } Output: - time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 + + time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 For a full guide visit https://github.com/sirupsen/logrus */ diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go index 71d796d0..82de41f9 100644 --- a/vendor/github.com/sirupsen/logrus/entry.go +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -4,9 +4,11 @@ import ( "bytes" "context" "fmt" + "maps" "os" "reflect" "runtime" + "strconv" "strings" "sync" "time" @@ -17,8 +19,10 @@ var ( // qualified package name, cached at first use logrusPackage string - // Positions in the call stack when tracing to report the calling method - minimumCallerDepth int + // Positions in the call stack when tracing to report the calling method. + // + // Start at the bottom of the stack before the package-name cache is primed. + minimumCallerDepth = 1 // Used for caller information initialisation callerInitOnce sync.Once @@ -29,68 +33,116 @@ const ( knownLogrusFrames int = 4 ) -func init() { - // start at the bottom of the stack before the package-name cache is primed - minimumCallerDepth = 1 -} - // ErrorKey defines the key when adding errors using [WithError], [Logger.WithError]. var ErrorKey = "error" -// Entry is the final or intermediate Logrus logging entry. It contains all -// the fields passed with WithField{,s}. It's finally logged when Trace, Debug, -// Info, Warn, Error, Fatal or Panic is called on it. These objects can be -// reused and passed around as much as you wish to avoid field duplication. +// Entry represents a single log event. It may be either an intermediate +// entry (created via WithField(s), WithContext, etc.) or a final entry +// that is emitted when one of the level methods (Trace, Debug, Info, +// Warn, Error, Fatal, Panic) is called. // -//nolint:recvcheck // the methods of "Entry" use pointer receiver and non-pointer receiver. +// An Entry always belongs to a Logger. A nil Logger is invalid and will +// cause a panic when the entry is logged. Use [NewEntry] or Logger methods +// to construct entries. +// +// Entries are safe to reuse for adding fields and may be passed around +// to avoid field duplication. Each log operation operates on a copy +// of the Entry’s data to avoid mutation during formatting. +// +//nolint:recvcheck // Entry methods intentionally use both pointer and value receivers. type Entry struct { + // Logger is the Logger that owns this entry and is responsible for + // formatting, hooks, and output. It must not be nil. An Entry without + // a Logger is invalid and will panic when logged. Logger *Logger - // Contains all the fields set by the user. + // Data contains all user-defined fields attached to this entry. Data Fields - // Time at which the log entry was created + // Time is the timestamp for the log event. If zero when the entry is + // logged, it defaults to the current time. Time time.Time - // Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic - // This field will be set on entry firing and the value will be equal to the one in Logger struct field. + // Level is the severity of the log entry. It is set when the entry + // is fired and reflects the level used for that log call. Level Level - // Calling method, with package name + // Caller contains the calling method information. + // + // When [Logger.ReportCaller] is enabled, Caller is populated automatically at + // log time if it is nil. Hooks and formatters may inspect Caller. + // + // Applications generally should not modify Caller unless they intentionally + // want to provide custom caller information. Caller *runtime.Frame - // Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic + // Message is the log message supplied to one of the logging methods + // (Trace, Debug, Info, Warn, Error, Fatal, or Panic). It is set when + // the entry is logged. Message string - // When formatter is called in entry.log(), a Buffer may be set to entry + // Buffer is a reusable buffer provided to the formatter. It is set + // before formatting in the normal log path; when nil, formatters + // allocate their own. Buffer *bytes.Buffer - // Contains the context set by the user. Useful for hook processing etc. + // Context carries user-provided context for hooks and formatters. Context context.Context - // err may contain a field formatting error + // err contains internal field-formatting errors. err string } +// NewEntry creates a new [Entry] associated with the provided Logger. +// The logger must not be nil. Passing a nil logger results in a +// panic when a logging method (e.g., [Entry.Info], [Entry.Error], etc.) +// is called. func NewEntry(logger *Logger) *Entry { return &Entry{ Logger: logger, - // Default is three fields, plus one optional. Give a little extra room. - Data: make(Fields, 6), + // Reserve default predefined fields and a little extra room. + Data: make(Fields, defaultFields+3), } } +// Dup creates a copy of the entry for further modification. +// +// Data is cloned to avoid mutating the original entry. Other fields +// (Logger, Time, Context, etc.) are copied by value. func (entry *Entry) Dup() *Entry { - data := make(Fields, len(entry.Data)) - for k, v := range entry.Data { - data[k] = v + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + return dup +} + +// dup copies the entry fields shared by derived entries except Data, which +// callers must copy or initialize as appropriate for their use. +func (entry *Entry) dup() *Entry { + return &Entry{ + Logger: entry.Logger, + Time: entry.Time, + Caller: entry.Caller, + Context: entry.Context, + err: entry.err, } - return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err} } // Bytes returns the bytes representation of this entry from the formatter. func (entry *Entry) Bytes() ([]byte, error) { - return entry.Logger.Formatter.Format(entry) + // Snapshot the formatter under the lock to protect against concurrent + // SetFormatter calls, then release the lock before formatting. + // This avoids a data race and prevents a deadlock if Format() triggers + // reentrant logging (e.g., a field's MarshalJSON calls logrus). + // + // See: + // + // - https://github.com/sirupsen/logrus/issues/1440 + // - https://github.com/sirupsen/logrus/issues/1448 + entry.Logger.mu.Lock() + formatter := entry.Logger.Formatter + entry.Logger.mu.Unlock() + + return formatter.Format(entry) } // String returns the string representation from the reader and ultimately the @@ -112,58 +164,61 @@ func (entry *Entry) WithError(err error) *Entry { // WithContext adds a context to the Entry. func (entry *Entry) WithContext(ctx context.Context) *Entry { - dataCopy := make(Fields, len(entry.Data)) - for k, v := range entry.Data { - dataCopy[k] = v - } - return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx} + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + dup.Context = ctx + return dup } // WithField adds a single field to the Entry. -func (entry *Entry) WithField(key string, value interface{}) *Entry { - return entry.WithFields(Fields{key: value}) +func (entry *Entry) WithField(key string, value any) *Entry { + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + dup.addField(key, value) + return dup } // WithFields adds a map of fields to the Entry. func (entry *Entry) WithFields(fields Fields) *Entry { - data := make(Fields, len(entry.Data)+len(fields)) - for k, v := range entry.Data { - data[k] = v + dup := entry.dup() + dup.Data = make(Fields, len(entry.Data)+len(fields)) + maps.Copy(dup.Data, entry.Data) + + for key, value := range fields { + dup.addField(key, value) } - fieldErr := entry.err - for k, v := range fields { - isErrField := false - if t := reflect.TypeOf(v); t != nil { - switch { - case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func: - isErrField = true - } - } - if isErrField { - tmp := fmt.Sprintf("can not add field %q", k) - if fieldErr != "" { - fieldErr = entry.err + ", " + tmp + return dup +} + +// WithTime overrides the time of the Entry. +func (entry *Entry) WithTime(t time.Time) *Entry { + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + dup.Time = t + return dup +} + +func (entry *Entry) addField(key string, value any) { + if _, ok := value.(error); !ok { + t := reflect.TypeOf(value) + if t != nil && (t.Kind() == reflect.Func || t.Kind() == reflect.Pointer && t.Elem().Kind() == reflect.Func) { + if entry.err != "" { + entry.err += ", skipping unsupported field " + strconv.Quote(key) } else { - fieldErr = tmp + entry.err = "skipping unsupported field " + strconv.Quote(key) } - } else { - data[k] = v + return } } - return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context} -} -// WithTime overrides the time of the Entry. -func (entry *Entry) WithTime(t time.Time) *Entry { - dataCopy := make(Fields, len(entry.Data)) - for k, v := range entry.Data { - dataCopy[k] = v + if entry.Data == nil { + entry.Data = make(Fields, 1) } - return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context} + entry.Data[key] = value } // getPackageName reduces a fully qualified function name to the package name -// There really ought to be to be a better way... +// There really ought to be a better way... func getPackageName(f string) string { for { lastPeriod := strings.LastIndex(f, ".") @@ -186,7 +241,7 @@ func getCaller() *runtime.Frame { _ = runtime.Callers(0, pcs) // dynamic get the package name and the minimum caller depth - for i := 0; i < maximumCallerDepth; i++ { + for i := range maximumCallerDepth { funcName := runtime.FuncForPC(pcs[i]).Name() if strings.Contains(funcName, "getCaller") { logrusPackage = getPackageName(funcName) @@ -215,16 +270,47 @@ func getCaller() *runtime.Frame { return nil } -func (entry Entry) HasCaller() (has bool) { - return entry.Logger != nil && - entry.Logger.ReportCaller && - entry.Caller != nil +// HasCaller reports whether this Entry contains caller information. +// +// Caller may be set explicitly, or populated at log time when +// [Logger.ReportCaller] is enabled. +// +// Deprecated: use [Entry.Caller] != nil instead. +// +//go:fix inline +func (entry Entry) HasCaller() bool { + return entry.Caller != nil } -func (entry *Entry) log(level Level, msg string) { - var buffer *bytes.Buffer +func (entry *Entry) logArgs(level Level, panicAfter bool, args ...any) { + entry.log(level, panicAfter, sprint(args...)) +} - newEntry := entry.Dup() +func (entry *Entry) logf(level Level, panicAfter bool, format string, args ...any) { + entry.log(level, panicAfter, fmt.Sprintf(format, args...)) +} + +// logln uses Sprintln for multiple arguments to preserve Println-style +// spacing between args, then trims the trailing newline. +func (entry *Entry) logln(level Level, panicAfter bool, args ...any) { + if len(args) <= 1 { + entry.log(level, panicAfter, sprint(args...)) + return + } + msg := fmt.Sprintln(args...) + msg = msg[:len(msg)-1] // Trim the newline added by Sprintln; logging adds its own. + entry.log(level, panicAfter, msg) +} + +// log writes msg at level. If panicAfter is true, it panics with the fully +// populated entry after hooks and output have completed. +// +// The explicit flag keeps panic behavior limited to Panic, Panicf, and +// Panicln while avoiding a return value used only as the panic value. +// See #1283 and commits f96066e and 5f8c666. +func (entry *Entry) log(level Level, panicAfter bool, msg string) { + newEntry := entry.dup() + newEntry.Data = maps.Clone(entry.Data) if newEntry.Time.IsZero() { newEntry.Time = time.Now() @@ -233,17 +319,24 @@ func (entry *Entry) log(level Level, msg string) { newEntry.Level = level newEntry.Message = msg - newEntry.Logger.mu.Lock() - reportCaller := newEntry.Logger.ReportCaller + logger := newEntry.Logger + logger.mu.Lock() + reportCaller := logger.ReportCaller bufPool := newEntry.getBufferPool() - newEntry.Logger.mu.Unlock() + logger.mu.Unlock() - if reportCaller { + // Preserve explicitly set caller information. + if reportCaller && newEntry.Caller == nil { newEntry.Caller = getCaller() } - newEntry.fireHooks() - buffer = bufPool.Get() + // Select hooks based on the level for this log call. Hooks receive the + // Entry and may mutate it, but that does not affect which hooks are + // fired for this event. + hooks := logger.hooksForLevel(level) + newEntry.fireHooks(hooks) + + buffer := bufPool.Get() defer func() { newEntry.Buffer = nil buffer.Reset() @@ -251,15 +344,12 @@ func (entry *Entry) log(level Level, msg string) { }() buffer.Reset() newEntry.Buffer = buffer - newEntry.write() - newEntry.Buffer = nil - // To avoid Entry#log() returning a value that only would make sense for - // panic() to use in Entry#Panic(), we avoid the allocation by checking - // directly here. - if level <= PanicLevel { + // Panic here so the panic value contains the fully populated entry without + // requiring log to return it to the caller. + if panicAfter { panic(newEntry) } } @@ -271,175 +361,207 @@ func (entry *Entry) getBufferPool() (pool BufferPool) { return bufferPool } -func (entry *Entry) fireHooks() { - var tmpHooks LevelHooks - entry.Logger.mu.Lock() - tmpHooks = make(LevelHooks, len(entry.Logger.Hooks)) - for k, v := range entry.Logger.Hooks { - tmpHooks[k] = v - } - entry.Logger.mu.Unlock() - - err := tmpHooks.Fire(entry.Level, entry) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) +func (entry *Entry) fireHooks(hooks []Hook) { + for _, hook := range hooks { + if err := hook.Fire(entry); err != nil { + _, _ = fmt.Fprintln(os.Stderr, "Failed to fire hook:", err) + return + } } } func (entry *Entry) write() { + // Snapshot the formatter under the lock to protect against concurrent + // SetFormatter calls, then release the lock before formatting. + // This avoids a deadlock when Format() triggers reentrant logging (e.g., + // a field's MarshalJSON calls logrus). See #1448, #1440. entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() - serialized, err := entry.Logger.Formatter.Format(entry) + formatter := entry.Logger.Formatter + entry.Logger.mu.Unlock() + + serialized, err := formatter.Format(entry) if err != nil { - fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + _, _ = fmt.Fprintln(os.Stderr, "Failed to format entry:", err) return } + + // Re-acquire the lock to serialize writes to the underlying io.Writer. + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() if _, err := entry.Logger.Out.Write(serialized); err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + _, _ = fmt.Fprintln(os.Stderr, "Failed to write to log:", err) } } -// Log will log a message at the level given as parameter. -// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. -// For this behaviour Entry.Panic or Entry.Fatal should be used instead. -func (entry *Entry) Log(level Level, args ...interface{}) { +// Log logs a message at the specified level. +// +// Using Log with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Log treats the level as logging severity only; +// use [Entry.Panic] or [Entry.Fatal] when those side effects are desired. +func (entry *Entry) Log(level Level, args ...any) { + const panicAfter = false if entry.Logger.IsLevelEnabled(level) { - entry.log(level, fmt.Sprint(args...)) + entry.logArgs(level, panicAfter, args...) } } -func (entry *Entry) Trace(args ...interface{}) { +func (entry *Entry) Trace(args ...any) { entry.Log(TraceLevel, args...) } -func (entry *Entry) Debug(args ...interface{}) { +func (entry *Entry) Debug(args ...any) { entry.Log(DebugLevel, args...) } -func (entry *Entry) Print(args ...interface{}) { +func (entry *Entry) Print(args ...any) { entry.Info(args...) } -func (entry *Entry) Info(args ...interface{}) { +func (entry *Entry) Info(args ...any) { entry.Log(InfoLevel, args...) } -func (entry *Entry) Warn(args ...interface{}) { +func (entry *Entry) Warn(args ...any) { entry.Log(WarnLevel, args...) } -func (entry *Entry) Warning(args ...interface{}) { +func (entry *Entry) Warning(args ...any) { entry.Warn(args...) } -func (entry *Entry) Error(args ...interface{}) { +func (entry *Entry) Error(args ...any) { entry.Log(ErrorLevel, args...) } -func (entry *Entry) Fatal(args ...interface{}) { +func (entry *Entry) Fatal(args ...any) { entry.Log(FatalLevel, args...) entry.Logger.Exit(1) } -func (entry *Entry) Panic(args ...interface{}) { - entry.Log(PanicLevel, args...) +func (entry *Entry) Panic(args ...any) { + const panicAfter = true + if entry.Logger.IsLevelEnabled(PanicLevel) { + entry.logArgs(PanicLevel, panicAfter, args...) + } } // Entry Printf family functions -func (entry *Entry) Logf(level Level, format string, args ...interface{}) { +// Logf logs a formatted message at the specified level. +// +// Using Logf with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logf treats the level as logging severity only; +// use [Entry.Panicf] or [Entry.Fatalf] when those side effects are desired. +func (entry *Entry) Logf(level Level, format string, args ...any) { + const panicAfter = false if entry.Logger.IsLevelEnabled(level) { - entry.Log(level, fmt.Sprintf(format, args...)) + entry.logf(level, panicAfter, format, args...) } } -func (entry *Entry) Tracef(format string, args ...interface{}) { +func (entry *Entry) Tracef(format string, args ...any) { entry.Logf(TraceLevel, format, args...) } -func (entry *Entry) Debugf(format string, args ...interface{}) { +func (entry *Entry) Debugf(format string, args ...any) { entry.Logf(DebugLevel, format, args...) } -func (entry *Entry) Infof(format string, args ...interface{}) { +func (entry *Entry) Infof(format string, args ...any) { entry.Logf(InfoLevel, format, args...) } -func (entry *Entry) Printf(format string, args ...interface{}) { +func (entry *Entry) Printf(format string, args ...any) { entry.Infof(format, args...) } -func (entry *Entry) Warnf(format string, args ...interface{}) { +func (entry *Entry) Warnf(format string, args ...any) { entry.Logf(WarnLevel, format, args...) } -func (entry *Entry) Warningf(format string, args ...interface{}) { +func (entry *Entry) Warningf(format string, args ...any) { entry.Warnf(format, args...) } -func (entry *Entry) Errorf(format string, args ...interface{}) { +func (entry *Entry) Errorf(format string, args ...any) { entry.Logf(ErrorLevel, format, args...) } -func (entry *Entry) Fatalf(format string, args ...interface{}) { +func (entry *Entry) Fatalf(format string, args ...any) { entry.Logf(FatalLevel, format, args...) entry.Logger.Exit(1) } -func (entry *Entry) Panicf(format string, args ...interface{}) { - entry.Logf(PanicLevel, format, args...) +func (entry *Entry) Panicf(format string, args ...any) { + const panicAfter = true + if entry.Logger.IsLevelEnabled(PanicLevel) { + entry.logf(PanicLevel, panicAfter, format, args...) + } } // Entry Println family functions -func (entry *Entry) Logln(level Level, args ...interface{}) { +// Logln logs a message at the specified level with Println-style spacing. +// +// Using Logln with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logln treats the level as logging severity only; +// use [Entry.Panicln] or [Entry.Fatalln] when those side effects are desired. +func (entry *Entry) Logln(level Level, args ...any) { + const panicAfter = false if entry.Logger.IsLevelEnabled(level) { - entry.Log(level, entry.sprintlnn(args...)) + entry.logln(level, panicAfter, args...) } } -func (entry *Entry) Traceln(args ...interface{}) { +func (entry *Entry) Traceln(args ...any) { entry.Logln(TraceLevel, args...) } -func (entry *Entry) Debugln(args ...interface{}) { +func (entry *Entry) Debugln(args ...any) { entry.Logln(DebugLevel, args...) } -func (entry *Entry) Infoln(args ...interface{}) { +func (entry *Entry) Infoln(args ...any) { entry.Logln(InfoLevel, args...) } -func (entry *Entry) Println(args ...interface{}) { +func (entry *Entry) Println(args ...any) { entry.Infoln(args...) } -func (entry *Entry) Warnln(args ...interface{}) { +func (entry *Entry) Warnln(args ...any) { entry.Logln(WarnLevel, args...) } -func (entry *Entry) Warningln(args ...interface{}) { +func (entry *Entry) Warningln(args ...any) { entry.Warnln(args...) } -func (entry *Entry) Errorln(args ...interface{}) { +func (entry *Entry) Errorln(args ...any) { entry.Logln(ErrorLevel, args...) } -func (entry *Entry) Fatalln(args ...interface{}) { +func (entry *Entry) Fatalln(args ...any) { entry.Logln(FatalLevel, args...) entry.Logger.Exit(1) } -func (entry *Entry) Panicln(args ...interface{}) { - entry.Logln(PanicLevel, args...) +func (entry *Entry) Panicln(args ...any) { + const panicAfter = true + if entry.Logger.IsLevelEnabled(PanicLevel) { + entry.logln(PanicLevel, panicAfter, args...) + } } -// sprintlnn => Sprint no newline. This is to get the behavior of how -// fmt.Sprintln where spaces are always added between operands, regardless of -// their type. Instead of vendoring the Sprintln implementation to spare a -// string allocation, we do the simplest thing. -func (entry *Entry) sprintlnn(args ...interface{}) string { - msg := fmt.Sprintln(args...) - return msg[:len(msg)-1] +// sprint is fmt.Sprint with fast paths for zero or one string argument. +func sprint(args ...any) string { + switch len(args) { + case 0: + return "" + case 1: + if msg, ok := args[0].(string); ok { + return msg + } + } + return fmt.Sprint(args...) } diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go index 017c30ce..8b261c12 100644 --- a/vendor/github.com/sirupsen/logrus/exported.go +++ b/vendor/github.com/sirupsen/logrus/exported.go @@ -6,11 +6,12 @@ import ( "time" ) -var ( - // std is the name of the standard logger in stdlib `log` - std = New() -) +// std is the package-level standard logger, similar to the default logger +// in the stdlib [log] package. +var std = New() +// StandardLogger returns the package-level standard logger used by +// the top-level logging functions. func StandardLogger() *Logger { return std } @@ -41,7 +42,7 @@ func GetLevel() Level { return std.GetLevel() } -// IsLevelEnabled checks if the log level of the standard logger is greater than the level param +// IsLevelEnabled checks if logging for the given level is enabled for the standard logger. func IsLevelEnabled(level Level) bool { return std.IsLevelEnabled(level) } @@ -51,9 +52,10 @@ func AddHook(hook Hook) { std.AddHook(hook) } -// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +// WithError creates an entry from the standard logger and adds an error to it, +// using the value defined in [ErrorKey] as key. func WithError(err error) *Entry { - return std.WithField(ErrorKey, err) + return std.WithError(err) } // WithContext creates an entry from the standard logger and adds a context to it. @@ -61,210 +63,203 @@ func WithContext(ctx context.Context) *Entry { return std.WithContext(ctx) } -// WithField creates an entry from the standard logger and adds a field to -// it. If you want multiple fields, use `WithFields`. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. -func WithField(key string, value interface{}) *Entry { +// WithField creates an entry from the standard logger and adds a single field. +// For multiple fields, prefer [WithFields] over chaining WithField calls. +func WithField(key string, value any) *Entry { return std.WithField(key, value) } -// WithFields creates an entry from the standard logger and adds multiple -// fields to it. This is simply a helper for `WithField`, invoking it -// once for each field. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. +// WithFields creates an entry from the standard logger and adds the fields to it. func WithFields(fields Fields) *Entry { return std.WithFields(fields) } -// WithTime creates an entry from the standard logger and overrides the time of -// logs generated with it. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. +// WithTime creates an entry from the standard logger and overrides the time +// used for logs generated with it. func WithTime(t time.Time) *Entry { return std.WithTime(t) } -// Trace logs a message at level Trace on the standard logger. -func Trace(args ...interface{}) { +// Trace logs a message at level [TraceLevel] on the standard logger. +func Trace(args ...any) { std.Trace(args...) } -// Debug logs a message at level Debug on the standard logger. -func Debug(args ...interface{}) { +// Debug logs a message at level [DebugLevel] on the standard logger. +func Debug(args ...any) { std.Debug(args...) } -// Print logs a message at level Info on the standard logger. -func Print(args ...interface{}) { +// Print logs a message at level [InfoLevel] on the standard logger. +func Print(args ...any) { std.Print(args...) } -// Info logs a message at level Info on the standard logger. -func Info(args ...interface{}) { +// Info logs a message at level [InfoLevel] on the standard logger. +func Info(args ...any) { std.Info(args...) } -// Warn logs a message at level Warn on the standard logger. -func Warn(args ...interface{}) { +// Warn logs a message at level [WarnLevel] on the standard logger. +func Warn(args ...any) { std.Warn(args...) } -// Warning logs a message at level Warn on the standard logger. -func Warning(args ...interface{}) { +// Warning logs a message at level [WarnLevel] on the standard logger. +func Warning(args ...any) { std.Warning(args...) } -// Error logs a message at level Error on the standard logger. -func Error(args ...interface{}) { +// Error logs a message at level [ErrorLevel] on the standard logger. +func Error(args ...any) { std.Error(args...) } -// Panic logs a message at level Panic on the standard logger. -func Panic(args ...interface{}) { +// Panic logs a message at level [PanicLevel] on the standard logger. +func Panic(args ...any) { std.Panic(args...) } -// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1. -func Fatal(args ...interface{}) { +// Fatal logs a message at level [FatalLevel] on the standard logger, +// then exits the process with status 1. +func Fatal(args ...any) { std.Fatal(args...) } -// TraceFn logs a message from a func at level Trace on the standard logger. +// TraceFn logs a message from a func at level [TraceLevel] on the standard logger. func TraceFn(fn LogFunction) { std.TraceFn(fn) } -// DebugFn logs a message from a func at level Debug on the standard logger. +// DebugFn logs a message from a func at level [DebugLevel] on the standard logger. func DebugFn(fn LogFunction) { std.DebugFn(fn) } -// PrintFn logs a message from a func at level Info on the standard logger. +// PrintFn logs a message from a func at level [InfoLevel] on the standard logger. func PrintFn(fn LogFunction) { std.PrintFn(fn) } -// InfoFn logs a message from a func at level Info on the standard logger. +// InfoFn logs a message from a func at level [InfoLevel] on the standard logger. func InfoFn(fn LogFunction) { std.InfoFn(fn) } -// WarnFn logs a message from a func at level Warn on the standard logger. +// WarnFn logs a message from a func at level [WarnLevel] on the standard logger. func WarnFn(fn LogFunction) { std.WarnFn(fn) } -// WarningFn logs a message from a func at level Warn on the standard logger. +// WarningFn logs a message from a func at level [WarnLevel] on the standard logger. func WarningFn(fn LogFunction) { std.WarningFn(fn) } -// ErrorFn logs a message from a func at level Error on the standard logger. +// ErrorFn logs a message from a func at level [ErrorLevel] on the standard logger. func ErrorFn(fn LogFunction) { std.ErrorFn(fn) } -// PanicFn logs a message from a func at level Panic on the standard logger. +// PanicFn logs a message from a func at level [PanicLevel] on the standard logger. func PanicFn(fn LogFunction) { std.PanicFn(fn) } -// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1. +// FatalFn logs a message from a func at level [FatalLevel] on the standard logger, +// then exits the process with status 1. func FatalFn(fn LogFunction) { std.FatalFn(fn) } -// Tracef logs a message at level Trace on the standard logger. -func Tracef(format string, args ...interface{}) { +// Tracef logs a message at level [TraceLevel] on the standard logger. +func Tracef(format string, args ...any) { std.Tracef(format, args...) } -// Debugf logs a message at level Debug on the standard logger. -func Debugf(format string, args ...interface{}) { +// Debugf logs a message at level [DebugLevel] on the standard logger. +func Debugf(format string, args ...any) { std.Debugf(format, args...) } -// Printf logs a message at level Info on the standard logger. -func Printf(format string, args ...interface{}) { +// Printf logs a message at level [InfoLevel] on the standard logger. +func Printf(format string, args ...any) { std.Printf(format, args...) } -// Infof logs a message at level Info on the standard logger. -func Infof(format string, args ...interface{}) { +// Infof logs a message at level [InfoLevel] on the standard logger. +func Infof(format string, args ...any) { std.Infof(format, args...) } -// Warnf logs a message at level Warn on the standard logger. -func Warnf(format string, args ...interface{}) { +// Warnf logs a message at level [WarnLevel] on the standard logger. +func Warnf(format string, args ...any) { std.Warnf(format, args...) } -// Warningf logs a message at level Warn on the standard logger. -func Warningf(format string, args ...interface{}) { +// Warningf logs a message at level [WarnLevel] on the standard logger. +func Warningf(format string, args ...any) { std.Warningf(format, args...) } -// Errorf logs a message at level Error on the standard logger. -func Errorf(format string, args ...interface{}) { +// Errorf logs a message at level [ErrorLevel] on the standard logger. +func Errorf(format string, args ...any) { std.Errorf(format, args...) } -// Panicf logs a message at level Panic on the standard logger. -func Panicf(format string, args ...interface{}) { +// Panicf logs a message at level [PanicLevel] on the standard logger. +func Panicf(format string, args ...any) { std.Panicf(format, args...) } -// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1. -func Fatalf(format string, args ...interface{}) { +// Fatalf logs a message at level [FatalLevel] on the standard logger, +// then exits the process with status 1. +func Fatalf(format string, args ...any) { std.Fatalf(format, args...) } -// Traceln logs a message at level Trace on the standard logger. -func Traceln(args ...interface{}) { +// Traceln logs a message at level [TraceLevel] on the standard logger. +func Traceln(args ...any) { std.Traceln(args...) } -// Debugln logs a message at level Debug on the standard logger. -func Debugln(args ...interface{}) { +// Debugln logs a message at level [DebugLevel] on the standard logger. +func Debugln(args ...any) { std.Debugln(args...) } -// Println logs a message at level Info on the standard logger. -func Println(args ...interface{}) { +// Println logs a message at level [InfoLevel] on the standard logger. +func Println(args ...any) { std.Println(args...) } -// Infoln logs a message at level Info on the standard logger. -func Infoln(args ...interface{}) { +// Infoln logs a message at level [InfoLevel] on the standard logger. +func Infoln(args ...any) { std.Infoln(args...) } -// Warnln logs a message at level Warn on the standard logger. -func Warnln(args ...interface{}) { +// Warnln logs a message at level [WarnLevel] on the standard logger. +func Warnln(args ...any) { std.Warnln(args...) } -// Warningln logs a message at level Warn on the standard logger. -func Warningln(args ...interface{}) { +// Warningln logs a message at level [WarnLevel] on the standard logger. +func Warningln(args ...any) { std.Warningln(args...) } -// Errorln logs a message at level Error on the standard logger. -func Errorln(args ...interface{}) { +// Errorln logs a message at level [ErrorLevel] on the standard logger. +func Errorln(args ...any) { std.Errorln(args...) } -// Panicln logs a message at level Panic on the standard logger. -func Panicln(args ...interface{}) { +// Panicln logs a message at level [PanicLevel] on the standard logger. +func Panicln(args ...any) { std.Panicln(args...) } -// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1. -func Fatalln(args ...interface{}) { +// Fatalln logs a message at level [FatalLevel] on the standard logger, +// then exits the process with status 1. +func Fatalln(args ...any) { std.Fatalln(args...) } diff --git a/vendor/github.com/sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go index 40888377..16f2e0e0 100644 --- a/vendor/github.com/sirupsen/logrus/formatter.go +++ b/vendor/github.com/sirupsen/logrus/formatter.go @@ -2,27 +2,40 @@ package logrus import "time" -// Default key names for the default fields const ( + // defaultTimestampFormat is the layout used to format entry timestamps + // when a formatter has not specified a custom TimestampFormat. + // It follows time.RFC3339 and is applied unless timestamps are disabled. defaultTimestampFormat = time.RFC3339 - FieldKeyMsg = "msg" - FieldKeyLevel = "level" - FieldKeyTime = "time" - FieldKeyLogrusError = "logrus_error" - FieldKeyFunc = "func" - FieldKeyFile = "file" + + // defaultFields is the number of commonly included predefined log entry fields + // (msg, level, time). It is used as a capacity hint when constructing + // intermediate collections during formatting (for example, the fixed key list). + // + // It does not include the optional "logrus_error", "func", or "file" fields. + defaultFields = 3 +) + +// Default key names for the default fields +const ( + FieldKeyMsg = "msg" + FieldKeyLevel = "level" + FieldKeyTime = "time" + FieldKeyLogrusError = "logrus_error" + FieldKeyFunc = "func" + FieldKeyFile = "file" ) -// The Formatter interface is used to implement a custom Formatter. It takes an -// `Entry`. It exposes all the fields, including the default ones: +// Formatter is implemented by types that format log entries. It receives an +// [*Entry], which contains: // -// * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. -// * `entry.Data["time"]`. The timestamp. -// * `entry.Data["level"]. The level the entry was logged at. +// - entry.Message: the message passed to logging methods such as [Info], [Warn], [Error] +// - entry.Time: the timestamp +// - entry.Level: the log level // -// Any additional fields added with `WithField` or `WithFields` are also in -// `entry.Data`. Format is expected to return an array of bytes which are then -// logged to `logger.Out`. +// Additional fields added with [WithField] or [WithFields] are available in +// [Entry.Data]. Format should return the formatted log entry as a byte slice, +// which is written to [Logger.Out]. type Formatter interface { Format(*Entry) ([]byte, error) } @@ -30,12 +43,12 @@ type Formatter interface { // This is to not silently overwrite `time`, `msg`, `func` and `level` fields when // dumping it. If this code wasn't there doing: // -// logrus.WithField("level", 1).Info("hello") +// logrus.WithField("level", 1).Info("hello") // // Would just silently drop the user provided level. Instead with this code // it'll logged as: // -// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} +// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} // // It's not exported because it's still using Data in an opinionated way. It's to // avoid code duplication between the two default formatters. diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go index c96dc563..fac7695e 100644 --- a/vendor/github.com/sirupsen/logrus/json_formatter.go +++ b/vendor/github.com/sirupsen/logrus/json_formatter.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "runtime" + "strconv" ) type fieldKey string @@ -20,7 +21,13 @@ func (f FieldMap) resolve(key fieldKey) string { return string(key) } -// JSONFormatter formats logs into parsable json +// JSONFormatter formats logs into parsable JSON. +// +// Fields from [Entry.Data] are included in the JSON object together with the +// standard fields derived from the entry. If a field conflicts with a standard +// field, it is prefixed with "fields.". Standard field names can be customized +// through FieldMap. When DataKey is set, fields from [Entry.Data] are nested +// under that key instead. type JSONFormatter struct { // TimestampFormat sets the format used for marshaling timestamps. // The format to use is the same than for time.Format or time.Parse from the standard @@ -61,7 +68,8 @@ type JSONFormatter struct { // Format renders a single log entry func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - data := make(Fields, len(entry.Data)+4) + caller := entry.Caller + data := make(Fields, len(entry.Data)+defaultFields) for k, v := range entry.Data { switch v := v.(type) { case error: @@ -73,13 +81,14 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { } } - if f.DataKey != "" { - newData := make(Fields, 4) + if f.DataKey != "" && len(entry.Data) > 0 { + newData := make(Fields, defaultFields+1) newData[f.DataKey] = data data = newData } - prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + hasCaller := caller != nil + prefixFieldClashes(data, f.FieldMap, hasCaller) timestampFormat := f.TimestampFormat if timestampFormat == "" { @@ -94,11 +103,13 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { } data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() - if entry.HasCaller() { - funcVal := entry.Caller.Function - fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) + if caller != nil { + var funcVal, fileVal string if f.CallerPrettyfier != nil { - funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + funcVal, fileVal = f.CallerPrettyfier(caller) + } else { + funcVal = caller.Function + fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10) } if funcVal != "" { data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal @@ -108,11 +119,9 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { } } - var b *bytes.Buffer - if entry.Buffer != nil { - b = entry.Buffer - } else { - b = &bytes.Buffer{} + b := entry.Buffer + if b == nil { + b = new(bytes.Buffer) } encoder := json.NewEncoder(b) diff --git a/vendor/github.com/sirupsen/logrus/level.go b/vendor/github.com/sirupsen/logrus/level.go new file mode 100644 index 00000000..7bd4255d --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/level.go @@ -0,0 +1,101 @@ +package logrus + +import ( + "strings" + "sync" +) + +const ( + ansiReset = "\x1b[0m" // reset attributes + ansiRed = "\x1b[31m" // red + ansiYellow = "\x1b[33m" // yellow + ansiCyan = "\x1b[36m" // cyan + ansiDimCyan = "\x1b[2;36m" // dim cyan + ansiDimWhite = "\x1b[2;37m" // dim white (light gray) +) + +type lvlPrefix struct { + full string + truncated string + padded string +} + +func colorize(level Level, s string) string { + color := ansiCyan + switch level { + case TraceLevel: + color = ansiDimWhite + case DebugLevel: + color = ansiDimCyan + case WarnLevel: + color = ansiYellow + case ErrorLevel, FatalLevel, PanicLevel: + color = ansiRed + case InfoLevel: + color = ansiCyan + } + return color + s + ansiReset +} + +func formatLevel(level Level, disableTrunc, pad bool, maxLen int) string { + upper := strings.ToUpper(level.String()) + + if pad && maxLen > len(upper) { + upper += strings.Repeat(" ", maxLen-len(upper)) + } + + if !pad && !disableTrunc && len(upper) > 4 { + upper = upper[:4] + } + + return colorize(level, upper) +} + +var levelPrefixOnce = sync.OnceValues(func() (map[Level]lvlPrefix, lvlPrefix) { + var maxLevel Level + maxLen := 0 + for _, lvl := range AllLevels { + if lvl > maxLevel { + maxLevel = lvl + } + if l := len(lvl.String()); l > maxLen { + maxLen = l + } + } + + prefix := make(map[Level]lvlPrefix, len(AllLevels)) + for _, lvl := range AllLevels { + prefix[lvl] = lvlPrefix{ + full: formatLevel(lvl, true, false, maxLen), + truncated: formatLevel(lvl, false, false, maxLen), + padded: formatLevel(lvl, true, true, maxLen), + } + } + + unknownLevel := maxLevel + 1 + unknown := lvlPrefix{ + full: formatLevel(unknownLevel, true, false, maxLen), + truncated: formatLevel(unknownLevel, false, false, maxLen), + padded: formatLevel(unknownLevel, true, true, maxLen), + } + + return prefix, unknown +}) + +func levelPrefix(level Level, disableTrunc, pad bool) string { + prefix, unknown := levelPrefixOnce() + + p, ok := prefix[level] + if !ok { + p = unknown + } + + switch { + case pad: + return p.padded + case !disableTrunc: + return p.truncated + default: + return p.full + } +} diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go index f5b8c439..17a46e6a 100644 --- a/vendor/github.com/sirupsen/logrus/logger.go +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -12,17 +12,19 @@ import ( // LogFunction For big messages, it can be more efficient to pass a function // and only call it if the log level is actually enables rather than // generating the log message and then checking if the level is enabled -type LogFunction func() []interface{} +type LogFunction func() []any type Logger struct { // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a // file, or leave it default which is `os.Stderr`. You can also set this to // something more adventurous, such as logging to Kafka. Out io.Writer + // Hooks for the logger instance. These allow firing events based on logging // levels and log entries. For example, to send errors to an error tracking // service, log to StatsD or dump the core on fatal errors. Hooks LevelHooks + // All log entries pass through the formatter before logged to Out. The // included formatters are `TextFormatter` and `JSONFormatter` for which // TextFormatter is the default. In development (when a TTY is attached) it @@ -38,37 +40,44 @@ type Logger struct { // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be // logged. Level Level + // Used to sync writing to the log. Locking is enabled by Default - mu MutexWrap + mu mutexWrap + // Reusable empty entry entryPool sync.Pool + // Function to exit the application, defaults to `os.Exit()` - ExitFunc exitFunc + ExitFunc func(int) + // The buffer pool used to format the log. If it is nil, the default global // buffer pool will be used. BufferPool BufferPool } -type exitFunc func(int) +// MutexWrap is the mutex implementation used by [Logger]. +// +// Deprecated: MutexWrap is an implementation detail of Logger and should not be used directly. +type MutexWrap = mutexWrap -type MutexWrap struct { +type mutexWrap struct { lock sync.Mutex disabled bool } -func (mw *MutexWrap) Lock() { +func (mw *mutexWrap) Lock() { if !mw.disabled { mw.lock.Lock() } } -func (mw *MutexWrap) Unlock() { +func (mw *mutexWrap) Unlock() { if !mw.disabled { mw.lock.Unlock() } } -func (mw *MutexWrap) Disable() { +func (mw *mutexWrap) Disable() { mw.disabled = true } @@ -104,7 +113,7 @@ func (logger *Logger) newEntry() *Entry { } func (logger *Logger) releaseEntry(entry *Entry) { - entry.Data = map[string]interface{}{} + entry.Data = map[string]any{} logger.entryPool.Put(entry) } @@ -112,7 +121,7 @@ func (logger *Logger) releaseEntry(entry *Entry) { // Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to // this new returned entry. // If you want multiple fields, use `WithFields`. -func (logger *Logger) WithField(key string, value interface{}) *Entry { +func (logger *Logger) WithField(key string, value any) *Entry { entry := logger.newEntry() defer logger.releaseEntry(entry) return entry.WithField(key, value) @@ -148,7 +157,12 @@ func (logger *Logger) WithTime(t time.Time) *Entry { return entry.WithTime(t) } -func (logger *Logger) Logf(level Level, format string, args ...interface{}) { +// Logf logs a formatted message at the specified level. +// +// Using Logf with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logf treats the level as logging severity only; +// use [Logger.Panicf] or [Logger.Fatalf] when those side effects are desired. +func (logger *Logger) Logf(level Level, format string, args ...any) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() entry.Logf(level, format, args...) @@ -156,49 +170,55 @@ func (logger *Logger) Logf(level Level, format string, args ...interface{}) { } } -func (logger *Logger) Tracef(format string, args ...interface{}) { +func (logger *Logger) Tracef(format string, args ...any) { logger.Logf(TraceLevel, format, args...) } -func (logger *Logger) Debugf(format string, args ...interface{}) { +func (logger *Logger) Debugf(format string, args ...any) { logger.Logf(DebugLevel, format, args...) } -func (logger *Logger) Infof(format string, args ...interface{}) { +func (logger *Logger) Infof(format string, args ...any) { logger.Logf(InfoLevel, format, args...) } -func (logger *Logger) Printf(format string, args ...interface{}) { +func (logger *Logger) Printf(format string, args ...any) { entry := logger.newEntry() entry.Printf(format, args...) logger.releaseEntry(entry) } -func (logger *Logger) Warnf(format string, args ...interface{}) { +func (logger *Logger) Warnf(format string, args ...any) { logger.Logf(WarnLevel, format, args...) } -func (logger *Logger) Warningf(format string, args ...interface{}) { +func (logger *Logger) Warningf(format string, args ...any) { logger.Warnf(format, args...) } -func (logger *Logger) Errorf(format string, args ...interface{}) { +func (logger *Logger) Errorf(format string, args ...any) { logger.Logf(ErrorLevel, format, args...) } -func (logger *Logger) Fatalf(format string, args ...interface{}) { +func (logger *Logger) Fatalf(format string, args ...any) { logger.Logf(FatalLevel, format, args...) logger.Exit(1) } -func (logger *Logger) Panicf(format string, args ...interface{}) { - logger.Logf(PanicLevel, format, args...) +func (logger *Logger) Panicf(format string, args ...any) { + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panicf(format, args...) + } } -// Log will log a message at the level given as parameter. -// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. -// For this behaviour Logger.Panic or Logger.Fatal should be used instead. -func (logger *Logger) Log(level Level, args ...interface{}) { +// Log logs a message at the specified level. +// +// Using Log with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Log treats the level as logging severity only; +// use [Logger.Panic] or [Logger.Fatal] when those side effects are desired. +func (logger *Logger) Log(level Level, args ...any) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() entry.Log(level, args...) @@ -206,6 +226,11 @@ func (logger *Logger) Log(level Level, args ...interface{}) { } } +// LogFn logs a message returned by fn at the specified level. +// +// Using LogFn with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. LogFn treats the level as logging severity only; +// use [Logger.PanicFn] or [Logger.FatalFn] when those side effects are desired. func (logger *Logger) LogFn(level Level, fn LogFunction) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() @@ -214,43 +239,47 @@ func (logger *Logger) LogFn(level Level, fn LogFunction) { } } -func (logger *Logger) Trace(args ...interface{}) { +func (logger *Logger) Trace(args ...any) { logger.Log(TraceLevel, args...) } -func (logger *Logger) Debug(args ...interface{}) { +func (logger *Logger) Debug(args ...any) { logger.Log(DebugLevel, args...) } -func (logger *Logger) Info(args ...interface{}) { +func (logger *Logger) Info(args ...any) { logger.Log(InfoLevel, args...) } -func (logger *Logger) Print(args ...interface{}) { +func (logger *Logger) Print(args ...any) { entry := logger.newEntry() entry.Print(args...) logger.releaseEntry(entry) } -func (logger *Logger) Warn(args ...interface{}) { +func (logger *Logger) Warn(args ...any) { logger.Log(WarnLevel, args...) } -func (logger *Logger) Warning(args ...interface{}) { +func (logger *Logger) Warning(args ...any) { logger.Warn(args...) } -func (logger *Logger) Error(args ...interface{}) { +func (logger *Logger) Error(args ...any) { logger.Log(ErrorLevel, args...) } -func (logger *Logger) Fatal(args ...interface{}) { +func (logger *Logger) Fatal(args ...any) { logger.Log(FatalLevel, args...) logger.Exit(1) } -func (logger *Logger) Panic(args ...interface{}) { - logger.Log(PanicLevel, args...) +func (logger *Logger) Panic(args ...any) { + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panic(args...) + } } func (logger *Logger) TraceFn(fn LogFunction) { @@ -289,10 +318,19 @@ func (logger *Logger) FatalFn(fn LogFunction) { } func (logger *Logger) PanicFn(fn LogFunction) { - logger.LogFn(PanicLevel, fn) + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panic(fn()...) + } } -func (logger *Logger) Logln(level Level, args ...interface{}) { +// Logln logs a message at the specified level with Println-style spacing. +// +// Using Logln with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logln treats the level as logging severity only; +// use [Logger.Panicln] or [Logger.Fatalln] when those side effects are desired. +func (logger *Logger) Logln(level Level, args ...any) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() entry.Logln(level, args...) @@ -300,43 +338,47 @@ func (logger *Logger) Logln(level Level, args ...interface{}) { } } -func (logger *Logger) Traceln(args ...interface{}) { +func (logger *Logger) Traceln(args ...any) { logger.Logln(TraceLevel, args...) } -func (logger *Logger) Debugln(args ...interface{}) { +func (logger *Logger) Debugln(args ...any) { logger.Logln(DebugLevel, args...) } -func (logger *Logger) Infoln(args ...interface{}) { +func (logger *Logger) Infoln(args ...any) { logger.Logln(InfoLevel, args...) } -func (logger *Logger) Println(args ...interface{}) { +func (logger *Logger) Println(args ...any) { entry := logger.newEntry() entry.Println(args...) logger.releaseEntry(entry) } -func (logger *Logger) Warnln(args ...interface{}) { +func (logger *Logger) Warnln(args ...any) { logger.Logln(WarnLevel, args...) } -func (logger *Logger) Warningln(args ...interface{}) { +func (logger *Logger) Warningln(args ...any) { logger.Warnln(args...) } -func (logger *Logger) Errorln(args ...interface{}) { +func (logger *Logger) Errorln(args ...any) { logger.Logln(ErrorLevel, args...) } -func (logger *Logger) Fatalln(args ...interface{}) { +func (logger *Logger) Fatalln(args ...any) { logger.Logln(FatalLevel, args...) logger.Exit(1) } -func (logger *Logger) Panicln(args ...interface{}) { - logger.Logln(PanicLevel, args...) +func (logger *Logger) Panicln(args ...any) { + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panicln(args...) + } } func (logger *Logger) Exit(code int) { @@ -375,7 +417,22 @@ func (logger *Logger) AddHook(hook Hook) { logger.Hooks.Add(hook) } -// IsLevelEnabled checks if the log level of the logger is greater than the level param +// hooksForLevel returns a snapshot of the hooks registered for the given level. +// The returned slice is a shallow copy and may be used without holding logger.mu. +func (logger *Logger) hooksForLevel(level Level) []Hook { + logger.mu.Lock() + hooks := logger.Hooks[level] + if len(hooks) == 0 { + logger.mu.Unlock() + return nil + } + out := make([]Hook, len(hooks)) + copy(out, hooks) + logger.mu.Unlock() + return out +} + +// IsLevelEnabled checks if logging for the given level is enabled. func (logger *Logger) IsLevelEnabled(level Level) bool { return logger.level() >= level } @@ -394,6 +451,7 @@ func (logger *Logger) SetOutput(output io.Writer) { logger.Out = output } +// SetReportCaller sets whether the caller stack frame must be logged. func (logger *Logger) SetReportCaller(reportCaller bool) { logger.mu.Lock() defer logger.mu.Unlock() @@ -403,9 +461,9 @@ func (logger *Logger) SetReportCaller(reportCaller bool) { // ReplaceHooks replaces the logger hooks and returns the old ones func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks { logger.mu.Lock() + defer logger.mu.Unlock() oldHooks := logger.Hooks logger.Hooks = hooks - logger.mu.Unlock() return oldHooks } diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go index 37fc4fef..d52b4ba7 100644 --- a/vendor/github.com/sirupsen/logrus/logrus.go +++ b/vendor/github.com/sirupsen/logrus/logrus.go @@ -1,13 +1,13 @@ package logrus import ( + "bytes" "fmt" "log" - "strings" ) // Fields type, used to pass to [WithFields]. -type Fields map[string]interface{} +type Fields map[string]any // Level type // @@ -16,39 +16,56 @@ type Level uint32 // Convert the Level to a string. E.g. [PanicLevel] becomes "panic". func (level Level) String() string { - if b, err := level.MarshalText(); err == nil { - return string(b) - } else { + switch level { + case TraceLevel: + return "trace" + case DebugLevel: + return "debug" + case InfoLevel: + return "info" + case WarnLevel: + return "warning" + case ErrorLevel: + return "error" + case FatalLevel: + return "fatal" + case PanicLevel: + return "panic" + default: return "unknown" } } // ParseLevel takes a string level and returns the Logrus log level constant. func ParseLevel(lvl string) (Level, error) { - switch strings.ToLower(lvl) { - case "panic": + return parseLevel([]byte(lvl)) +} + +func parseLevel(b []byte) (Level, error) { + switch { + case bytes.EqualFold(b, []byte("panic")): return PanicLevel, nil - case "fatal": + case bytes.EqualFold(b, []byte("fatal")): return FatalLevel, nil - case "error": + case bytes.EqualFold(b, []byte("error")): return ErrorLevel, nil - case "warn", "warning": + case bytes.EqualFold(b, []byte("warn")), + bytes.EqualFold(b, []byte("warning")): return WarnLevel, nil - case "info": + case bytes.EqualFold(b, []byte("info")): return InfoLevel, nil - case "debug": + case bytes.EqualFold(b, []byte("debug")): return DebugLevel, nil - case "trace": + case bytes.EqualFold(b, []byte("trace")): return TraceLevel, nil + default: + return 0, fmt.Errorf("not a valid logrus Level: %q", b) } - - var l Level - return l, fmt.Errorf("not a valid logrus Level: %q", lvl) } // UnmarshalText implements encoding.TextUnmarshaler. func (level *Level) UnmarshalText(text []byte) error { - l, err := ParseLevel(string(text)) + l, err := parseLevel(text) if err != nil { return err } @@ -60,23 +77,11 @@ func (level *Level) UnmarshalText(text []byte) error { func (level Level) MarshalText() ([]byte, error) { switch level { - case TraceLevel: - return []byte("trace"), nil - case DebugLevel: - return []byte("debug"), nil - case InfoLevel: - return []byte("info"), nil - case WarnLevel: - return []byte("warning"), nil - case ErrorLevel: - return []byte("error"), nil - case FatalLevel: - return []byte("fatal"), nil - case PanicLevel: - return []byte("panic"), nil + case TraceLevel, DebugLevel, InfoLevel, WarnLevel, ErrorLevel, FatalLevel, PanicLevel: + return []byte(level.String()), nil + default: + return nil, fmt.Errorf("not a valid logrus level %d", level) } - - return nil, fmt.Errorf("not a valid logrus level %d", level) } // AllLevels exposing all logging levels. @@ -91,7 +96,7 @@ var AllLevels = []Level{ } // These are the different logging levels. You can set the logging level to log -// on your instance of logger, obtained with `logrus.New()`. +// on your instance of logger, obtained with [logrus.New]. const ( // PanicLevel level, highest level of severity. Logs and then calls panic with the // message passed to Debug, Info, ... @@ -113,78 +118,110 @@ const ( TraceLevel ) -// Won't compile if StdLogger can't be realized by a log.Logger +// Compile-time interface assertions. var ( - _ StdLogger = &log.Logger{} - _ StdLogger = &Entry{} - _ StdLogger = &Logger{} + _ StdLogger = (*log.Logger)(nil) + _ StdLogger = (*Entry)(nil) + _ StdLogger = (*Logger)(nil) + + _ FieldLogger = (*Logger)(nil) + _ FieldLogger = (*Entry)(nil) + _ FieldLogger = Ext1FieldLogger(nil) + + _ DebugLogger = (*Logger)(nil) + _ InfoLogger = (*Logger)(nil) + _ WarnLogger = (*Logger)(nil) + _ ErrorLogger = (*Logger)(nil) + _ TraceLogger = (*Logger)(nil) + + _ DebugLogger = (*Entry)(nil) + _ InfoLogger = (*Entry)(nil) + _ WarnLogger = (*Entry)(nil) + _ ErrorLogger = (*Entry)(nil) + _ TraceLogger = (*Entry)(nil) + + _ Ext1FieldLogger = (*Logger)(nil) + _ Ext1FieldLogger = (*Entry)(nil) ) // StdLogger is what your logrus-enabled library should take, that way // it'll accept a stdlib logger ([log.Logger]) and a logrus logger. // There's no standard interface, so this is the closest we get, unfortunately. type StdLogger interface { - Print(...interface{}) - Printf(string, ...interface{}) - Println(...interface{}) + Print(args ...any) + Printf(format string, args ...any) + Println(args ...any) - Fatal(...interface{}) - Fatalf(string, ...interface{}) - Fatalln(...interface{}) + Fatal(args ...any) + Fatalf(format string, args ...any) + Fatalln(args ...any) - Panic(...interface{}) - Panicf(string, ...interface{}) - Panicln(...interface{}) + Panic(args ...any) + Panicf(format string, args ...any) + Panicln(args ...any) } // FieldLogger extends the [StdLogger] interface, generalizing // the [Entry] and [Logger] types. type FieldLogger interface { - WithField(key string, value interface{}) *Entry + WithField(key string, value any) *Entry WithFields(fields Fields) *Entry WithError(err error) *Entry - Debugf(format string, args ...interface{}) - Infof(format string, args ...interface{}) - Printf(format string, args ...interface{}) - Warnf(format string, args ...interface{}) - Warningf(format string, args ...interface{}) - Errorf(format string, args ...interface{}) - Fatalf(format string, args ...interface{}) - Panicf(format string, args ...interface{}) - - Debug(args ...interface{}) - Info(args ...interface{}) - Print(args ...interface{}) - Warn(args ...interface{}) - Warning(args ...interface{}) - Error(args ...interface{}) - Fatal(args ...interface{}) - Panic(args ...interface{}) - - Debugln(args ...interface{}) - Infoln(args ...interface{}) - Println(args ...interface{}) - Warnln(args ...interface{}) - Warningln(args ...interface{}) - Errorln(args ...interface{}) - Fatalln(args ...interface{}) - Panicln(args ...interface{}) - - // IsDebugEnabled() bool - // IsInfoEnabled() bool - // IsWarnEnabled() bool - // IsErrorEnabled() bool - // IsFatalEnabled() bool - // IsPanicEnabled() bool + StdLogger + DebugLogger + InfoLogger + WarnLogger + ErrorLogger + + // Legacy warning aliases. These are kept on FieldLogger for backwards + // compatibility, but are intentionally omitted from [WarnLogger]. + + Warning(args ...any) + Warningf(format string, args ...any) + Warningln(args ...any) +} + +// DebugLogger provides convenience functions to log messages at level [DebugLevel]. +type DebugLogger interface { + Debug(args ...any) + Debugf(format string, args ...any) + Debugln(args ...any) +} + +// InfoLogger provides convenience functions to log messages at level [InfoLevel]. +type InfoLogger interface { + Info(args ...any) + Infof(format string, args ...any) + Infoln(args ...any) +} + +// WarnLogger provides convenience functions to log messages at level [WarnLevel]. +type WarnLogger interface { + Warn(args ...any) + Warnf(format string, args ...any) + Warnln(args ...any) +} + +// ErrorLogger provides convenience functions to log messages at level [ErrorLevel]. +type ErrorLogger interface { + Error(args ...any) + Errorf(format string, args ...any) + Errorln(args ...any) +} + +// TraceLogger provides convenience functions to log messages at level [TraceLevel]. +type TraceLogger interface { + Trace(args ...any) + Tracef(format string, args ...any) + Traceln(args ...any) } -// Ext1FieldLogger (the first extension to [FieldLogger]) is superfluous, it is -// here for consistency. Do not use. Use [FieldLogger], [Logger] or [Entry] -// instead. +// Ext1FieldLogger is FieldLogger extended with Trace-level methods. +// +// New code should prefer the smallest applicable interface, such as +// [FieldLogger] or [TraceLogger], or use [Logger] or [Entry] directly. type Ext1FieldLogger interface { FieldLogger - Tracef(format string, args ...interface{}) - Trace(args ...interface{}) - Traceln(args ...interface{}) + TraceLogger } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go index 2403de98..1c6202b8 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go @@ -1,11 +1,7 @@ -// +build appengine +//go:build appengine package logrus -import ( - "io" -) - -func checkIfTerminal(w io.Writer) bool { +func checkIfTerminal(_ any) bool { return true } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go index 69956b42..ff9531ac 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go @@ -1,5 +1,4 @@ -// +build darwin dragonfly freebsd netbsd openbsd hurd -// +build !js +//go:build (darwin || dragonfly || freebsd || netbsd || openbsd || hurd) && !tinygo package logrus diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_js.go b/vendor/github.com/sirupsen/logrus/terminal_check_js.go deleted file mode 100644 index ebdae3ec..00000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_js.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build js - -package logrus - -func isTerminal(fd int) bool { - return false -} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go index 97af92c6..17ae9f04 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go @@ -1,11 +1,7 @@ -// +build js nacl plan9 +//go:build js || nacl || plan9 || wasi || wasip1 || tinygo package logrus -import ( - "io" -) - -func checkIfTerminal(w io.Writer) bool { +func checkIfTerminal(_ any) bool { return false } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go index 3293fb3c..780a42a5 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go @@ -1,4 +1,4 @@ -// +build !appengine,!js,!windows,!nacl,!plan9 +//go:build !appengine && !js && !windows && !nacl && !plan9 && !wasi && !wasip1 && !tinygo package logrus @@ -10,7 +10,11 @@ import ( func checkIfTerminal(w io.Writer) bool { switch v := w.(type) { case *os.File: - return isTerminal(int(v.Fd())) + fd := v.Fd() + if fd > uintptr(^uint(0)>>1) { + return false + } + return isTerminal(int(fd)) default: return false } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go index f6710b3b..8d9b26fc 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go @@ -1,3 +1,5 @@ +//go:build solaris && !tinygo + package logrus import ( diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go index c9aed267..b161506d 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go @@ -1,7 +1,4 @@ -//go:build (linux || aix || zos) && !js && !wasi -// +build linux aix zos -// +build !js -// +build !wasi +//go:build (linux || aix || zos) && !tinygo package logrus diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go b/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go deleted file mode 100644 index 2822b212..00000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build wasi -// +build wasi - -package logrus - -func isTerminal(fd int) bool { - return false -} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go b/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go deleted file mode 100644 index 108a6be1..00000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build wasip1 -// +build wasip1 - -package logrus - -func isTerminal(fd int) bool { - return false -} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go index 2879eb50..5fd3c431 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go @@ -1,4 +1,4 @@ -// +build !appengine,!js,windows +//go:build windows && !appengine package logrus diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go index 6dfeb18b..82c1f3da 100644 --- a/vendor/github.com/sirupsen/logrus/text_formatter.go +++ b/vendor/github.com/sirupsen/logrus/text_formatter.go @@ -3,30 +3,32 @@ package logrus import ( "bytes" "fmt" + "maps" "os" + "reflect" "runtime" - "sort" + "slices" "strconv" "strings" "sync" "time" - "unicode/utf8" ) -const ( - red = 31 - yellow = 33 - blue = 36 - gray = 37 -) - -var baseTimestamp time.Time - -func init() { - baseTimestamp = time.Now() -} - -// TextFormatter formats logs into text +var baseTimestamp = time.Now() + +// TextFormatter formats logs into text. +// +// Output is logfmt-like: key=value pairs separated by spaces. Fields from +// [Entry.Data] are included together with the standard fields derived from the +// entry. If a field conflicts with a standard field, it is prefixed with +// "fields.". Standard field names can be customized through FieldMap. +// +// Field keys are written as-is (unquoted and unescaped) in the plain +// (non-colored) format; only field values may be quoted depending on +// DisableQuote, ForceQuote, QuoteEmptyFields, and the value content. +// +// When colors are enabled, ANSI escape sequences may be added for presentation. +// For fully escaped structured output (including safe keys), use JSONFormatter. type TextFormatter struct { // Set to true to bypass checking for a TTY before outputting colors. ForceColors bool @@ -64,7 +66,7 @@ type TextFormatter struct { // be desired. DisableSorting bool - // The keys sorting function, when uninitialized it uses sort.Strings. + // The keys sorting function, when uninitialized it uses slices.Sort. SortingFunc func([]string) // Disables the truncation of the level text to 4 characters. @@ -77,16 +79,22 @@ type TextFormatter struct { // QuoteEmptyFields will wrap empty fields in quotes if true QuoteEmptyFields bool - // Whether the logger's out is to a terminal - isTerminal bool + // Whether the logger's out is to a terminal. Don't use this field + // directly; use TextFormatter.isTerminal instead. + terminal bool // FieldMap allows users to customize the names of keys for default fields. + // Mapped keys are written as-is, so they should be safe for plain-text output. + // // As an example: + // // formatter := &TextFormatter{ - // FieldMap: FieldMap{ - // FieldKeyTime: "@timestamp", - // FieldKeyLevel: "@level", - // FieldKeyMsg: "@message"}} + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message", + // }, + // } FieldMap FieldMap // CallerPrettyfier can be set by the user to modify the content @@ -96,54 +104,78 @@ type TextFormatter struct { CallerPrettyfier func(*runtime.Frame) (function string, file string) terminalInitOnce sync.Once - - // The max length of the level text, generated dynamically on init - levelTextMaxLength int } -func (f *TextFormatter) init(entry *Entry) { - if entry.Logger != nil { - f.isTerminal = checkIfTerminal(entry.Logger.Out) - } - // Get the max length of the level text - for _, level := range AllLevels { - levelTextLength := utf8.RuneCount([]byte(level.String())) - if levelTextLength > f.levelTextMaxLength { - f.levelTextMaxLength = levelTextLength - } +func (f *TextFormatter) isTerminal(entry *Entry) bool { + if entry == nil || entry.Logger == nil { + // Don't run the terminalInitOnce without a logger, otherwise we'd + // cache the default (false) forever even if a logger is attached + // later. + return false } -} -func (f *TextFormatter) isColored() bool { - isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows")) + f.terminalInitOnce.Do(func() { + entry.Logger.mu.Lock() + out := entry.Logger.Out + entry.Logger.mu.Unlock() - if f.EnvironmentOverrideColors { - switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); { - case ok && force != "0": - isColored = true - case ok && force == "0", os.Getenv("CLICOLOR") == "0": - isColored = false - } + f.terminal = checkIfTerminal(out) + }) + + return f.terminal +} + +func (f *TextFormatter) isColored(isTerminal bool) bool { + if f.DisableColors { + return false } - return isColored && !f.DisableColors + colored := f.ForceColors || isTerminal + if !f.EnvironmentOverrideColors { + return colored + } + if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok { + return force != "0" + } + if os.Getenv("CLICOLOR") == "0" { + return false + } + return colored } // Format renders a single log entry func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - data := make(Fields) - for k, v := range entry.Data { - data[k] = v - } - prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + data := make(Fields, len(entry.Data)) + maps.Copy(data, entry.Data) + isColored := f.isColored(f.isTerminal(entry)) + + caller := entry.Caller + hasCaller := caller != nil + prefixFieldClashes(data, f.FieldMap, hasCaller) keys := make([]string, 0, len(data)) for k := range data { keys = append(keys, k) } - var funcVal, fileVal string + b := entry.Buffer + if b == nil { + b = new(bytes.Buffer) + } + + if isColored { + f.printColored(b, entry, keys, data) + } else { + f.printPlain(b, entry, keys, data) + } + + return b.Bytes(), nil +} + +func (f *TextFormatter) printPlain(b *bytes.Buffer, entry *Entry, keys []string, data Fields) { + caller := entry.Caller + hasCaller := caller != nil - fixedKeys := make([]string, 0, 4+len(data)) + fixedKeys := make([]string, 0, len(keys)+defaultFields) if !f.DisableTimestamp { fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime)) } @@ -154,12 +186,14 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { if entry.err != "" { fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError)) } - if entry.HasCaller() { + + var funcVal, fileVal string + if caller != nil { if f.CallerPrettyfier != nil { - funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + funcVal, fileVal = f.CallerPrettyfier(caller) } else { - funcVal = entry.Caller.Function - fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) + funcVal = caller.Function + fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10) } if funcVal != "" { @@ -172,169 +206,278 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { if !f.DisableSorting { if f.SortingFunc == nil { - sort.Strings(keys) + // Default sorting does not sort the "fixed keys"; + // see https://github.com/sirupsen/logrus/commit/73bc94e60c753099e8bae902f81fbd6e7dd95f26 + slices.Sort(keys) fixedKeys = append(fixedKeys, keys...) } else { - if !f.isColored() { - fixedKeys = append(fixedKeys, keys...) - f.SortingFunc(fixedKeys) - } else { - f.SortingFunc(keys) - } + fixedKeys = append(fixedKeys, keys...) + f.SortingFunc(fixedKeys) } } else { fixedKeys = append(fixedKeys, keys...) } - var b *bytes.Buffer - if entry.Buffer != nil { - b = entry.Buffer - } else { - b = &bytes.Buffer{} - } - - f.terminalInitOnce.Do(func() { f.init(entry) }) - - timestampFormat := f.TimestampFormat - if timestampFormat == "" { - timestampFormat = defaultTimestampFormat - } - if f.isColored() { - f.printColored(b, entry, keys, data, timestampFormat) - } else { - - for _, key := range fixedKeys { - var value interface{} - switch { - case key == f.FieldMap.resolve(FieldKeyTime): - value = entry.Time.Format(timestampFormat) - case key == f.FieldMap.resolve(FieldKeyLevel): - value = entry.Level.String() - case key == f.FieldMap.resolve(FieldKeyMsg): - value = entry.Message - case key == f.FieldMap.resolve(FieldKeyLogrusError): - value = entry.err - case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller(): - value = funcVal - case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller(): - value = fileVal - default: - value = data[key] + for _, key := range fixedKeys { + var value any + switch { + case key == f.FieldMap.resolve(FieldKeyTime): + if f.TimestampFormat == "" { + value = entry.Time.Format(defaultTimestampFormat) + } else { + value = entry.Time.Format(f.TimestampFormat) } - f.appendKeyValue(b, key, value) + case key == f.FieldMap.resolve(FieldKeyLevel): + value = entry.Level.String() + case key == f.FieldMap.resolve(FieldKeyMsg): + value = entry.Message + case key == f.FieldMap.resolve(FieldKeyLogrusError): + value = entry.err + case key == f.FieldMap.resolve(FieldKeyFunc) && hasCaller: + value = funcVal + case key == f.FieldMap.resolve(FieldKeyFile) && hasCaller: + value = fileVal + default: + value = data[key] } + f.appendKeyValue(b, key, value) } b.WriteByte('\n') - return b.Bytes(), nil } -func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) { - var levelColor int - switch entry.Level { - case DebugLevel, TraceLevel: - levelColor = gray - case WarnLevel: - levelColor = yellow - case ErrorLevel, FatalLevel, PanicLevel: - levelColor = red - case InfoLevel: - levelColor = blue - default: - levelColor = blue - } - - levelText := strings.ToUpper(entry.Level.String()) - if !f.DisableLevelTruncation && !f.PadLevelText { - levelText = levelText[0:4] - } - if f.PadLevelText { - // Generates the format string used in the next line, for example "%-6s" or "%-7s". - // Based on the max level text length. - formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s" - // Formats the level text by appending spaces up to the max length, for example: - // - "INFO " - // - "WARNING" - levelText = fmt.Sprintf(formatString, levelText) - } - +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields) { // Remove a single newline if it already exists in the message to keep // the behavior of logrus text_formatter the same as the stdlib log package entry.Message = strings.TrimSuffix(entry.Message, "\n") - caller := "" - if entry.HasCaller() { - funcVal := fmt.Sprintf("%s()", entry.Caller.Function) - fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) - + var callerText string + if caller := entry.Caller; caller != nil { + var funcVal, fileVal string if f.CallerPrettyfier != nil { - funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + funcVal, fileVal = f.CallerPrettyfier(caller) + } else { + if caller.Function != "" { + funcVal = caller.Function + "()" + } + fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10) } if fileVal == "" { - caller = funcVal + callerText = funcVal } else if funcVal == "" { - caller = fileVal + callerText = fileVal } else { - caller = fileVal + " " + funcVal + callerText = fileVal + " " + funcVal } } + levelText := levelPrefix(entry.Level, f.DisableLevelTruncation, f.PadLevelText) switch { case f.DisableTimestamp: - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message) + _, _ = fmt.Fprintf(b, "%s%s %-44s ", levelText, callerText, entry.Message) case !f.FullTimestamp: - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message) + _, _ = fmt.Fprintf(b, "%s[%04d]%s %-44s ", levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), callerText, entry.Message) default: - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = defaultTimestampFormat + } + _, _ = fmt.Fprintf(b, "%s[%s]%s %-44s ", levelText, entry.Time.Format(timestampFormat), callerText, entry.Message) + } + + if !f.DisableSorting { + if f.SortingFunc == nil { + slices.Sort(keys) + } else { + f.SortingFunc(keys) + } } + + // Keys use the same color as the level-prefix. for _, k := range keys { - v := data[k] - fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) - f.appendValue(b, v) + b.WriteByte(' ') + b.WriteString(colorize(entry.Level, k)) + b.WriteByte('=') + f.appendValue(b, data[k]) } + + b.WriteByte('\n') } -func (f *TextFormatter) needsQuoting(text string) bool { - if f.ForceQuote { - return true +// appendKeyValue writes key=value. Keys are written verbatim (unquoted/unescaped); +// values are subject to quoting/escaping. +func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value any) { + if b.Len() > 0 { + b.WriteByte(' ') } - if f.QuoteEmptyFields && len(text) == 0 { - return true + b.WriteString(key) + b.WriteByte('=') + f.appendValue(b, value) +} + +func (f *TextFormatter) appendValue(b *bytes.Buffer, value any) { + // Fast paths. + switch v := value.(type) { + case string: + f.appendString(b, v) + return + case []byte: + f.appendBytes(b, v) + return + case bool: + var raw [8]byte + f.appendBytes(b, strconv.AppendBool(raw[:0], v)) + return + case error: + f.appendError(b, v) + return + case fmt.Stringer: + f.appendStringer(b, v) + return } - if f.DisableQuote { - return false + + // Handle common primitives. + var raw [64]byte + var num []byte + + switch v := value.(type) { + case int: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int8: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int16: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int32: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int64: + num = strconv.AppendInt(raw[:0], v, 10) + + case uint: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint8: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint16: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint32: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint64: + num = strconv.AppendUint(raw[:0], v, 10) + case uintptr: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + + case float32: + num = strconv.AppendFloat(raw[:0], float64(v), 'g', -1, 32) + case float64: + num = strconv.AppendFloat(raw[:0], v, 'g', -1, 64) + + default: + f.appendString(b, fmt.Sprint(value)) + return + } + + f.appendNumeric(b, num) +} + +func (f *TextFormatter) appendString(b *bytes.Buffer, s string) { + quote := f.ForceQuote || (f.QuoteEmptyFields && len(s) == 0) || (!f.DisableQuote && needsQuoting(s)) + if !quote { + b.WriteString(s) + return + } + if len(s) == 0 { + b.WriteString(`""`) + return + } + + var tmp [128]byte + b.Write(strconv.AppendQuote(tmp[:0], s)) +} + +func (f *TextFormatter) appendBytes(b *bytes.Buffer, bs []byte) { + quote := f.ForceQuote || (f.QuoteEmptyFields && len(bs) == 0) || (!f.DisableQuote && needsQuotingBytes(bs)) + if !quote { + b.Write(bs) + return + } + if len(bs) == 0 { + b.WriteString(`""`) + return + } + + var tmp [128]byte + b.Write(strconv.AppendQuote(tmp[:0], string(bs))) +} + +func (f *TextFormatter) appendNumeric(b *bytes.Buffer, out []byte) { + if f.ForceQuote { + var tmp [128]byte + b.Write(strconv.AppendQuote(tmp[:0], string(out))) + return } - for _, ch := range text { - //nolint:staticcheck // QF1001: could apply De Morgan's law - if !((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || - ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') { + b.Write(out) +} + +func (f *TextFormatter) appendError(b *bytes.Buffer, v error) { + defer f.recoverValue(b, v, "Error") + + f.appendString(b, v.Error()) +} + +func (f *TextFormatter) appendStringer(b *bytes.Buffer, v fmt.Stringer) { + defer f.recoverValue(b, v, "String") + + f.appendString(b, v.String()) +} + +func (f *TextFormatter) recoverValue(b *bytes.Buffer, v any, method string) { + if r := recover(); r != nil { + rv := reflect.ValueOf(v) + if rv.Kind() == reflect.Pointer && rv.IsNil() { + f.appendString(b, "") + } else { + f.appendString(b, fmt.Sprintf("%%!v(PANIC=%s method: %v)", method, r)) + } + } +} + +// needsQuoting returns true if the string contains any byte that +// requires quoting. It returns false when every byte is "safe" according +// to isSafeByte. +func needsQuoting(s string) bool { + // use an index loop (avoid rune decoding). + for i := range len(s) { + c := s[i] + if !isSafeByte(c) { return true } } return false } -func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { - if b.Len() > 0 { - b.WriteByte(' ') +// needsQuotingBytes returns true if the byte slice contains any byte that +// requires quoting. It returns false when every byte is "safe" according +// to isSafeByte. +func needsQuotingBytes(bs []byte) bool { + for _, c := range bs { + if !isSafeByte(c) { + return true + } } - b.WriteString(key) - b.WriteByte('=') - f.appendValue(b, value) + return false } -func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { - stringVal, ok := value.(string) - if !ok { - stringVal = fmt.Sprint(value) +// isSafeByte returns true if the byte is allowed unquoted (ASCII and in the allowlist). +// It purposely uses byte arithmetic (no runes) for performance. +func isSafeByte(ch byte) bool { + ok := ch < 0x80 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) + if ok { + return true } - - if !f.needsQuoting(stringVal) { - b.WriteString(stringVal) - } else { - fmt.Fprintf(b, "%q", stringVal) + switch ch { + case '-', '.', '_', '/', '@', '^', '+': + return true + default: + return false } } diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go index 074fd4b8..30e34cda 100644 --- a/vendor/github.com/sirupsen/logrus/writer.go +++ b/vendor/github.com/sirupsen/logrus/writer.go @@ -30,7 +30,7 @@ func (entry *Entry) Writer() *io.PipeWriter { func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { reader, writer := io.Pipe() - var printFunc func(args ...interface{}) + printFunc := entry.Print // Determine which log function to use based on the specified log level switch level { @@ -48,8 +48,6 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { printFunc = entry.Fatal case PanicLevel: printFunc = entry.Panic - default: - printFunc = entry.Print } // Start a new goroutine to scan the input and write it to the logger using the specified print function. @@ -63,7 +61,7 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { } // writerScanner scans the input from the reader and writes it to the logger -func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { +func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...any)) { scanner := bufio.NewScanner(reader) // Set the buffer size to the maximum token size to avoid buffer overflows diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go index 0fa5bdfd..47b0a943 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/config/feature_flags.go @@ -121,6 +121,18 @@ const ( EnableTerminationMessageCompression = "enable-termination-message-compression" // DefaultEnableTerminationMessageCompression is the default value for EnableTerminationMessageCompression DefaultEnableTerminationMessageCompression = false + // KeepStatusSpecDescriptions is the opt-out flag to retain documentation-only + // description fields in the status.taskSpec/status.pipelineSpec snapshots. + // They are stripped by default to reduce etcd usage; set this to "true" to + // keep them during a migration window. See #10321. + KeepStatusSpecDescriptions = "keep-status-spec-descriptions" + // DefaultKeepStatusSpecDescriptions is the default value for KeepStatusSpecDescriptions + DefaultKeepStatusSpecDescriptions = false + // SurfacePodEvents is the flag to enable surfacing Pod Warning events + // onto TaskRun status when a Pod is stuck pending with no useful message. + SurfacePodEvents = "surface-pod-events" + // DefaultSurfacePodEvents is the default value for SurfacePodEvents + DefaultSurfacePodEvents = false // EnableStepActions is the flag to enable step actions (no-op since it's stable) EnableStepActions = "enable-step-actions" @@ -193,6 +205,13 @@ var ( Enabled: DefaultAlphaFeatureEnabled, } + // DefaultSurfacePodEventsFlag is the default PerFeatureFlag value for SurfacePodEvents + DefaultSurfacePodEventsFlag = PerFeatureFlag{ + Name: SurfacePodEvents, + Stability: AlphaAPIFields, + Enabled: DefaultAlphaFeatureEnabled, + } + DefaultEnableTektonOCIBundles = PerFeatureFlag{ Name: EnableTektonOCIBundles, Stability: AlphaAPIFields, @@ -235,6 +254,8 @@ type FeatureFlags struct { EnableKubernetesSidecar bool `json:"enableKubernetesSidecar,omitempty"` EnableWaitExponentialBackoff bool `json:"enableWaitExponentialBackoff,omitempty"` EnableTerminationMessageCompression bool `json:"enableTerminationMessageCompression,omitempty"` + KeepStatusSpecDescriptions bool `json:"keepStatusSpecDescriptions,omitempty"` + EnableSurfacePodEvents bool `json:"enableSurfacePodEvents,omitempty"` // DeprecatedEnableTektonOCIBundles is maintained for backward compatibility // to allow deletion of PipelineRuns created before v0.62.x. // This field is not used and can be removed in a future release @@ -351,6 +372,12 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) { if err := setPerFeatureFlag(EnableTerminationMessageCompression, DefaultEnableTerminationMessageCompressionFlag, &tc.EnableTerminationMessageCompression); err != nil { return nil, err } + if err := setFeature(KeepStatusSpecDescriptions, DefaultKeepStatusSpecDescriptions, &tc.KeepStatusSpecDescriptions); err != nil { + return nil, err + } + if err := setPerFeatureFlag(SurfacePodEvents, DefaultSurfacePodEventsFlag, &tc.EnableSurfacePodEvents); err != nil { + return nil, err + } return &tc, nil } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go index 6cbcb68b..f940ad3a 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/openapi_generated.go @@ -114,9 +114,8 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -134,8 +133,7 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Toleration"), + Ref: ref("k8s.io/api/core/v1.Toleration"), }, }, }, @@ -153,8 +151,7 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), + Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, }, @@ -203,9 +200,8 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -225,8 +221,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -244,8 +239,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Toleration"), + Ref: ref("k8s.io/api/core/v1.Toleration"), }, }, }, @@ -276,8 +270,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -343,8 +336,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), + Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, }, @@ -362,8 +354,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.HostAlias"), + Ref: ref("k8s.io/api/core/v1.HostAlias"), }, }, }, @@ -395,8 +386,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.TopologySpreadConstraint"), + Ref: ref("k8s.io/api/core/v1.TopologySpreadConstraint"), }, }, }, @@ -431,8 +421,7 @@ func schema_pkg_apis_pipeline_v1_Artifact(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ArtifactValue"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ArtifactValue"), }, }, }, @@ -467,9 +456,8 @@ func schema_pkg_apis_pipeline_v1_ArtifactValue(ref common.ReferenceCallback) com Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -506,8 +494,7 @@ func schema_pkg_apis_pipeline_v1_Artifacts(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), }, }, }, @@ -524,8 +511,7 @@ func schema_pkg_apis_pipeline_v1_Artifacts(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), }, }, }, @@ -591,8 +577,7 @@ func schema_pkg_apis_pipeline_v1_ChildStatusReference(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), }, }, }, @@ -644,8 +629,7 @@ func schema_pkg_apis_pipeline_v1_EmbeddedTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), }, }, }, @@ -677,8 +661,7 @@ func schema_pkg_apis_pipeline_v1_EmbeddedTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Step"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Step"), }, }, }, @@ -691,8 +674,7 @@ func schema_pkg_apis_pipeline_v1_EmbeddedTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -716,8 +698,7 @@ func schema_pkg_apis_pipeline_v1_EmbeddedTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Sidecar"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Sidecar"), }, }, }, @@ -735,8 +716,7 @@ func schema_pkg_apis_pipeline_v1_EmbeddedTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceDeclaration"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceDeclaration"), }, }, }, @@ -754,8 +734,7 @@ func schema_pkg_apis_pipeline_v1_EmbeddedTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskResult"), }, }, }, @@ -790,8 +769,7 @@ func schema_pkg_apis_pipeline_v1_IncludeParams(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -819,8 +797,7 @@ func schema_pkg_apis_pipeline_v1_Matrix(ref common.ReferenceCallback) common.Ope Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -833,8 +810,7 @@ func schema_pkg_apis_pipeline_v1_Matrix(ref common.ReferenceCallback) common.Ope Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.IncludeParams"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.IncludeParams"), }, }, }, @@ -913,8 +889,7 @@ func schema_pkg_apis_pipeline_v1_ParamSpec(ref common.ReferenceCallback) common. Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"), }, }, }, @@ -933,9 +908,8 @@ func schema_pkg_apis_pipeline_v1_ParamSpec(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -983,9 +957,8 @@ func schema_pkg_apis_pipeline_v1_ParamValue(ref common.ReferenceCallback) common Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -998,9 +971,8 @@ func schema_pkg_apis_pipeline_v1_ParamValue(ref common.ReferenceCallback) common Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1088,8 +1060,7 @@ func schema_pkg_apis_pipeline_v1_PipelineList(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Pipeline"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Pipeline"), }, }, }, @@ -1125,9 +1096,31 @@ func schema_pkg_apis_pipeline_v1_PipelineRef(ref common.ReferenceCallback) commo Format: "", }, }, + "resolver": { + SchemaProps: spec.SchemaProps{ + Description: "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + Type: []string{"string"}, + Format: "", + }, + }, + "params": { + SchemaProps: spec.SchemaProps{ + Description: "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + }, + }, + }, + }, + }, }, }, }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"}, } } @@ -1256,8 +1249,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunList(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineRun"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineRun"), }, }, }, @@ -1334,8 +1326,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunRunStatus(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), }, }, }, @@ -1374,8 +1365,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunSpec(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -1413,8 +1403,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunSpec(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceBinding"), }, }, }, @@ -1432,8 +1421,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunSpec(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineTaskRunSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineTaskRunSpec"), }, }, }, @@ -1481,8 +1469,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatus(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("knative.dev/pkg/apis.Condition"), + Ref: ref("knative.dev/pkg/apis.Condition"), }, }, }, @@ -1496,9 +1483,8 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatus(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1528,8 +1514,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatus(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineRunResult"), }, }, }, @@ -1553,8 +1538,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatus(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SkippedTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SkippedTask"), }, }, }, @@ -1572,8 +1556,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatus(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ChildStatusReference"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ChildStatusReference"), }, }, }, @@ -1599,9 +1582,8 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatus(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1646,8 +1628,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatusFields(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineRunResult"), }, }, }, @@ -1671,8 +1652,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatusFields(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SkippedTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SkippedTask"), }, }, }, @@ -1690,8 +1670,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatusFields(ref common.ReferenceCal Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ChildStatusReference"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ChildStatusReference"), }, }, }, @@ -1717,9 +1696,8 @@ func schema_pkg_apis_pipeline_v1_PipelineRunStatusFields(ref common.ReferenceCal Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1765,8 +1743,7 @@ func schema_pkg_apis_pipeline_v1_PipelineRunTaskRunStatus(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), }, }, }, @@ -1813,8 +1790,7 @@ func schema_pkg_apis_pipeline_v1_PipelineSpec(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineTask"), }, }, }, @@ -1827,8 +1803,7 @@ func schema_pkg_apis_pipeline_v1_PipelineSpec(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), }, }, }, @@ -1846,8 +1821,7 @@ func schema_pkg_apis_pipeline_v1_PipelineSpec(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineWorkspaceDeclaration"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineWorkspaceDeclaration"), }, }, }, @@ -1865,8 +1839,7 @@ func schema_pkg_apis_pipeline_v1_PipelineSpec(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineResult"), }, }, }, @@ -1884,8 +1857,7 @@ func schema_pkg_apis_pipeline_v1_PipelineSpec(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineTask"), }, }, }, @@ -1946,8 +1918,7 @@ func schema_pkg_apis_pipeline_v1_PipelineTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), }, }, }, @@ -1972,9 +1943,8 @@ func schema_pkg_apis_pipeline_v1_PipelineTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1987,8 +1957,7 @@ func schema_pkg_apis_pipeline_v1_PipelineTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -2012,8 +1981,7 @@ func schema_pkg_apis_pipeline_v1_PipelineTask(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspacePipelineTaskBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspacePipelineTaskBinding"), }, }, }, @@ -2066,9 +2034,8 @@ func schema_pkg_apis_pipeline_v1_PipelineTaskMetadata(ref common.ReferenceCallba Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2081,9 +2048,8 @@ func schema_pkg_apis_pipeline_v1_PipelineTaskMetadata(ref common.ReferenceCallba Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2177,8 +2143,7 @@ func schema_pkg_apis_pipeline_v1_PipelineTaskRunSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStepSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStepSpec"), }, }, }, @@ -2195,8 +2160,7 @@ func schema_pkg_apis_pipeline_v1_PipelineTaskRunSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunSidecarSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunSidecarSpec"), }, }, }, @@ -2349,9 +2313,31 @@ func schema_pkg_apis_pipeline_v1_Ref(ref common.ReferenceCallback) common.OpenAP Format: "", }, }, + "resolver": { + SchemaProps: spec.SchemaProps{ + Description: "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + Type: []string{"string"}, + Format: "", + }, + }, + "params": { + SchemaProps: spec.SchemaProps{ + Description: "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + }, + }, + }, + }, + }, }, }, }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"}, } } @@ -2377,9 +2363,8 @@ func schema_pkg_apis_pipeline_v1_RefSource(ref common.ReferenceCallback) common. Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2419,8 +2404,7 @@ func schema_pkg_apis_pipeline_v1_ResolverRef(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -2509,9 +2493,8 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2529,9 +2512,8 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2562,8 +2544,7 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.ContainerPort"), + Ref: ref("k8s.io/api/core/v1.ContainerPort"), }, }, }, @@ -2581,8 +2562,7 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), }, }, }, @@ -2602,8 +2582,7 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -2630,8 +2609,7 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -2651,8 +2629,7 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), }, }, }, @@ -2749,8 +2726,7 @@ func schema_pkg_apis_pipeline_v1_Sidecar(ref common.ReferenceCallback) common.Op Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage"), }, }, }, @@ -2858,8 +2834,7 @@ func schema_pkg_apis_pipeline_v1_SkippedTask(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), }, }, }, @@ -2915,9 +2890,8 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2935,9 +2909,8 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2962,8 +2935,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), }, }, }, @@ -2983,8 +2955,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -3011,8 +2982,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -3032,8 +3002,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), }, }, }, @@ -3077,8 +3046,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage"), }, }, }, @@ -3116,8 +3084,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -3135,8 +3102,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), }, }, }, @@ -3149,8 +3115,7 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WhenExpression"), }, }, }, @@ -3215,8 +3180,7 @@ func schema_pkg_apis_pipeline_v1_StepResult(ref common.ReferenceCallback) common Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"), }, }, }, @@ -3287,8 +3251,7 @@ func schema_pkg_apis_pipeline_v1_StepState(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult"), }, }, }, @@ -3311,8 +3274,7 @@ func schema_pkg_apis_pipeline_v1_StepState(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), }, }, }, @@ -3324,8 +3286,7 @@ func schema_pkg_apis_pipeline_v1_StepState(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Artifact"), }, }, }, @@ -3365,9 +3326,8 @@ func schema_pkg_apis_pipeline_v1_StepTemplate(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3385,9 +3345,8 @@ func schema_pkg_apis_pipeline_v1_StepTemplate(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3412,8 +3371,7 @@ func schema_pkg_apis_pipeline_v1_StepTemplate(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), }, }, }, @@ -3433,8 +3391,7 @@ func schema_pkg_apis_pipeline_v1_StepTemplate(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -3461,8 +3418,7 @@ func schema_pkg_apis_pipeline_v1_StepTemplate(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -3482,8 +3438,7 @@ func schema_pkg_apis_pipeline_v1_StepTemplate(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), }, }, }, @@ -3577,9 +3532,8 @@ func schema_pkg_apis_pipeline_v1_TaskBreakpoints(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3624,8 +3578,7 @@ func schema_pkg_apis_pipeline_v1_TaskList(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Task"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Task"), }, }, }, @@ -3668,9 +3621,31 @@ func schema_pkg_apis_pipeline_v1_TaskRef(ref common.ReferenceCallback) common.Op Format: "", }, }, + "resolver": { + SchemaProps: spec.SchemaProps{ + Description: "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + Type: []string{"string"}, + Format: "", + }, + }, + "params": { + SchemaProps: spec.SchemaProps{ + Description: "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + }, + }, + }, + }, + }, }, }, }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"}, } } @@ -3704,8 +3679,7 @@ func schema_pkg_apis_pipeline_v1_TaskResult(ref common.ReferenceCallback) common Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PropertySpec"), }, }, }, @@ -3818,8 +3792,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunInputs(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -3866,8 +3839,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunList(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRun"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRun"), }, }, }, @@ -3968,8 +3940,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunSpec(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -4039,8 +4010,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunSpec(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceBinding"), }, }, }, @@ -4058,8 +4028,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunSpec(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStepSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStepSpec"), }, }, }, @@ -4077,8 +4046,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunSpec(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunSidecarSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunSidecarSpec"), }, }, }, @@ -4132,8 +4100,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("knative.dev/pkg/apis.Condition"), + Ref: ref("knative.dev/pkg/apis.Condition"), }, }, }, @@ -4147,9 +4114,8 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4187,8 +4153,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState"), }, }, }, @@ -4201,8 +4166,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus"), }, }, }, @@ -4220,8 +4184,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult"), }, }, }, @@ -4245,8 +4208,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState"), }, }, }, @@ -4272,9 +4234,8 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatus(ref common.ReferenceCallback) com Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4328,8 +4289,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatusFields(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepState"), }, }, }, @@ -4342,8 +4302,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatusFields(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunStatus"), }, }, }, @@ -4361,8 +4320,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatusFields(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskRunResult"), }, }, }, @@ -4386,8 +4344,7 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatusFields(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.SidecarState"), }, }, }, @@ -4413,9 +4370,8 @@ func schema_pkg_apis_pipeline_v1_TaskRunStatusFields(ref common.ReferenceCallbac Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4475,8 +4431,7 @@ func schema_pkg_apis_pipeline_v1_TaskSpec(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), }, }, }, @@ -4508,8 +4463,7 @@ func schema_pkg_apis_pipeline_v1_TaskSpec(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Step"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Step"), }, }, }, @@ -4522,8 +4476,7 @@ func schema_pkg_apis_pipeline_v1_TaskSpec(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -4547,8 +4500,7 @@ func schema_pkg_apis_pipeline_v1_TaskSpec(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Sidecar"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Sidecar"), }, }, }, @@ -4566,8 +4518,7 @@ func schema_pkg_apis_pipeline_v1_TaskSpec(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceDeclaration"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceDeclaration"), }, }, }, @@ -4585,8 +4536,7 @@ func schema_pkg_apis_pipeline_v1_TaskSpec(ref common.ReferenceCallback) common.O Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.TaskResult"), }, }, }, @@ -4666,9 +4616,8 @@ func schema_pkg_apis_pipeline_v1_WhenExpression(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go index f549ae3e..f0487484 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/pipeline_validation.go @@ -42,10 +42,11 @@ var ( ) const ( - taskRef = "taskRef" - taskSpec = "taskSpec" - pipelineRef = "pipelineRef" - pipelineSpec = "pipelineSpec" + taskRef = "taskRef" + taskSpec = "taskSpec" + pipelineRef = "pipelineRef" + pipelineSpec = "pipelineSpec" + ttParamsPrefix = "tt.params" ) // SupportedVerbs returns the operations that validation should be called for @@ -871,15 +872,17 @@ func validateMatrix(ctx context.Context, tasks []PipelineTask) (errs *apis.Field } func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) (errs *apis.FieldError) { - validPrefixes := sets.NewString("params", "tasks", "finally", "context", "workspaces", "results") + validPrefixes := sets.NewString("params", "tasks", "finally", "context", "workspaces", "results", ttParamsPrefix) for idx, task := range tasks { for _, param := range task.Params { if expressions, ok := param.GetVarSubstitutionExpressions(); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "value", ).ViaFieldKey("params", param.Name).ViaFieldIndex(fieldPath, idx)) } @@ -889,10 +892,12 @@ func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) for i, we := range task.When { if expressions, ok := we.GetVarSubstitutionExpressions(); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "", ).ViaFieldIndex("when", i).ViaFieldIndex(fieldPath, idx)) } @@ -903,10 +908,13 @@ func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) for _, param := range task.Matrix.Params { if expressions, ok := param.GetVarSubstitutionExpressions(); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && + validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "value", ).ViaFieldKey("matrix.params", param.Name).ViaFieldIndex(fieldPath, idx)) } @@ -917,10 +925,13 @@ func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) for _, param := range include.Params { if expressions, ok := param.GetVarSubstitutionExpressions(); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && + validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "value", ).ViaFieldKey("params", param.Name).ViaFieldIndex("matrix.include", i).ViaFieldIndex(fieldPath, idx)) } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/result_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/result_validation.go index 6f4298da..4dd7e550 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/result_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/result_validation.go @@ -22,6 +22,9 @@ import ( "knative.dev/pkg/apis" ) +// stepResultNameRegex matches the format $(steps..results.). +var stepResultNameRegex = regexp.MustCompile(`\$\(steps\.(.*?)\.results\.(.*?)\)`) + // Validate implements apis.Validatable func (tr TaskResult) Validate(ctx context.Context) (errs *apis.FieldError) { if !resultNameFormatRegex.MatchString(tr.Name) { @@ -153,11 +156,10 @@ func validateObjectStepResult(sr StepResult) (errs *apis.FieldError) { } // ExtractStepResultName extracts the step name and result name from a string matching -// formtat $(steps..results.). +// format $(steps..results.). // If a match is not found, an error is retured. func ExtractStepResultName(value string) (string, string, error) { - re := regexp.MustCompile(`\$\(steps\.(.*?)\.results\.(.*?)\)`) - rs := re.FindStringSubmatch(value) + rs := stepResultNameRegex.FindStringSubmatch(value) if len(rs) != 3 { return "", "", fmt.Errorf("Could not extract step name and result name. Expected value to look like $(steps..results.) but got \"%v\"", value) } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/strip_descriptions.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/strip_descriptions.go new file mode 100644 index 00000000..4143bf25 --- /dev/null +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/strip_descriptions.go @@ -0,0 +1,70 @@ +/* +Copyright 2026 The Tekton 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 v1 + +// StripDescriptions clears documentation-only description fields from the TaskSpec snapshot. See #10321. +func (ts *TaskSpec) StripDescriptions() { + if ts == nil { + return + } + ts.Description = "" + for i := range ts.Params { + ts.Params[i].Description = "" + } + for i := range ts.Results { + ts.Results[i].Description = "" + } + for i := range ts.Workspaces { + ts.Workspaces[i].Description = "" + } + for i := range ts.Steps { + for j := range ts.Steps[i].Results { + ts.Steps[i].Results[j].Description = "" + } + } +} + +// StripDescriptions clears documentation-only description fields from the PipelineSpec snapshot. See #10321. +func (ps *PipelineSpec) StripDescriptions() { + if ps == nil { + return + } + ps.Description = "" + for i := range ps.Params { + ps.Params[i].Description = "" + } + for i := range ps.Results { + ps.Results[i].Description = "" + } + for i := range ps.Workspaces { + ps.Workspaces[i].Description = "" + } + for i := range ps.Tasks { + ps.Tasks[i].stripDescriptions() + } + for i := range ps.Finally { + ps.Finally[i].stripDescriptions() + } +} + +// stripDescriptions clears the PipelineTask description and any inline embedded TaskSpec descriptions. +func (pt *PipelineTask) stripDescriptions() { + pt.Description = "" + if pt.TaskSpec != nil { + pt.TaskSpec.TaskSpec.StripDescriptions() + } +} diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json index a0964b1d..a97a3ffc 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/swagger.json @@ -15,7 +15,6 @@ "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.LocalObjectReference" }, "x-kubernetes-list-type": "atomic" @@ -24,8 +23,7 @@ "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "priorityClassName": { @@ -44,7 +42,6 @@ "description": "If specified, the pod's tolerations.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Toleration" }, "x-kubernetes-list-type": "atomic" @@ -79,7 +76,6 @@ "description": "List of environment variables that can be provided to the containers belonging to the pod.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -90,7 +86,6 @@ "description": "HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.HostAlias" }, "x-kubernetes-list-type": "atomic" @@ -107,7 +102,6 @@ "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.LocalObjectReference" }, "x-kubernetes-list-type": "atomic" @@ -116,8 +110,7 @@ "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "priorityClassName": { @@ -140,7 +133,6 @@ "description": "If specified, the pod's tolerations.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Toleration" }, "x-kubernetes-list-type": "atomic" @@ -149,7 +141,6 @@ "description": "TopologySpreadConstraints controls how Pods are spread across your cluster among failure-domains such as regions, zones, nodes, and other user-defined topology domains.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TopologySpreadConstraint" }, "x-kubernetes-list-type": "atomic" @@ -158,7 +149,6 @@ "description": "List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes See Pod.spec.volumes (API version: v1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" }, "x-kubernetes-patch-merge-key": "name", @@ -182,7 +172,6 @@ "description": "A collection of values related to the artifact", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ArtifactValue" } } @@ -195,8 +184,7 @@ "digest": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "uri": { @@ -212,7 +200,6 @@ "inputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Artifact" }, "x-kubernetes-list-type": "atomic" @@ -220,7 +207,6 @@ "outputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Artifact" }, "x-kubernetes-list-type": "atomic" @@ -253,7 +239,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -286,7 +271,6 @@ "description": "Params is a list of input parameters required to run the task. Params must be supplied as inputs in TaskRuns unless they declare a default value.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ParamSpec" } }, @@ -294,7 +278,6 @@ "description": "Results are values that this Task can output", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskResult" }, "x-kubernetes-list-type": "atomic" @@ -303,7 +286,6 @@ "description": "Sidecars are run alongside the Task's step containers. They begin before the steps start and end after the steps complete.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Sidecar" }, "x-kubernetes-list-type": "atomic" @@ -320,7 +302,6 @@ "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Step" }, "x-kubernetes-list-type": "atomic" @@ -329,7 +310,6 @@ "description": "Volumes is a collection of volumes that are available to mount into the steps of the build. See Pod.spec.volumes (API version: v1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" } }, @@ -337,7 +317,6 @@ "description": "Workspaces are the volumes that this Task requires.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WorkspaceDeclaration" }, "x-kubernetes-list-type": "atomic" @@ -356,7 +335,6 @@ "description": "Params takes only `Parameters` of type `\"string\"` The names of the `params` must match the names of the `params` in the underlying `Task`", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" } } @@ -370,7 +348,6 @@ "description": "Include is a list of IncludeParams which allows passing in specific combinations of Parameters into the Matrix.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.IncludeParams" } }, @@ -378,7 +355,6 @@ "description": "Params is a list of parameters used to fan out the pipelineTask Params takes only `Parameters` of type `\"array\"` Each array element is supplied to the `PipelineTask` by substituting `params` of type `\"string\"` in the underlying `Task`. The names of the `params` in the `Matrix` must match the names of the `params` in the underlying `Task` that they will be substituting.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" } } @@ -420,8 +396,7 @@ "description": "Enum declares a set of allowed param input values for tasks/pipelines that can be validated. If Enum is not set, no input validation is performed for the param.", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" } }, "name": { @@ -433,7 +408,6 @@ "description": "Properties is the JSON Schema properties to support key-value pairs parameter.", "type": "object", "additionalProperties": { - "default": {}, "$ref": "#/definitions/v1.PropertySpec" } }, @@ -456,16 +430,14 @@ "ArrayVal": { "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, "ObjectVal": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "StringVal": { @@ -516,7 +488,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Pipeline" } }, @@ -541,6 +512,17 @@ "name": { "description": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", "type": "string" + }, + "params": { + "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + "type": "array", + "items": { + "$ref": "#/definitions/v1.Param" + } + }, + "resolver": { + "description": "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + "type": "string" } } }, @@ -612,7 +594,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineRun" } }, @@ -661,7 +642,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -680,7 +660,6 @@ "description": "Params is a list of parameter names and values.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" } }, @@ -699,7 +678,6 @@ "description": "TaskRunSpecs holds a set of runtime specs", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineTaskRunSpec" }, "x-kubernetes-list-type": "atomic" @@ -717,7 +695,6 @@ "description": "Workspaces holds a set of workspace bindings that must match names with those declared in the pipeline.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WorkspaceBinding" }, "x-kubernetes-list-type": "atomic" @@ -732,15 +709,13 @@ "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "childReferences": { "description": "list of TaskRun and Run names, PipelineTask names, and API versions/kinds for children of this PipelineRun.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ChildStatusReference" }, "x-kubernetes-list-type": "atomic" @@ -753,7 +728,6 @@ "description": "Conditions the latest available observations of a resource's current state.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/knative.Condition" }, "x-kubernetes-patch-merge-key": "type", @@ -780,7 +754,6 @@ "description": "Results are the list of results written out by the pipeline task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineRunResult" }, "x-kubernetes-list-type": "atomic" @@ -789,7 +762,6 @@ "description": "list of tasks that were skipped due to when expressions evaluating to false", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.SkippedTask" }, "x-kubernetes-list-type": "atomic" @@ -798,8 +770,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -816,7 +787,6 @@ "description": "list of TaskRun and Run names, PipelineTask names, and API versions/kinds for children of this PipelineRun.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ChildStatusReference" }, "x-kubernetes-list-type": "atomic" @@ -841,7 +811,6 @@ "description": "Results are the list of results written out by the pipeline task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineRunResult" }, "x-kubernetes-list-type": "atomic" @@ -850,7 +819,6 @@ "description": "list of tasks that were skipped due to when expressions evaluating to false", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.SkippedTask" }, "x-kubernetes-list-type": "atomic" @@ -859,8 +827,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -885,7 +852,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -908,7 +874,6 @@ "description": "Finally declares the list of Tasks that execute just before leaving the Pipeline i.e. either after all Tasks are finished executing successfully or after a failure which would result in ending the Pipeline", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineTask" }, "x-kubernetes-list-type": "atomic" @@ -917,7 +882,6 @@ "description": "Params declares a list of input parameters that must be supplied when this Pipeline is run.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ParamSpec" } }, @@ -925,7 +889,6 @@ "description": "Results are values that this pipeline can output once run", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineResult" }, "x-kubernetes-list-type": "atomic" @@ -934,7 +897,6 @@ "description": "Tasks declares the graph of Tasks that execute when this Pipeline is run.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineTask" }, "x-kubernetes-list-type": "atomic" @@ -943,7 +905,6 @@ "description": "Workspaces declares a set of named workspaces that are expected to be provided by a PipelineRun.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.PipelineWorkspaceDeclaration" }, "x-kubernetes-list-type": "atomic" @@ -978,7 +939,6 @@ "description": "Parameters declares parameters passed to this task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" } }, @@ -999,8 +959,7 @@ "description": "RunAfter is the list of PipelineTask names that should be executed before this Task executes. (Used to force a specific ordering in graph execution.)", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1020,7 +979,6 @@ "description": "When is a list of when expressions that need to be true for the task to run", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WhenExpression" } }, @@ -1028,7 +986,6 @@ "description": "Workspaces maps workspaces from the pipeline spec to the workspaces declared in the Task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WorkspacePipelineTaskBinding" }, "x-kubernetes-list-type": "atomic" @@ -1042,15 +999,13 @@ "annotations": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "labels": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } } } @@ -1105,7 +1060,6 @@ "sidecarSpecs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunSidecarSpec" }, "x-kubernetes-list-type": "atomic" @@ -1113,7 +1067,6 @@ "stepSpecs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunStepSpec" }, "x-kubernetes-list-type": "atomic" @@ -1188,6 +1141,17 @@ "name": { "description": "Name of the referenced step", "type": "string" + }, + "params": { + "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + "type": "array", + "items": { + "$ref": "#/definitions/v1.Param" + } + }, + "resolver": { + "description": "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + "type": "string" } } }, @@ -1199,8 +1163,7 @@ "description": "Digest is a collection of cryptographic digests for the contents of the artifact specified by URI. Example: {\"sha1\": \"f99d13e554ffcb696dee719fa85b695cb5b0f428\"}", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "entryPoint": { @@ -1221,7 +1184,6 @@ "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" } }, @@ -1270,8 +1232,7 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Sidecar's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1279,8 +1240,7 @@ "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Sidecar's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1293,7 +1253,6 @@ "description": "List of environment variables to set in the Sidecar. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -1304,7 +1263,6 @@ "description": "List of sources to populate environment variables in the Sidecar. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvFromSource" }, "x-kubernetes-list-type": "atomic" @@ -1334,7 +1292,6 @@ "description": "List of ports to expose from the Sidecar. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ContainerPort" }, "x-kubernetes-list-map-keys": [ @@ -1389,7 +1346,6 @@ "description": "volumeDevices is the list of block devices to be used by the Sidecar.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, "x-kubernetes-list-type": "atomic", @@ -1400,7 +1356,6 @@ "description": "Volumes to mount into the Sidecar's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -1415,7 +1370,6 @@ "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Sidecar wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WorkspaceUsage" }, "x-kubernetes-list-type": "atomic" @@ -1471,7 +1425,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -1489,8 +1442,7 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1498,8 +1450,7 @@ "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1516,7 +1467,6 @@ "description": "List of environment variables to set in the Step. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -1527,7 +1477,6 @@ "description": "List of sources to populate environment variables in the Step. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the Step is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvFromSource" }, "x-kubernetes-list-type": "atomic" @@ -1553,7 +1502,6 @@ "description": "Params declares parameters passed to this step action.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" } }, @@ -1565,7 +1513,6 @@ "description": "Results declares StepResults produced by the Step.\n\nIt can be used in an inlined Step when used to store Results to $(step.results.resultName.path). It cannot be used when referencing StepActions using [v1.Step.Ref]. The Results declared by the StepActions will be stored here instead.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.StepResult" }, "x-kubernetes-list-type": "atomic" @@ -1594,7 +1541,6 @@ "description": "volumeDevices is the list of block devices to be used by the Step.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, "x-kubernetes-list-type": "atomic", @@ -1605,7 +1551,6 @@ "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -1616,7 +1561,6 @@ "description": "When is a list of when expressions that need to be true for the task to run", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WhenExpression" } }, @@ -1628,7 +1572,6 @@ "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Step wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WorkspaceUsage" }, "x-kubernetes-list-type": "atomic" @@ -1665,7 +1608,6 @@ "description": "Properties is the JSON Schema properties to support key-value pairs results.", "type": "object", "additionalProperties": { - "default": {}, "$ref": "#/definitions/v1.PropertySpec" } }, @@ -1688,7 +1630,6 @@ "inputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Artifact" } }, @@ -1698,7 +1639,6 @@ "outputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Artifact" } }, @@ -1708,7 +1648,6 @@ "results": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunResult" } }, @@ -1737,8 +1676,7 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Step's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1746,8 +1684,7 @@ "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Step's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1760,7 +1697,6 @@ "description": "List of environment variables to set in the Step. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -1771,7 +1707,6 @@ "description": "List of sources to populate environment variables in the Step. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the Step is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvFromSource" }, "x-kubernetes-list-type": "atomic" @@ -1792,7 +1727,6 @@ "description": "volumeDevices is the list of block devices to be used by the Step.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, "x-kubernetes-list-type": "atomic", @@ -1803,7 +1737,6 @@ "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -1846,8 +1779,7 @@ "beforeSteps": { "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1871,7 +1803,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Task" } }, @@ -1900,6 +1831,17 @@ "name": { "description": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", "type": "string" + }, + "params": { + "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + "type": "array", + "items": { + "$ref": "#/definitions/v1.Param" + } + }, + "resolver": { + "description": "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + "type": "string" } } }, @@ -1923,7 +1865,6 @@ "description": "Properties is the JSON Schema properties to support key-value pairs results.", "type": "object", "additionalProperties": { - "default": {}, "$ref": "#/definitions/v1.PropertySpec" } }, @@ -1979,7 +1920,6 @@ "params": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" }, "x-kubernetes-list-type": "atomic" @@ -2000,7 +1940,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRun" } }, @@ -2075,7 +2014,6 @@ "params": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" } }, @@ -2096,7 +2034,6 @@ "description": "Specs to apply to Sidecars in this TaskRun. If a field is specified in both a Sidecar and a SidecarSpec, the value from the SidecarSpec will be used. This field is only supported when the alpha feature gate is enabled.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunSidecarSpec" }, "x-kubernetes-list-type": "atomic" @@ -2113,7 +2050,6 @@ "description": "Specs to apply to Steps in this TaskRun. If a field is specified in both a Step and a StepSpec, the value from the StepSpec will be used. This field is only supported when the alpha feature gate is enabled.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunStepSpec" }, "x-kubernetes-list-type": "atomic" @@ -2134,7 +2070,6 @@ "description": "Workspaces is a list of WorkspaceBindings from volumes to workspaces.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WorkspaceBinding" }, "x-kubernetes-list-type": "atomic" @@ -2152,8 +2087,7 @@ "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "artifacts": { @@ -2168,7 +2102,6 @@ "description": "Conditions the latest available observations of a resource's current state.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/knative.Condition" }, "x-kubernetes-patch-merge-key": "type", @@ -2192,7 +2125,6 @@ "description": "Results are the list of results written out by the task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunResult" }, "x-kubernetes-list-type": "atomic" @@ -2201,7 +2133,6 @@ "description": "RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures. All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunStatus" } }, @@ -2209,7 +2140,6 @@ "description": "The list has one entry per sidecar in the manifest. Each entry is represents the imageid of the corresponding sidecar.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.SidecarState" }, "x-kubernetes-list-type": "atomic" @@ -2218,8 +2148,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -2230,7 +2159,6 @@ "description": "Steps describes the state of each build step container.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.StepState" }, "x-kubernetes-list-type": "atomic" @@ -2269,7 +2197,6 @@ "description": "Results are the list of results written out by the task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunResult" }, "x-kubernetes-list-type": "atomic" @@ -2278,7 +2205,6 @@ "description": "RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures. All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskRunStatus" } }, @@ -2286,7 +2212,6 @@ "description": "The list has one entry per sidecar in the manifest. Each entry is represents the imageid of the corresponding sidecar.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.SidecarState" }, "x-kubernetes-list-type": "atomic" @@ -2295,8 +2220,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -2307,7 +2231,6 @@ "description": "Steps describes the state of each build step container.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.StepState" }, "x-kubernetes-list-type": "atomic" @@ -2354,7 +2277,6 @@ "description": "Params is a list of input parameters required to run the task. Params must be supplied as inputs in TaskRuns unless they declare a default value.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ParamSpec" } }, @@ -2362,7 +2284,6 @@ "description": "Results are values that this Task can output", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TaskResult" }, "x-kubernetes-list-type": "atomic" @@ -2371,7 +2292,6 @@ "description": "Sidecars are run alongside the Task's step containers. They begin before the steps start and end after the steps complete.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Sidecar" }, "x-kubernetes-list-type": "atomic" @@ -2384,7 +2304,6 @@ "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Step" }, "x-kubernetes-list-type": "atomic" @@ -2393,7 +2312,6 @@ "description": "Volumes is a collection of volumes that are available to mount into the steps of the build. See Pod.spec.volumes (API version: v1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" } }, @@ -2401,7 +2319,6 @@ "description": "Workspaces are the volumes that this Task requires.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.WorkspaceDeclaration" }, "x-kubernetes-list-type": "atomic" @@ -2446,8 +2363,7 @@ "description": "Values is an array of strings, which is compared against the input, for guard checking It must be non-empty", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go index a62621a6..d1d73a72 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1/when_validation.go @@ -21,7 +21,7 @@ import ( "fmt" "strings" - "github.com/google/cel-go/cel" + "cel.dev/cel-go/cel" "github.com/tektoncd/pipeline/pkg/apis/config" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/selection" diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/openapi_generated.go index c5a5e941..0be05ae5 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/openapi_generated.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/openapi_generated.go @@ -61,9 +61,8 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -81,8 +80,7 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Toleration"), + Ref: ref("k8s.io/api/core/v1.Toleration"), }, }, }, @@ -100,8 +98,7 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), + Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, }, @@ -150,9 +147,8 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -172,8 +168,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -191,8 +186,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Toleration"), + Ref: ref("k8s.io/api/core/v1.Toleration"), }, }, }, @@ -223,8 +217,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -290,8 +283,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), + Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, }, @@ -309,8 +301,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.HostAlias"), + Ref: ref("k8s.io/api/core/v1.HostAlias"), }, }, }, @@ -342,8 +333,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.TopologySpreadConstraint"), + Ref: ref("k8s.io/api/core/v1.TopologySpreadConstraint"), }, }, }, @@ -570,8 +560,7 @@ func schema_pkg_apis_pipeline_v1alpha1_RunList(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.Run"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.Run"), }, }, }, @@ -610,8 +599,7 @@ func schema_pkg_apis_pipeline_v1alpha1_RunSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -664,8 +652,7 @@ func schema_pkg_apis_pipeline_v1alpha1_RunSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), }, }, }, @@ -754,8 +741,7 @@ func schema_pkg_apis_pipeline_v1alpha1_StepActionList(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.StepAction"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.StepAction"), }, }, }, @@ -803,9 +789,8 @@ func schema_pkg_apis_pipeline_v1alpha1_StepActionSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -823,9 +808,8 @@ func schema_pkg_apis_pipeline_v1alpha1_StepActionSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -845,8 +829,7 @@ func schema_pkg_apis_pipeline_v1alpha1_StepActionSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -873,8 +856,7 @@ func schema_pkg_apis_pipeline_v1alpha1_StepActionSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), }, }, }, @@ -892,8 +874,7 @@ func schema_pkg_apis_pipeline_v1alpha1_StepActionSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), }, }, }, @@ -919,8 +900,7 @@ func schema_pkg_apis_pipeline_v1alpha1_StepActionSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -1010,8 +990,7 @@ func schema_pkg_apis_pipeline_v1alpha1_VerificationPolicyList(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.VerificationPolicy"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.VerificationPolicy"), }, }, }, @@ -1040,8 +1019,7 @@ func schema_pkg_apis_pipeline_v1alpha1_VerificationPolicySpec(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.ResourcePattern"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.ResourcePattern"), }, }, }, @@ -1054,8 +1032,7 @@ func schema_pkg_apis_pipeline_v1alpha1_VerificationPolicySpec(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.Authority"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1.Authority"), }, }, }, diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/swagger.json index 3f3fb55e..b00ef637 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/swagger.json +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1/swagger.json @@ -15,7 +15,6 @@ "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.LocalObjectReference" }, "x-kubernetes-list-type": "atomic" @@ -24,8 +23,7 @@ "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "priorityClassName": { @@ -44,7 +42,6 @@ "description": "If specified, the pod's tolerations.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Toleration" }, "x-kubernetes-list-type": "atomic" @@ -79,7 +76,6 @@ "description": "List of environment variables that can be provided to the containers belonging to the pod.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -90,7 +86,6 @@ "description": "HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.HostAlias" }, "x-kubernetes-list-type": "atomic" @@ -107,7 +102,6 @@ "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.LocalObjectReference" }, "x-kubernetes-list-type": "atomic" @@ -116,8 +110,7 @@ "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "priorityClassName": { @@ -140,7 +133,6 @@ "description": "If specified, the pod's tolerations.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Toleration" }, "x-kubernetes-list-type": "atomic" @@ -149,7 +141,6 @@ "description": "TopologySpreadConstraints controls how Pods are spread across your cluster among failure-domains such as regions, zones, nodes, and other user-defined topology domains.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TopologySpreadConstraint" }, "x-kubernetes-list-type": "atomic" @@ -158,7 +149,6 @@ "description": "List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes See Pod.spec.volumes (API version: v1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" }, "x-kubernetes-patch-merge-key": "name", @@ -280,7 +270,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1alpha1.Run" } }, @@ -301,7 +290,6 @@ "params": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } }, @@ -341,7 +329,6 @@ "description": "Workspaces is a list of WorkspaceBindings from volumes to workspaces.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceBinding" } } @@ -384,7 +371,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1alpha1.StepAction" } }, @@ -406,8 +392,7 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -415,8 +400,7 @@ "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -428,7 +412,6 @@ "description": "List of environment variables to set in the container. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -443,7 +426,6 @@ "description": "Params is a list of input parameters required to run the stepAction. Params must be supplied as inputs in Steps unless they declare a defaultvalue.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ParamSpec" } }, @@ -451,7 +433,6 @@ "description": "Results are values that this StepAction can output", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.StepResult" }, "x-kubernetes-list-type": "atomic" @@ -468,7 +449,6 @@ "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -521,7 +501,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1alpha1.VerificationPolicy" } }, @@ -547,7 +526,6 @@ "description": "Authorities defines the rules for validating signatures.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1alpha1.Authority" } }, @@ -559,7 +537,6 @@ "description": "Resources defines the patterns of resources sources that should be subject to this policy. For example, we may want to apply this Policy from a certain GitHub repo. Then the ResourcesPattern should be valid regex. E.g. If using gitresolver, and we want to config keys from a certain git repo. `ResourcesPattern` can be `https://github.com/tektoncd/catalog.git`, we will use regex to filter out those resources.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1alpha1.ResourcePattern" } } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go index df40de70..1e55bfab 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -139,9 +139,8 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -159,8 +158,7 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Toleration"), + Ref: ref("k8s.io/api/core/v1.Toleration"), }, }, }, @@ -178,8 +176,7 @@ func schema_pkg_apis_pipeline_pod_AffinityAssistantTemplate(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), + Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, }, @@ -228,9 +225,8 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -250,8 +246,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -269,8 +264,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Toleration"), + Ref: ref("k8s.io/api/core/v1.Toleration"), }, }, }, @@ -301,8 +295,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -368,8 +361,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), + Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, }, @@ -387,8 +379,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.HostAlias"), + Ref: ref("k8s.io/api/core/v1.HostAlias"), }, }, }, @@ -420,8 +411,7 @@ func schema_pkg_apis_pipeline_pod_Template(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.TopologySpreadConstraint"), + Ref: ref("k8s.io/api/core/v1.TopologySpreadConstraint"), }, }, }, @@ -456,8 +446,7 @@ func schema_pkg_apis_pipeline_v1beta1_Artifact(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ArtifactValue"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ArtifactValue"), }, }, }, @@ -492,9 +481,8 @@ func schema_pkg_apis_pipeline_v1beta1_ArtifactValue(ref common.ReferenceCallback Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -526,8 +514,7 @@ func schema_pkg_apis_pipeline_v1beta1_Artifacts(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), }, }, }, @@ -539,8 +526,7 @@ func schema_pkg_apis_pipeline_v1beta1_Artifacts(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), }, }, }, @@ -606,8 +592,7 @@ func schema_pkg_apis_pipeline_v1beta1_ChildStatusReference(ref common.ReferenceC Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), }, }, }, @@ -716,9 +701,8 @@ func schema_pkg_apis_pipeline_v1beta1_ConfigSource(ref common.ReferenceCallback) Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -817,8 +801,7 @@ func schema_pkg_apis_pipeline_v1beta1_CustomRunList(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRun"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CustomRun"), }, }, }, @@ -857,8 +840,7 @@ func schema_pkg_apis_pipeline_v1beta1_CustomRunSpec(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -910,8 +892,7 @@ func schema_pkg_apis_pipeline_v1beta1_CustomRunSpec(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), }, }, }, @@ -1008,8 +989,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec"), }, }, }, @@ -1041,8 +1021,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), }, }, }, @@ -1055,8 +1034,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -1080,8 +1058,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar"), }, }, }, @@ -1099,8 +1076,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration"), }, }, }, @@ -1118,8 +1094,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult"), }, }, }, @@ -1154,8 +1129,7 @@ func schema_pkg_apis_pipeline_v1beta1_IncludeParams(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -1187,8 +1161,7 @@ func schema_pkg_apis_pipeline_v1beta1_InternalTaskModifier(ref common.ReferenceC Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), }, }, }, @@ -1205,8 +1178,7 @@ func schema_pkg_apis_pipeline_v1beta1_InternalTaskModifier(ref common.ReferenceC Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), }, }, }, @@ -1223,8 +1195,7 @@ func schema_pkg_apis_pipeline_v1beta1_InternalTaskModifier(ref common.ReferenceC Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -1253,8 +1224,7 @@ func schema_pkg_apis_pipeline_v1beta1_Matrix(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -1267,8 +1237,7 @@ func schema_pkg_apis_pipeline_v1beta1_Matrix(ref common.ReferenceCallback) commo Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.IncludeParams"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.IncludeParams"), }, }, }, @@ -1347,8 +1316,7 @@ func schema_pkg_apis_pipeline_v1beta1_ParamSpec(ref common.ReferenceCallback) co Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PropertySpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PropertySpec"), }, }, }, @@ -1367,9 +1335,8 @@ func schema_pkg_apis_pipeline_v1beta1_ParamSpec(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1417,9 +1384,8 @@ func schema_pkg_apis_pipeline_v1beta1_ParamValue(ref common.ReferenceCallback) c Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1432,9 +1398,8 @@ func schema_pkg_apis_pipeline_v1beta1_ParamValue(ref common.ReferenceCallback) c Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -1559,8 +1524,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineList(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Pipeline"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Pipeline"), }, }, }, @@ -1603,9 +1567,31 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRef(ref common.ReferenceCallback) Format: "", }, }, + "resolver": { + SchemaProps: spec.SchemaProps{ + Description: "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + Type: []string{"string"}, + Format: "", + }, + }, + "params": { + SchemaProps: spec.SchemaProps{ + Description: "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + }, + }, + }, + }, + }, }, }, }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"}, } } @@ -1795,8 +1781,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunList(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineRun"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineRun"), }, }, }, @@ -1873,8 +1858,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunRunStatus(ref common.ReferenceC Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), }, }, }, @@ -1918,8 +1902,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineResourceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineResourceBinding"), }, }, }, @@ -1932,8 +1915,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -1982,8 +1964,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), }, }, }, @@ -2001,8 +1982,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunSpec(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskRunSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskRunSpec"), }, }, }, @@ -2050,8 +2030,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatus(ref common.ReferenceCall Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("knative.dev/pkg/apis.Condition"), + Ref: ref("knative.dev/pkg/apis.Condition"), }, }, }, @@ -2065,9 +2044,8 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatus(ref common.ReferenceCall Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2125,8 +2103,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatus(ref common.ReferenceCall Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineRunResult"), }, }, }, @@ -2150,8 +2127,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatus(ref common.ReferenceCall Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SkippedTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SkippedTask"), }, }, }, @@ -2169,8 +2145,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatus(ref common.ReferenceCall Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ChildStatusReference"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ChildStatusReference"), }, }, }, @@ -2196,9 +2171,8 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatus(ref common.ReferenceCall Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2271,8 +2245,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatusFields(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineRunResult"), }, }, }, @@ -2296,8 +2269,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatusFields(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SkippedTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SkippedTask"), }, }, }, @@ -2315,8 +2287,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatusFields(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ChildStatusReference"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ChildStatusReference"), }, }, }, @@ -2342,9 +2313,8 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunStatusFields(ref common.Referen Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2390,8 +2360,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineRunTaskRunStatus(ref common.Refere Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), }, }, }, @@ -2438,8 +2407,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineDeclaredResource"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineDeclaredResource"), }, }, }, @@ -2457,8 +2425,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTask"), }, }, }, @@ -2471,8 +2438,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec"), }, }, }, @@ -2490,8 +2456,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineWorkspaceDeclaration"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineWorkspaceDeclaration"), }, }, }, @@ -2509,8 +2474,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineResult"), }, }, }, @@ -2528,8 +2492,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTask"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTask"), }, }, }, @@ -2590,8 +2553,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), }, }, }, @@ -2616,9 +2578,8 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2637,8 +2598,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -2662,8 +2622,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspacePipelineTaskBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspacePipelineTaskBinding"), }, }, }, @@ -2737,9 +2696,8 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTaskInputResource(ref common.Refer Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2766,9 +2724,8 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTaskMetadata(ref common.ReferenceC Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2781,9 +2738,8 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTaskMetadata(ref common.ReferenceC Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -2872,8 +2828,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTaskResources(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskInputResource"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskInputResource"), }, }, }, @@ -2891,8 +2846,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTaskResources(ref common.Reference Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskOutputResource"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskOutputResource"), }, }, }, @@ -2960,8 +2914,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTaskRunSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStepOverride"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStepOverride"), }, }, }, @@ -2978,8 +2931,7 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTaskRunSpec(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunSidecarOverride"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunSidecarOverride"), }, }, }, @@ -3112,9 +3064,31 @@ func schema_pkg_apis_pipeline_v1beta1_Ref(ref common.ReferenceCallback) common.O Format: "", }, }, + "resolver": { + SchemaProps: spec.SchemaProps{ + Description: "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + Type: []string{"string"}, + Format: "", + }, + }, + "params": { + SchemaProps: spec.SchemaProps{ + Description: "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + }, + }, + }, + }, + }, }, }, }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"}, } } @@ -3140,9 +3114,8 @@ func schema_pkg_apis_pipeline_v1beta1_RefSource(ref common.ReferenceCallback) co Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3182,8 +3155,7 @@ func schema_pkg_apis_pipeline_v1beta1_ResolverRef(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -3272,9 +3244,8 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3292,9 +3263,8 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3325,8 +3295,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.ContainerPort"), + Ref: ref("k8s.io/api/core/v1.ContainerPort"), }, }, }, @@ -3344,8 +3313,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), }, }, }, @@ -3365,8 +3333,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -3393,8 +3360,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -3414,8 +3380,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), }, }, }, @@ -3512,8 +3477,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage"), }, }, }, @@ -3621,8 +3585,7 @@ func schema_pkg_apis_pipeline_v1beta1_SkippedTask(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), }, }, }, @@ -3678,9 +3641,8 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3698,9 +3660,8 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -3731,8 +3692,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.ContainerPort"), + Ref: ref("k8s.io/api/core/v1.ContainerPort"), }, }, }, @@ -3750,8 +3710,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), }, }, }, @@ -3771,8 +3730,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -3799,8 +3757,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -3820,8 +3777,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), }, }, }, @@ -3924,8 +3880,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage"), }, }, }, @@ -3963,8 +3918,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -3982,8 +3936,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), }, }, }, @@ -3995,8 +3948,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WhenExpression"), }, }, }, @@ -4086,8 +4038,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepActionList(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepAction"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepAction"), }, }, }, @@ -4135,9 +4086,8 @@ func schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4150,9 +4100,8 @@ func schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4172,8 +4121,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -4200,8 +4148,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), }, }, }, @@ -4219,8 +4166,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), }, }, }, @@ -4246,8 +4192,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -4330,8 +4275,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepState(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult"), }, }, }, @@ -4348,8 +4292,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepState(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), }, }, }, @@ -4361,8 +4304,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepState(ref common.ReferenceCallback) co Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Artifact"), }, }, }, @@ -4409,9 +4351,8 @@ func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4429,9 +4370,8 @@ func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4462,8 +4402,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.ContainerPort"), + Ref: ref("k8s.io/api/core/v1.ContainerPort"), }, }, }, @@ -4481,8 +4420,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), }, }, }, @@ -4502,8 +4440,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.EnvVar"), + Ref: ref("k8s.io/api/core/v1.EnvVar"), }, }, }, @@ -4530,8 +4467,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeMount"), + Ref: ref("k8s.io/api/core/v1.VolumeMount"), }, }, }, @@ -4551,8 +4487,7 @@ func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), }, }, }, @@ -4705,9 +4640,8 @@ func schema_pkg_apis_pipeline_v1beta1_TaskBreakpoints(ref common.ReferenceCallba Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4752,8 +4686,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskList(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Task"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Task"), }, }, }, @@ -4803,9 +4736,31 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRef(ref common.ReferenceCallback) comm Format: "", }, }, + "resolver": { + SchemaProps: spec.SchemaProps{ + Description: "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + Type: []string{"string"}, + Format: "", + }, + }, + "params": { + SchemaProps: spec.SchemaProps{ + Description: "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + }, + }, + }, + }, + }, }, }, }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"}, } } @@ -4898,9 +4853,8 @@ func schema_pkg_apis_pipeline_v1beta1_TaskResourceBinding(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -4933,8 +4887,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskResources(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResource"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResource"), }, }, }, @@ -4952,8 +4905,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskResources(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResource"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResource"), }, }, }, @@ -4997,8 +4949,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskResult(ref common.ReferenceCallback) c Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PropertySpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PropertySpec"), }, }, }, @@ -5111,8 +5062,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunInputs(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), }, }, }, @@ -5129,8 +5079,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunInputs(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -5177,8 +5126,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunList(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRun"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRun"), }, }, }, @@ -5211,8 +5159,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunOutputs(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), }, }, }, @@ -5245,8 +5192,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunResources(ref common.ReferenceCallb Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), }, }, }, @@ -5264,8 +5210,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunResources(ref common.ReferenceCallb Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResourceBinding"), }, }, }, @@ -5365,8 +5310,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), }, }, }, @@ -5442,8 +5386,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceBinding"), }, }, }, @@ -5461,8 +5404,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStepOverride"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStepOverride"), }, }, }, @@ -5480,8 +5422,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunSpec(ref common.ReferenceCallback) Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunSidecarOverride"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunSidecarOverride"), }, }, }, @@ -5535,8 +5476,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("knative.dev/pkg/apis.Condition"), + Ref: ref("knative.dev/pkg/apis.Condition"), }, }, }, @@ -5550,9 +5490,8 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -5590,8 +5529,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepState"), }, }, }, @@ -5609,8 +5547,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CloudEventDelivery"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CloudEventDelivery"), }, }, }, @@ -5623,8 +5560,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStatus"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStatus"), }, }, }, @@ -5642,8 +5578,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/result.RunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/result.RunResult"), }, }, }, @@ -5661,8 +5596,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult"), }, }, }, @@ -5680,8 +5614,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SidecarState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SidecarState"), }, }, }, @@ -5707,9 +5640,8 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatus(ref common.ReferenceCallback Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -5763,8 +5695,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatusFields(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepState"), }, }, }, @@ -5782,8 +5713,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatusFields(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CloudEventDelivery"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.CloudEventDelivery"), }, }, }, @@ -5796,8 +5726,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatusFields(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStatus"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunStatus"), }, }, }, @@ -5815,8 +5744,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatusFields(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/result.RunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/result.RunResult"), }, }, }, @@ -5834,8 +5762,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatusFields(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRunResult"), }, }, }, @@ -5853,8 +5780,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatusFields(ref common.ReferenceCa Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SidecarState"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SidecarState"), }, }, }, @@ -5880,9 +5806,8 @@ func schema_pkg_apis_pipeline_v1beta1_TaskRunStatusFields(ref common.ReferenceCa Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -5948,8 +5873,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec"), }, }, }, @@ -5981,8 +5905,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step"), }, }, }, @@ -5995,8 +5918,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/api/core/v1.Volume"), + Ref: ref("k8s.io/api/core/v1.Volume"), }, }, }, @@ -6020,8 +5942,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar"), }, }, }, @@ -6039,8 +5960,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration"), }, }, }, @@ -6058,8 +5978,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult"), }, }, }, @@ -6139,9 +6058,8 @@ func schema_pkg_apis_pipeline_v1beta1_WhenExpression(ref common.ReferenceCallbac Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, @@ -6431,8 +6349,7 @@ func schema_pkg_apis_resolution_v1beta1_ResolutionRequestList(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1.ResolutionRequest"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1.ResolutionRequest"), }, }, }, @@ -6466,8 +6383,7 @@ func schema_pkg_apis_resolution_v1beta1_ResolutionRequestSpec(ref common.Referen Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), }, }, }, @@ -6515,8 +6431,7 @@ func schema_pkg_apis_resolution_v1beta1_ResolutionRequestStatus(ref common.Refer Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("knative.dev/pkg/apis.Condition"), + Ref: ref("knative.dev/pkg/apis.Condition"), }, }, }, @@ -6530,9 +6445,8 @@ func schema_pkg_apis_resolution_v1beta1_ResolutionRequestStatus(ref common.Refer Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Type: []string{"string"}, + Format: "", }, }, }, diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go index 1dc239f3..7b71d9c9 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/pipeline_validation.go @@ -42,10 +42,11 @@ var ( ) const ( - taskRef = "taskRef" - taskSpec = "taskSpec" - pipelineRef = "pipelineRef" - pipelineSpec = "pipelineSpec" + taskRef = "taskRef" + taskSpec = "taskSpec" + pipelineRef = "pipelineRef" + pipelineSpec = "pipelineSpec" + ttParamsPrefix = "tt.params" ) // SupportedVerbs returns the operations that validation should be called for @@ -853,15 +854,17 @@ func validateMatrix(ctx context.Context, tasks []PipelineTask) (errs *apis.Field } func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) (errs *apis.FieldError) { - validPrefixes := sets.NewString("params", "tasks", "finally", "context", "workspaces", "results") + validPrefixes := sets.NewString("params", "tasks", "finally", "context", "workspaces", "results", ttParamsPrefix) for idx, task := range tasks { for _, param := range task.Params { if expressions, ok := GetVarSubstitutionExpressionsForParam(param); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "value", ).ViaFieldKey("params", param.Name).ViaFieldIndex(fieldPath, idx)) } @@ -871,10 +874,12 @@ func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) for i, we := range task.WhenExpressions { if expressions, ok := we.GetVarSubstitutionExpressions(); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "", ).ViaFieldIndex("when", i).ViaFieldIndex(fieldPath, idx)) } @@ -885,10 +890,13 @@ func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) for _, param := range task.Matrix.Params { if expressions, ok := GetVarSubstitutionExpressionsForParam(param); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && + validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "value", ).ViaFieldKey("matrix.params", param.Name).ViaFieldIndex(fieldPath, idx)) } @@ -899,10 +907,13 @@ func validateVarSubstitutionExpressions(tasks []PipelineTask, fieldPath string) for _, param := range include.Params { if expressions, ok := GetVarSubstitutionExpressionsForParam(param); ok { for _, expression := range expressions { - prefix := strings.SplitN(expression, ".", 2)[0] - if !validPrefixes.Has(prefix) { + fields := strings.SplitN(expression, ".", 3) + if !validPrefixes.Has(fields[0]) && + !(len(fields) > 1 && + validPrefixes.Has(fields[0]+"."+fields[1]) && + (fields[0]+"."+fields[1] != ttParamsPrefix || (len(fields) > 2 && fields[2] != ""))) { errs = errs.Also(apis.ErrInvalidValue( - fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, or results; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), + fmt.Sprintf("invalid variable reference %q, must start with a valid prefix: params, tasks, finally, context, workspaces, results, or tt.params; if you meant a shell variable, use ${VAR} instead", "$("+expression+")"), "value", ).ViaFieldKey("params", param.Name).ViaFieldIndex("matrix.include", i).ViaFieldIndex(fieldPath, idx)) } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json index cd95f64e..9262e506 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json @@ -15,7 +15,6 @@ "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.LocalObjectReference" }, "x-kubernetes-list-type": "atomic" @@ -24,8 +23,7 @@ "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "priorityClassName": { @@ -44,7 +42,6 @@ "description": "If specified, the pod's tolerations.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Toleration" }, "x-kubernetes-list-type": "atomic" @@ -79,7 +76,6 @@ "description": "List of environment variables that can be provided to the containers belonging to the pod.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -90,7 +86,6 @@ "description": "HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.HostAlias" }, "x-kubernetes-list-type": "atomic" @@ -107,7 +102,6 @@ "description": "ImagePullSecrets gives the name of the secret used by the pod to pull the image if specified", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.LocalObjectReference" }, "x-kubernetes-list-type": "atomic" @@ -116,8 +110,7 @@ "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "priorityClassName": { @@ -140,7 +133,6 @@ "description": "If specified, the pod's tolerations.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Toleration" }, "x-kubernetes-list-type": "atomic" @@ -149,7 +141,6 @@ "description": "TopologySpreadConstraints controls how Pods are spread across your cluster among failure-domains such as regions, zones, nodes, and other user-defined topology domains.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.TopologySpreadConstraint" }, "x-kubernetes-list-type": "atomic" @@ -158,7 +149,6 @@ "description": "List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes See Pod.spec.volumes (API version: v1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" }, "x-kubernetes-patch-merge-key": "name", @@ -182,7 +172,6 @@ "description": "A collection of values related to the artifact", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.ArtifactValue" } } @@ -195,8 +184,7 @@ "digest": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "uri": { @@ -212,14 +200,12 @@ "inputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Artifact" } }, "outputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Artifact" } } @@ -251,7 +237,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -309,8 +294,7 @@ "description": "Digest is a collection of cryptographic digests for the contents of the artifact specified by URI. Example: {\"sha1\": \"f99d13e554ffcb696dee719fa85b695cb5b0f428\"}", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "entryPoint": { @@ -363,7 +347,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.CustomRun" } }, @@ -391,7 +374,6 @@ "params": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } }, @@ -420,7 +402,6 @@ "description": "Workspaces is a list of WorkspaceBindings from volumes to workspaces.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceBinding" }, "x-kubernetes-list-type": "atomic" @@ -473,7 +454,6 @@ "description": "Params is a list of input parameters required to run the task. Params must be supplied as inputs in TaskRuns unless they declare a default value.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.ParamSpec" } }, @@ -485,7 +465,6 @@ "description": "Results are values that this Task can output", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResult" }, "x-kubernetes-list-type": "atomic" @@ -494,7 +473,6 @@ "description": "Sidecars are run alongside the Task's step containers. They begin before the steps start and end after the steps complete.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Sidecar" }, "x-kubernetes-list-type": "atomic" @@ -511,7 +489,6 @@ "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Step" }, "x-kubernetes-list-type": "atomic" @@ -520,7 +497,6 @@ "description": "Volumes is a collection of volumes that are available to mount into the steps of the build. See Pod.spec.volumes (API version: v1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" } }, @@ -528,7 +504,6 @@ "description": "Workspaces are the volumes that this Task requires.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceDeclaration" }, "x-kubernetes-list-type": "atomic" @@ -547,7 +522,6 @@ "description": "Params takes only `Parameters` of type `\"string\"` The names of the `params` must match the names of the `params` in the underlying `Task`", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } } @@ -565,7 +539,6 @@ "stepsToAppend": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Step" }, "x-kubernetes-list-type": "atomic" @@ -573,7 +546,6 @@ "stepsToPrepend": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Step" }, "x-kubernetes-list-type": "atomic" @@ -581,7 +553,6 @@ "volumes": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" }, "x-kubernetes-list-type": "atomic" @@ -596,7 +567,6 @@ "description": "Include is a list of IncludeParams which allows passing in specific combinations of Parameters into the Matrix.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.IncludeParams" } }, @@ -604,7 +574,6 @@ "description": "Params is a list of parameters used to fan out the pipelineTask Params takes only `Parameters` of type `\"array\"` Each array element is supplied to the `PipelineTask` by substituting `params` of type `\"string\"` in the underlying `Task`. The names of the `params` in the `Matrix` must match the names of the `params` in the underlying `Task` that they will be substituting.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } } @@ -646,8 +615,7 @@ "description": "Enum declares a set of allowed param input values for tasks/pipelines that can be validated. If Enum is not set, no input validation is performed for the param.", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" } }, "name": { @@ -659,7 +627,6 @@ "description": "Properties is the JSON Schema properties to support key-value pairs parameter.", "type": "object", "additionalProperties": { - "default": {}, "$ref": "#/definitions/v1beta1.PropertySpec" } }, @@ -682,16 +649,14 @@ "ArrayVal": { "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, "ObjectVal": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "StringVal": { @@ -766,7 +731,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Pipeline" } }, @@ -795,6 +759,17 @@ "name": { "description": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", "type": "string" + }, + "params": { + "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1.Param" + } + }, + "resolver": { + "description": "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + "type": "string" } } }, @@ -898,7 +873,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineRun" } }, @@ -947,7 +921,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -966,7 +939,6 @@ "description": "Params is a list of parameter names and values.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } }, @@ -985,7 +957,6 @@ "description": "Resources is a list of bindings specifying which actual instances of PipelineResources to use for the resources the Pipeline has declared it needs.\n\nDeprecated: Unused, preserved only for backwards compatibility", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineResourceBinding" }, "x-kubernetes-list-type": "atomic" @@ -1001,7 +972,6 @@ "description": "TaskRunSpecs holds a set of runtime specs", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineTaskRunSpec" }, "x-kubernetes-list-type": "atomic" @@ -1018,7 +988,6 @@ "description": "Workspaces holds a set of workspace bindings that must match names with those declared in the pipeline.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceBinding" }, "x-kubernetes-list-type": "atomic" @@ -1033,15 +1002,13 @@ "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "childReferences": { "description": "list of TaskRun and Run names, PipelineTask names, and API versions/kinds for children of this PipelineRun.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.ChildStatusReference" }, "x-kubernetes-list-type": "atomic" @@ -1054,7 +1021,6 @@ "description": "Conditions the latest available observations of a resource's current state.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/knative.Condition" }, "x-kubernetes-patch-merge-key": "type", @@ -1073,7 +1039,6 @@ "description": "PipelineResults are the list of results written out by the pipeline task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineRunResult" }, "x-kubernetes-list-type": "atomic" @@ -1097,7 +1062,6 @@ "description": "list of tasks that were skipped due to when expressions evaluating to false", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.SkippedTask" }, "x-kubernetes-list-type": "atomic" @@ -1106,8 +1070,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -1131,7 +1094,6 @@ "description": "list of TaskRun and Run names, PipelineTask names, and API versions/kinds for children of this PipelineRun.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.ChildStatusReference" }, "x-kubernetes-list-type": "atomic" @@ -1148,7 +1110,6 @@ "description": "PipelineResults are the list of results written out by the pipeline task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineRunResult" }, "x-kubernetes-list-type": "atomic" @@ -1172,7 +1133,6 @@ "description": "list of tasks that were skipped due to when expressions evaluating to false", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.SkippedTask" }, "x-kubernetes-list-type": "atomic" @@ -1181,8 +1141,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -1214,7 +1173,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -1237,7 +1195,6 @@ "description": "Finally declares the list of Tasks that execute just before leaving the Pipeline i.e. either after all Tasks are finished executing successfully or after a failure which would result in ending the Pipeline", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineTask" }, "x-kubernetes-list-type": "atomic" @@ -1246,7 +1203,6 @@ "description": "Params declares a list of input parameters that must be supplied when this Pipeline is run.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.ParamSpec" } }, @@ -1254,7 +1210,6 @@ "description": "Deprecated: Unused, preserved only for backwards compatibility", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineDeclaredResource" }, "x-kubernetes-list-type": "atomic" @@ -1263,7 +1218,6 @@ "description": "Results are values that this pipeline can output once run", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineResult" }, "x-kubernetes-list-type": "atomic" @@ -1272,7 +1226,6 @@ "description": "Tasks declares the graph of Tasks that execute when this Pipeline is run.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineTask" }, "x-kubernetes-list-type": "atomic" @@ -1281,7 +1234,6 @@ "description": "Workspaces declares a set of named workspaces that are expected to be provided by a PipelineRun.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineWorkspaceDeclaration" }, "x-kubernetes-list-type": "atomic" @@ -1316,7 +1268,6 @@ "description": "Parameters declares parameters passed to this task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } }, @@ -1341,8 +1292,7 @@ "description": "RunAfter is the list of PipelineTask names that should be executed before this Task executes. (Used to force a specific ordering in graph execution.)", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1362,7 +1312,6 @@ "description": "WhenExpressions is a list of when expressions that need to be true for the task to run", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WhenExpression" } }, @@ -1370,7 +1319,6 @@ "description": "Workspaces maps workspaces from the pipeline spec to the workspaces declared in the Task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspacePipelineTaskBinding" }, "x-kubernetes-list-type": "atomic" @@ -1389,8 +1337,7 @@ "description": "From is the list of PipelineTask names that the resource has to come from. (Implies an ordering in the execution graph.)", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1413,15 +1360,13 @@ "annotations": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "labels": { "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } } } @@ -1472,7 +1417,6 @@ "description": "Inputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineTaskInputResource" }, "x-kubernetes-list-type": "atomic" @@ -1481,7 +1425,6 @@ "description": "Outputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.PipelineTaskOutputResource" }, "x-kubernetes-list-type": "atomic" @@ -1514,7 +1457,6 @@ "sidecarOverrides": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunSidecarOverride" }, "x-kubernetes-list-type": "atomic" @@ -1522,7 +1464,6 @@ "stepOverrides": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunStepOverride" }, "x-kubernetes-list-type": "atomic" @@ -1595,6 +1536,17 @@ "name": { "description": "Name of the referenced step", "type": "string" + }, + "params": { + "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1.Param" + } + }, + "resolver": { + "description": "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + "type": "string" } } }, @@ -1606,8 +1558,7 @@ "description": "Digest is a collection of cryptographic digests for the contents of the artifact specified by URI. Example: {\"sha1\": \"f99d13e554ffcb696dee719fa85b695cb5b0f428\"}", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "entryPoint": { @@ -1662,7 +1613,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.ResolutionRequest" } }, @@ -1684,7 +1634,6 @@ "description": "Parameters are the runtime attributes passed to the resolver to help it figure out how to resolve the resource being requested. For example: repo URL, commit SHA, path to file, the kind of authentication to leverage, etc.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Param" }, "x-kubernetes-list-type": "atomic" @@ -1708,15 +1657,13 @@ "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "conditions": { "description": "Conditions the latest available observations of a resource's current state.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/knative.Condition" }, "x-kubernetes-patch-merge-key": "type", @@ -1774,7 +1721,6 @@ "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } }, @@ -1823,8 +1769,7 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1832,8 +1777,7 @@ "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Sidecar's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -1841,7 +1785,6 @@ "description": "List of environment variables to set in the Sidecar. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -1852,7 +1795,6 @@ "description": "List of sources to populate environment variables in the Sidecar. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the Sidecar is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvFromSource" }, "x-kubernetes-list-type": "atomic" @@ -1882,7 +1824,6 @@ "description": "List of ports to expose from the Sidecar. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ContainerPort" }, "x-kubernetes-list-map-keys": [ @@ -1942,7 +1883,6 @@ "description": "volumeDevices is the list of block devices to be used by the Sidecar.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, "x-kubernetes-list-type": "atomic", @@ -1953,7 +1893,6 @@ "description": "Volumes to mount into the Sidecar's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -1968,7 +1907,6 @@ "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Sidecar wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceUsage" }, "x-kubernetes-list-type": "atomic" @@ -2024,7 +1962,6 @@ "description": "WhenExpressions is the list of checks guarding the execution of the PipelineTask", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WhenExpression" }, "x-kubernetes-list-type": "atomic" @@ -2042,8 +1979,7 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -2051,8 +1987,7 @@ "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -2064,7 +1999,6 @@ "description": "List of environment variables to set in the container. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -2075,7 +2009,6 @@ "description": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvFromSource" }, "x-kubernetes-list-type": "atomic" @@ -2109,7 +2042,6 @@ "description": "Params declares parameters passed to this step action.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } }, @@ -2117,7 +2049,6 @@ "description": "List of ports to expose from the Step's container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ContainerPort" }, "x-kubernetes-list-map-keys": [ @@ -2145,7 +2076,6 @@ "description": "Results declares StepResults produced by the Step.\n\nIt can be used in an inlined Step when used to store Results to $(step.results.resultName.path). It cannot be used when referencing StepActions using [v1beta1.Step.Ref]. The Results declared by the StepActions will be stored here instead.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.StepResult" }, "x-kubernetes-list-type": "atomic" @@ -2198,7 +2128,6 @@ "description": "volumeDevices is the list of block devices to be used by the Step.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, "x-kubernetes-list-type": "atomic", @@ -2209,7 +2138,6 @@ "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -2219,7 +2147,6 @@ "when": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WhenExpression" } }, @@ -2231,7 +2158,6 @@ "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Step wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceUsage" }, "x-kubernetes-list-type": "atomic" @@ -2275,7 +2201,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.StepAction" } }, @@ -2297,16 +2222,14 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" } }, "command": { "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -2318,7 +2241,6 @@ "description": "List of environment variables to set in the container. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -2333,7 +2255,6 @@ "description": "Params is a list of input parameters required to run the stepAction. Params must be supplied as inputs in Steps unless they declare a defaultvalue.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ParamSpec" } }, @@ -2341,7 +2262,6 @@ "description": "Results are values that this StepAction can output", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.StepResult" }, "x-kubernetes-list-type": "atomic" @@ -2358,7 +2278,6 @@ "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -2394,7 +2313,6 @@ "inputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Artifact" } }, @@ -2404,7 +2322,6 @@ "outputs": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Artifact" } }, @@ -2414,7 +2331,6 @@ "results": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunResult" } }, @@ -2440,8 +2356,7 @@ "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Step's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -2449,8 +2364,7 @@ "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the Step's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -2458,7 +2372,6 @@ "description": "List of environment variables to set in the container. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvVar" }, "x-kubernetes-list-type": "atomic", @@ -2469,7 +2382,6 @@ "description": "List of sources to populate environment variables in the Step. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.EnvFromSource" }, "x-kubernetes-list-type": "atomic" @@ -2498,7 +2410,6 @@ "description": "List of ports to expose from the Step's container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.ContainerPort" }, "x-kubernetes-list-map-keys": [ @@ -2550,7 +2461,6 @@ "description": "volumeDevices is the list of block devices to be used by the Step.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, "x-kubernetes-list-type": "atomic", @@ -2561,7 +2471,6 @@ "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, "x-kubernetes-list-type": "atomic", @@ -2604,8 +2513,7 @@ "beforeSteps": { "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -2629,7 +2537,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Task" } }, @@ -2662,6 +2569,17 @@ "name": { "description": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", "type": "string" + }, + "params": { + "description": "Params contains the parameters used to identify the referenced Tekton resource. Example entries might include \"repo\" or \"path\" but the set of params ultimately depends on the chosen resolver.", + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1.Param" + } + }, + "resolver": { + "description": "Resolver is the name of the resolver that should perform resolution of the referenced Tekton resource, such as \"git\".", + "type": "string" } } }, @@ -2709,8 +2627,7 @@ "description": "Paths will probably be removed in #1284, and then PipelineResourceBinding can be used instead. The optional Path field corresponds to a path on disk at which the Resource can be found (used when providing the resource via mounted volume, overriding the default logic to fetch the Resource).", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" }, @@ -2732,7 +2649,6 @@ "description": "Inputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResource" }, "x-kubernetes-list-type": "atomic" @@ -2741,7 +2657,6 @@ "description": "Outputs holds the mapping from the PipelineResources declared in DeclaredPipelineResources to the input PipelineResources required by the Task.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResource" }, "x-kubernetes-list-type": "atomic" @@ -2768,7 +2683,6 @@ "description": "Properties is the JSON Schema properties to support key-value pairs results.", "type": "object", "additionalProperties": { - "default": {}, "$ref": "#/definitions/v1beta1.PropertySpec" } }, @@ -2824,7 +2738,6 @@ "params": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" }, "x-kubernetes-list-type": "atomic" @@ -2832,7 +2745,6 @@ "resources": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResourceBinding" }, "x-kubernetes-list-type": "atomic" @@ -2853,7 +2765,6 @@ "items": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRun" } }, @@ -2874,7 +2785,6 @@ "resources": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResourceBinding" }, "x-kubernetes-list-type": "atomic" @@ -2889,7 +2799,6 @@ "description": "Inputs holds the inputs resources this task was invoked with", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResourceBinding" }, "x-kubernetes-list-type": "atomic" @@ -2898,7 +2807,6 @@ "description": "Outputs holds the inputs resources this task was invoked with", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResourceBinding" }, "x-kubernetes-list-type": "atomic" @@ -2966,7 +2874,6 @@ "params": { "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Param" } }, @@ -2991,7 +2898,6 @@ "description": "Overrides to apply to Sidecars in this TaskRun. If a field is specified in both a Sidecar and a SidecarOverride, the value from the SidecarOverride will be used. This field is only supported when the alpha feature gate is enabled.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunSidecarOverride" }, "x-kubernetes-list-type": "atomic" @@ -3008,7 +2914,6 @@ "description": "Overrides to apply to Steps in this TaskRun. If a field is specified in both a Step and a StepOverride, the value from the StepOverride will be used. This field is only supported when the alpha feature gate is enabled.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunStepOverride" }, "x-kubernetes-list-type": "atomic" @@ -3029,7 +2934,6 @@ "description": "Workspaces is a list of WorkspaceBindings from volumes to workspaces.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceBinding" }, "x-kubernetes-list-type": "atomic" @@ -3047,15 +2951,13 @@ "description": "Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "cloudEvents": { "description": "CloudEvents describe the state of each cloud event requested via a CloudEventResource.\n\nDeprecated: No content written to it. To be Removed (since v0.44.0). Use kubectl describe (CloudEventSent/CloudEventFailed k8s Events) or the tekton_events_sent_total Prometheus metric for delivery visibility instead.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.CloudEventDelivery" }, "x-kubernetes-list-type": "atomic" @@ -3068,7 +2970,6 @@ "description": "Conditions the latest available observations of a resource's current state.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/knative.Condition" }, "x-kubernetes-patch-merge-key": "type", @@ -3092,7 +2993,6 @@ "description": "Results from Resources built during the TaskRun. This is tomb-stoned along with the removal of pipelineResources Deprecated: this field is not populated and is preserved only for backwards compatibility", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.result.RunResult" }, "x-kubernetes-list-type": "atomic" @@ -3101,7 +3001,6 @@ "description": "RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures. All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant. See TaskRun.status (API version: tekton.dev/v1beta1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunStatus" } }, @@ -3109,7 +3008,6 @@ "description": "The list has one entry per sidecar in the manifest. Each entry is represents the imageid of the corresponding sidecar.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.SidecarState" }, "x-kubernetes-list-type": "atomic" @@ -3118,8 +3016,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -3130,7 +3027,6 @@ "description": "Steps describes the state of each build step container.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.StepState" }, "x-kubernetes-list-type": "atomic" @@ -3139,7 +3035,6 @@ "description": "TaskRunResults are the list of results written out by the task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunResult" }, "x-kubernetes-list-type": "atomic" @@ -3161,7 +3056,6 @@ "description": "CloudEvents describe the state of each cloud event requested via a CloudEventResource.\n\nDeprecated: No content written to it. To be Removed (since v0.44.0). Use kubectl describe (CloudEventSent/CloudEventFailed k8s Events) or the tekton_events_sent_total Prometheus metric for delivery visibility instead.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.CloudEventDelivery" }, "x-kubernetes-list-type": "atomic" @@ -3183,7 +3077,6 @@ "description": "Results from Resources built during the TaskRun. This is tomb-stoned along with the removal of pipelineResources Deprecated: this field is not populated and is preserved only for backwards compatibility", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/github.com.tektoncd.pipeline.pkg.result.RunResult" }, "x-kubernetes-list-type": "atomic" @@ -3192,7 +3085,6 @@ "description": "RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures. All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant. See TaskRun.status (API version: tekton.dev/v1beta1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunStatus" } }, @@ -3200,7 +3092,6 @@ "description": "The list has one entry per sidecar in the manifest. Each entry is represents the imageid of the corresponding sidecar.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.SidecarState" }, "x-kubernetes-list-type": "atomic" @@ -3209,8 +3100,7 @@ "description": "SpanContext contains tracing span context fields", "type": "object", "additionalProperties": { - "type": "string", - "default": "" + "type": "string" } }, "startTime": { @@ -3221,7 +3111,6 @@ "description": "Steps describes the state of each build step container.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.StepState" }, "x-kubernetes-list-type": "atomic" @@ -3230,7 +3119,6 @@ "description": "TaskRunResults are the list of results written out by the task's containers", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskRunResult" }, "x-kubernetes-list-type": "atomic" @@ -3277,7 +3165,6 @@ "description": "Params is a list of input parameters required to run the task. Params must be supplied as inputs in TaskRuns unless they declare a default value.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.ParamSpec" } }, @@ -3289,7 +3176,6 @@ "description": "Results are values that this Task can output", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.TaskResult" }, "x-kubernetes-list-type": "atomic" @@ -3298,7 +3184,6 @@ "description": "Sidecars are run alongside the Task's step containers. They begin before the steps start and end after the steps complete.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Sidecar" }, "x-kubernetes-list-type": "atomic" @@ -3311,7 +3196,6 @@ "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.Step" }, "x-kubernetes-list-type": "atomic" @@ -3320,7 +3204,6 @@ "description": "Volumes is a collection of volumes that are available to mount into the steps of the build. See Pod.spec.volumes (API version: v1)", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1.Volume" } }, @@ -3328,7 +3211,6 @@ "description": "Workspaces are the volumes that this Task requires.", "type": "array", "items": { - "default": {}, "$ref": "#/definitions/v1beta1.WorkspaceDeclaration" }, "x-kubernetes-list-type": "atomic" @@ -3373,8 +3255,7 @@ "description": "Values is an array of strings, which is compared against the input, for guard checking It must be non-empty", "type": "array", "items": { - "type": "string", - "default": "" + "type": "string" }, "x-kubernetes-list-type": "atomic" } diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go index aa6b4b4c..f7983de7 100644 --- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go +++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/when_validation.go @@ -21,7 +21,7 @@ import ( "fmt" "strings" - "github.com/google/cel-go/cel" + "cel.dev/cel-go/cel" "github.com/tektoncd/pipeline/pkg/apis/config" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/selection" diff --git a/vendor/golang.org/x/sys/unix/ifreq_linux.go b/vendor/golang.org/x/sys/unix/ifreq_linux.go index 309f5a2b..3f7fa766 100644 --- a/vendor/golang.org/x/sys/unix/ifreq_linux.go +++ b/vendor/golang.org/x/sys/unix/ifreq_linux.go @@ -22,7 +22,13 @@ import ( // fields can be get and set using the following methods: // - Uint16/SetUint16: flags // - Uint32/SetUint32: ifindex, metric, mtu -type Ifreq struct{ raw ifreq } +type Ifreq struct { + // Aligns the union for the accessors below, which cast it in place; + // the generated ifreq is all byte arrays, so its alignment is one. + _ [0]int64 + + raw ifreq +} // NewIfreq creates an Ifreq with the input network interface name after // validating the name does not exceed IFNAMSIZ-1 (trailing NULL required) diff --git a/vendor/golang.org/x/sys/unix/ioctl_linux.go b/vendor/golang.org/x/sys/unix/ioctl_linux.go index 7ca4fa12..5589d4f6 100644 --- a/vendor/golang.org/x/sys/unix/ioctl_linux.go +++ b/vendor/golang.org/x/sys/unix/ioctl_linux.go @@ -332,3 +332,10 @@ func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error { func IoctlLoopConfigure(fd int, value *LoopConfig) error { return ioctlPtr(fd, LOOP_CONFIGURE, unsafe.Pointer(value)) } + +// IoctlPidfdInfo fetches information about a pidfd. +// The Mask field of the info argument indicates which +// values to fetch. +func IoctlPidfdInfo(fd int, info *PidfdInfo) error { + return ioctlPtr(fd, PIDFD_GET_INFO, unsafe.Pointer(info)) +} diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index fa74cfe9..9e907ac2 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -290,14 +290,7 @@ struct ltchars { #include #include -#if defined(__sparc__) -// On sparc{,64}, the kernel defines struct termios2 itself which clashes with the -// definition in glibc. As only the error constants are needed here, include the -// generic termibits.h (which is included by termbits.h on sparc). -#include -#else #include -#endif #ifndef PTRACE_GETREGS #define PTRACE_GETREGS 0xc @@ -544,7 +537,7 @@ ccflags="$@" $2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || $2 == "LOOP_CONFIGURE" || - $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ || + $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|MLOCK|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ || $2 ~ /^PTP_/ || diff --git a/vendor/golang.org/x/sys/unix/syscall.go b/vendor/golang.org/x/sys/unix/syscall.go index 5ea74da9..8f27e7ec 100644 --- a/vendor/golang.org/x/sys/unix/syscall.go +++ b/vendor/golang.org/x/sys/unix/syscall.go @@ -76,7 +76,7 @@ func BytePtrToString(p *byte) string { // Find NUL terminator. n := 0 for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ { - ptr = unsafe.Pointer(uintptr(ptr) + 1) + ptr = unsafe.Add(ptr, 1) } return string(unsafe.Slice(p, n)) diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index a00c3e54..035c2cd9 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -188,7 +188,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { } sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL sa.raw.Family = AF_UNIX - for i := 0; i < n; i++ { + for i := range n { sa.raw.Path[i] = int8(name[i]) } return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 21e2bfa3..6926057e 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -2363,7 +2363,7 @@ func (fh *FileHandle) Bytes() []byte { if n == 0 { return nil } - return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n) + return unsafe.Slice((*byte)(unsafe.Add(unsafe.Pointer(&fh.fileHandle.Type), 4)), n) } // NameToHandleAt wraps the name_to_handle_at system call; it obtains diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 5bb51d7a..45feb124 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2048,6 +2048,7 @@ const ( MINIX3_SUPER_MAGIC = 0x4d5a MINIX_SUPER_MAGIC = 0x137f MINIX_SUPER_MAGIC2 = 0x138f + MLOCK_ONFAULT = 0x1 MNT_DETACH = 0x2 MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 @@ -3862,6 +3863,7 @@ const ( TIOCPKT_NOSTOP = 0x10 TIOCPKT_START = 0x8 TIOCPKT_STOP = 0x4 + TIOCSER_TEMT = 0x1 TIPC_ADDR_ID = 0x3 TIPC_ADDR_MCAST = 0x1 TIPC_ADDR_NAME = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index c0a8ea1d..6f74d4a0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -483,7 +483,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 TIOCSISO7816 = 0xc0285443 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index ff927c83..36c1f0b6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -484,7 +484,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 TIOCSISO7816 = 0xc0285443 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 55294eda..c5512dbe 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -489,7 +489,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 TIOCSISO7816 = 0xc0285443 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 5dac54c3..4dabfae0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -483,7 +483,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 TIOCSISO7816 = 0xc0285443 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 46ac1fcb..ea97930f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -476,7 +476,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 TIOCSISO7816 = 0xc0285443 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index b55483e8..0826a929 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -481,7 +481,6 @@ const ( TIOCSERGWILD = 0x5489 TIOCSERSETMULTI = 0x5490 TIOCSERSWILD = 0x548a - TIOCSER_TEMT = 0x1 TIOCSETD = 0x7401 TIOCSETN = 0x740a TIOCSETP = 0x7409 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 71890c98..139deedd 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -481,7 +481,6 @@ const ( TIOCSERGWILD = 0x5489 TIOCSERSETMULTI = 0x5490 TIOCSERSWILD = 0x548a - TIOCSER_TEMT = 0x1 TIOCSETD = 0x7401 TIOCSETN = 0x740a TIOCSETP = 0x7409 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index a78b6cc1..b8018af3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -481,7 +481,6 @@ const ( TIOCSERGWILD = 0x5489 TIOCSERSETMULTI = 0x5490 TIOCSERSWILD = 0x548a - TIOCSER_TEMT = 0x1 TIOCSETD = 0x7401 TIOCSETN = 0x740a TIOCSETP = 0x7409 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index d0e38ca7..deb5c2e6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -481,7 +481,6 @@ const ( TIOCSERGWILD = 0x5489 TIOCSERSETMULTI = 0x5490 TIOCSERSWILD = 0x548a - TIOCSER_TEMT = 0x1 TIOCSETD = 0x7401 TIOCSETN = 0x740a TIOCSETP = 0x7409 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c883e14c..0603bf3a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -535,7 +535,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETC = 0x80067411 TIOCSETD = 0x5423 TIOCSETN = 0x8006740a diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 1834273d..5fa8a5d3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -539,7 +539,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETC = 0x80067411 TIOCSETD = 0x5423 TIOCSETN = 0x8006740a diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 39945dd9..2733e999 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -539,7 +539,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETC = 0x80067411 TIOCSETD = 0x5423 TIOCSETN = 0x8006740a diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index bc0f3724..1470172f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -486,7 +486,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 TIOCSISO7816 = 0xc0285443 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 6e87bd65..1871579c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -545,7 +545,6 @@ const ( TIOCSERGWILD = 0x5454 TIOCSERSETMULTI = 0x545b TIOCSERSWILD = 0x5455 - TIOCSER_TEMT = 0x1 TIOCSETD = 0x5423 TIOCSIG = 0x40045436 TIOCSISO7816 = 0xc0285443 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 7e2b2e8a..10881cf6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -14,21 +14,21 @@ const ( ASI_LEON_DFLUSH = 0x11 ASI_LEON_IFLUSH = 0x10 ASI_LEON_MMUFLUSH = 0x18 - B1000000 = 0x1008 + B1000000 = 0x100c B115200 = 0x1002 - B1152000 = 0x1009 - B1500000 = 0x100a - B2000000 = 0x100b + B1152000 = 0x100d + B1500000 = 0x100e + B153600 = 0x1006 + B2000000 = 0x100f B230400 = 0x1003 - B2500000 = 0x100c - B3000000 = 0x100d - B3500000 = 0x100e - B4000000 = 0x100f + B307200 = 0x1007 B460800 = 0x1004 - B500000 = 0x1005 + B500000 = 0x100a B57600 = 0x1001 - B576000 = 0x1006 - B921600 = 0x1007 + B576000 = 0x100b + B614400 = 0x1008 + B76800 = 0x1005 + B921600 = 0x1009 BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 @@ -91,7 +91,7 @@ const ( FFDLY = 0x8000 FICLONE = 0x80049409 FICLONERANGE = 0x8020940d - FLUSHO = 0x1000 + FLUSHO = 0x2000 FS_IOC_ENABLE_VERITY = 0x80806685 FS_IOC_GETFLAGS = 0x40086601 FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b @@ -563,6 +563,9 @@ const ( TIOCM_CD = 0x40 TIOCM_CTS = 0x20 TIOCM_DSR = 0x100 + TIOCM_LOOP = 0x8000 + TIOCM_OUT1 = 0x2000 + TIOCM_OUT2 = 0x4000 TIOCM_RI = 0x80 TIOCM_RNG = 0x80 TIOCM_SR = 0x10 @@ -641,10 +644,11 @@ const ( UBI_IOCVOLRMBLK = 0x20004f08 UBI_IOCVOLUP = 0x80084f00 VDISCARD = 0xd + VDSUSP = 0xb VEOF = 0x4 - VEOL = 0xb - VEOL2 = 0x10 - VMIN = 0x6 + VEOL = 0x5 + VEOL2 = 0x6 + VMIN = 0x4 VREPRINT = 0xc VSTART = 0x8 VSTOP = 0x9 @@ -664,6 +668,7 @@ const ( WDIOC_KEEPALIVE = 0x40045705 WDIOC_SETOPTIONS = 0x40045704 WORDSIZE = 0x40 + WRAP = 0x20000 XCASE = 0x4 XTABS = 0x1800 _HIDIOCGRAWNAME = 0x40804804 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 526a0d5f..538a18f2 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -4264,19 +4264,29 @@ type HwTstampConfig struct { } const ( - HWTSTAMP_FILTER_NONE = 0x0 - HWTSTAMP_FILTER_ALL = 0x1 - HWTSTAMP_FILTER_SOME = 0x2 - HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3 - HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6 - HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9 - HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc + HWTSTAMP_FILTER_NONE = 0x0 + HWTSTAMP_FILTER_ALL = 0x1 + HWTSTAMP_FILTER_SOME = 0x2 + HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3 + HWTSTAMP_FILTER_PTP_V1_L4_SYNC = 0x4 + HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ = 0x5 + HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6 + HWTSTAMP_FILTER_PTP_V2_L4_SYNC = 0x7 + HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ = 0x8 + HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9 + HWTSTAMP_FILTER_PTP_V2_L2_SYNC = 0xa + HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ = 0xb + HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc + HWTSTAMP_FILTER_PTP_V2_SYNC = 0xd + HWTSTAMP_FILTER_PTP_V2_DELAY_REQ = 0xe + HWTSTAMP_FILTER_NTP_ALL = 0xf ) const ( HWTSTAMP_TX_OFF = 0x0 HWTSTAMP_TX_ON = 0x1 HWTSTAMP_TX_ONESTEP_SYNC = 0x2 + HWTSTAMP_TX_ONESTEP_P2P = 0x3 ) type ( @@ -4541,6 +4551,48 @@ const ( LANDLOCK_RULE_PATH_BENEATH = 0x1 ) +const ( + PIDFD_SIGNAL_THREAD = 0x1 + PIDFD_SIGNAL_THREAD_GROUP = 0x2 + PIDFD_SIGNAL_PROCESS_GROUP = 0x4 + PIDFD_SELF_THREAD = -0x2710 + PIDFD_SELF_THREAD_GROUP = -0x2711 + PIDFD_SELF = -0x2710 + PIDFD_SELF_PROCESS = -0x2711 + PIDFD_INFO_PID = 0x1 + PIDFD_INFO_CREDS = 0x2 + PIDFD_INFO_CGROUPID = 0x4 + PIDFD_INFO_EXIT = 0x8 + PIDFD_INFO_COREDUMP = 0x10 + PIDFD_COREDUMPED = 0x1 + PIDFD_COREDUMP_SKIP = 0x2 + PIDFD_COREDUMP_USER = 0x4 + PIDFD_COREDUMP_ROOT = 0x8 + PIDFD_INFO_SIZE_VER0 = 0x40 + PIDFD_GET_INFO = 0xc048ff0b +) + +const SizeofPidfdInfo = 0x48 + +type PidfdInfo struct { + Mask uint64 + Cgroupid uint64 + Pid uint32 + Tgid uint32 + Ppid uint32 + Ruid uint32 + Rgid uint32 + Euid uint32 + Egid uint32 + Suid uint32 + Sgid uint32 + Fsuid uint32 + Fsgid uint32 + Exit_code int32 + Coredump_mask uint32 + _ uint32 +} + const ( IPC_CREAT = 0x200 IPC_EXCL = 0x400 @@ -6473,3 +6525,23 @@ type GPIOV2LineEvent struct { Line_seqno uint32 _ [6]uint32 } + +const ( + IPMI_MAX_ADDR_SIZE = 0x20 + IPMI_SYSTEM_INTERFACE_ADDR_TYPE = 0xc + IPMI_BMC_CHANNEL = 0xf + IPMI_RESPONSE_RECV_TYPE = 0x1 +) + +type IPMISystemInterfaceAddr struct { + Type int32 + Channel int16 + Lun uint8 + _ [1]byte +} +type IPMIMsg struct { + Netfn uint8 + Cmd uint8 + Len uint16 + Data *uint8 +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index aede1de7..38658a34 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -680,7 +680,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0xff01 + PIDFD_GET_IPC_NAMESPACE = 0xff02 + PIDFD_GET_MNT_NAMESPACE = 0xff03 + PIDFD_GET_NET_NAMESPACE = 0xff04 + PIDFD_GET_PID_NAMESPACE = 0xff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06 + PIDFD_GET_TIME_NAMESPACE = 0xff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08 + PIDFD_GET_USER_NAMESPACE = 0xff09 + PIDFD_GET_UTS_NAMESPACE = 0xff0a ) type SysvIpcPerm struct { @@ -715,3 +726,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x8044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x8014690d + IPMICTL_RECEIVE_MSG = 0xc018690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int32 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int32 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index bb3bc4dc..267ffe05 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -697,7 +697,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0xff01 + PIDFD_GET_IPC_NAMESPACE = 0xff02 + PIDFD_GET_MNT_NAMESPACE = 0xff03 + PIDFD_GET_NET_NAMESPACE = 0xff04 + PIDFD_GET_PID_NAMESPACE = 0xff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06 + PIDFD_GET_TIME_NAMESPACE = 0xff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08 + PIDFD_GET_USER_NAMESPACE = 0xff09 + PIDFD_GET_UTS_NAMESPACE = 0xff0a ) type SysvIpcPerm struct { @@ -729,3 +740,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x8044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x8028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index 1fdf4c51..ec459d5f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -674,7 +674,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0xff01 + PIDFD_GET_IPC_NAMESPACE = 0xff02 + PIDFD_GET_MNT_NAMESPACE = 0xff03 + PIDFD_GET_NET_NAMESPACE = 0xff04 + PIDFD_GET_PID_NAMESPACE = 0xff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06 + PIDFD_GET_TIME_NAMESPACE = 0xff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08 + PIDFD_GET_USER_NAMESPACE = 0xff09 + PIDFD_GET_UTS_NAMESPACE = 0xff0a ) type SysvIpcPerm struct { @@ -709,3 +720,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x8044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x8014690d + IPMICTL_RECEIVE_MSG = 0xc018690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int32 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int32 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index 063e6f0b..fa45ab7d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -676,7 +676,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0xff01 + PIDFD_GET_IPC_NAMESPACE = 0xff02 + PIDFD_GET_MNT_NAMESPACE = 0xff03 + PIDFD_GET_NET_NAMESPACE = 0xff04 + PIDFD_GET_PID_NAMESPACE = 0xff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06 + PIDFD_GET_TIME_NAMESPACE = 0xff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08 + PIDFD_GET_USER_NAMESPACE = 0xff09 + PIDFD_GET_UTS_NAMESPACE = 0xff0a ) type SysvIpcPerm struct { @@ -708,3 +719,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x8044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x8028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 9cf836c7..3da72ccd 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -677,7 +677,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0xff01 + PIDFD_GET_IPC_NAMESPACE = 0xff02 + PIDFD_GET_MNT_NAMESPACE = 0xff03 + PIDFD_GET_NET_NAMESPACE = 0xff04 + PIDFD_GET_PID_NAMESPACE = 0xff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06 + PIDFD_GET_TIME_NAMESPACE = 0xff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08 + PIDFD_GET_USER_NAMESPACE = 0xff09 + PIDFD_GET_UTS_NAMESPACE = 0xff0a ) type SysvIpcPerm struct { @@ -709,3 +720,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x8044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x8028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 1d222fcb..78f8c6d5 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -680,7 +680,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x80 + PIDFD_NONBLOCK = 0x80 + PIDFD_THREAD = 0x400 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -714,3 +725,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4014690d + IPMICTL_RECEIVE_MSG = 0xc018690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int32 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int32 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 912cc4ab..bbd4c6c2 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -679,7 +679,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x80 + PIDFD_NONBLOCK = 0x80 + PIDFD_THREAD = 0x400 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -711,3 +722,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index 1e358ef3..644d31d6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -679,7 +679,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x80 + PIDFD_NONBLOCK = 0x80 + PIDFD_THREAD = 0x400 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -711,3 +722,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index df59f32f..a976f626 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -680,7 +680,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x80 + PIDFD_NONBLOCK = 0x80 + PIDFD_THREAD = 0x400 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -714,3 +725,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4014690d + IPMICTL_RECEIVE_MSG = 0xc018690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int32 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int32 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index 29355aa0..46324695 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -686,7 +686,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -722,3 +733,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4014690d + IPMICTL_RECEIVE_MSG = 0xc018690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int32 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int32 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index c6083a15..cbc30397 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -686,7 +686,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -717,3 +728,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 6321cc76..b47f7b49 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -686,7 +686,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -717,3 +728,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index b44f402f..cb16add5 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -704,7 +704,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0xff01 + PIDFD_GET_IPC_NAMESPACE = 0xff02 + PIDFD_GET_MNT_NAMESPACE = 0xff03 + PIDFD_GET_NET_NAMESPACE = 0xff04 + PIDFD_GET_PID_NAMESPACE = 0xff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06 + PIDFD_GET_TIME_NAMESPACE = 0xff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08 + PIDFD_GET_USER_NAMESPACE = 0xff09 + PIDFD_GET_UTS_NAMESPACE = 0xff0a ) type SysvIpcPerm struct { @@ -796,3 +807,22 @@ const ( const ( GPIO_GET_CHIPINFO_IOCTL = 0x8044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x8028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index b22c795a..a57ab8fa 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -700,7 +700,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x800 + PIDFD_NONBLOCK = 0x800 + PIDFD_THREAD = 0x80 + PIDFD_GET_CGROUP_NAMESPACE = 0xff01 + PIDFD_GET_IPC_NAMESPACE = 0xff02 + PIDFD_GET_MNT_NAMESPACE = 0xff03 + PIDFD_GET_NET_NAMESPACE = 0xff04 + PIDFD_GET_PID_NAMESPACE = 0xff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0xff06 + PIDFD_GET_TIME_NAMESPACE = 0xff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0xff08 + PIDFD_GET_USER_NAMESPACE = 0xff09 + PIDFD_GET_UTS_NAMESPACE = 0xff0a ) type SysvIpcPerm struct { @@ -731,3 +742,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x8044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x8028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 0b18075b..bf99635d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -681,7 +681,18 @@ const ( ) const ( - PIDFD_NONBLOCK = 0x4000 + PIDFD_NONBLOCK = 0x4000 + PIDFD_THREAD = 0x800 + PIDFD_GET_CGROUP_NAMESPACE = 0x2000ff01 + PIDFD_GET_IPC_NAMESPACE = 0x2000ff02 + PIDFD_GET_MNT_NAMESPACE = 0x2000ff03 + PIDFD_GET_NET_NAMESPACE = 0x2000ff04 + PIDFD_GET_PID_NAMESPACE = 0x2000ff05 + PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE = 0x2000ff06 + PIDFD_GET_TIME_NAMESPACE = 0x2000ff07 + PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE = 0x2000ff08 + PIDFD_GET_USER_NAMESPACE = 0x2000ff09 + PIDFD_GET_UTS_NAMESPACE = 0x2000ff0a ) type SysvIpcPerm struct { @@ -712,3 +723,22 @@ type SysvShmDesc struct { const ( GPIO_GET_CHIPINFO_IOCTL = 0x4044b401 ) + +const ( + IPMICTL_SEND_COMMAND = 0x4028690d + IPMICTL_RECEIVE_MSG = 0xc030690c +) + +type IPMIReq struct { + Addr *uint8 + Len uint32 + Msgid int64 + Msg IPMIMsg +} +type IPMIRecv struct { + Recv_type int32 + Addr *uint8 + Addr_len uint32 + Msgid int64 + Msg IPMIMsg +} diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 75a50b31..643737d4 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1065,6 +1065,7 @@ const ( SO_BROADCAST = 32 SO_LINGER = 128 SO_RCVBUF = 0x1002 + SO_SNDTIMEO = 0x1005 SO_RCVTIMEO = 0x1006 SO_SNDBUF = 0x1001 SO_UPDATE_ACCEPT_CONTEXT = 0x700b diff --git a/vendor/golang.org/x/term/terminal.go b/vendor/golang.org/x/term/terminal.go index 6ec537cd..e8327c83 100644 --- a/vendor/golang.org/x/term/terminal.go +++ b/vendor/golang.org/x/term/terminal.go @@ -106,6 +106,9 @@ type Terminal struct { // a read. It aliases into inBuf. remainder []byte inBuf [256]byte + // readErr is an error returned by a read that also returned data. It is + // reported after all of that data has been processed. + readErr error // History records and retrieves lines of input read by [ReadLine] which // a user can retrieve and navigate using the up and down arrow keys. @@ -788,7 +791,11 @@ func (t *Terminal) ReadPassword(prompt string) (line string, err error) { return } -// ReadLine returns a line of input from the terminal. +// ReadLine returns a line of input from the terminal, excluding the +// trailing newline. It may return partial data along with an error. +// An [io.EOF] error indicates the end of the stream. For other errors, +// such as [ErrPasteIndicator] in bracketed paste mode, a subsequent +// call may return more data. func (t *Terminal) ReadLine() (line string, err error) { t.lock.Lock() defer t.lock.Unlock() @@ -863,21 +870,24 @@ func (t *Terminal) readLine() (line string, err error) { } return } + if t.readErr != nil { + err = t.readErr + t.readErr = nil + return + } // t.remainder is a slice at the beginning of t.inBuf // containing a partial key sequence readBuf := t.inBuf[len(t.remainder):] - var n int t.lock.Unlock() - n, err = t.c.Read(readBuf) + n, readErr := t.c.Read(readBuf) t.lock.Lock() - if err != nil { - return - } - t.remainder = t.inBuf[:n+len(t.remainder)] + if readErr != nil { + t.readErr = readErr + } } } diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index fb827323..e28ac8c8 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -6,7 +6,6 @@ package bidi import ( "fmt" - "log" ) // This implementation is a port based on the reference implementation found at: @@ -248,7 +247,7 @@ func (p *paragraph) determineParagraphEmbeddingLevel(start, end int) level { } else if t.in(FSI, LRI, RLI) { i = p.matchingPDI[i] // skip over to the matching PDI if i > end { - log.Panic("assert (i <= end)") + panic("assert (i <= end)") } } } @@ -729,7 +728,7 @@ loop: continue loop } } - log.Panicf("invalid bidi code %v present in assertOnly at position %d", t, s.indexes[i]) + panic(fmt.Errorf("invalid bidi code %v present in assertOnly at position %d", t, s.indexes[i])) } } diff --git a/vendor/golang.org/x/text/unicode/norm/composition.go b/vendor/golang.org/x/text/unicode/norm/composition.go index e2087bce..e024e74b 100644 --- a/vendor/golang.org/x/text/unicode/norm/composition.go +++ b/vendor/golang.org/x/text/unicode/norm/composition.go @@ -449,6 +449,16 @@ func (rb *reorderBuffer) combineHangul(s, i, k int) { // ACxx plus 11Ax to LVT rb.assignRune(s, l+v-jamoTBase) default: + // Not a Hangul composition. The segment may still + // contain regular canonical compositions, such as + // combining marks following a Hangul syllable, so + // fall back to the composition table. + if b[i].combinesBackward() { + if combined := combine(l, v); combined != 0 { + rb.assignRune(s, combined) + continue + } + } b[k] = b[i] k++ } @@ -484,25 +494,27 @@ func (rb *reorderBuffer) compose() { return } ii := b[i] + // Track the last starter unconditionally: b[i] must be blocked by + // any starter between it and s, even one that b[i] itself cannot + // combine with, and even if the runes in between never enter the + // combinesBackward branch below. + cccB := b[k-1].ccc + cccC := ii.ccc + blocked := false // b[i] blocked by starter or greater or equal CCC? + if cccB == 0 { + s = k - 1 + } else { + blocked = s != k-1 && cccB >= cccC + } // We can only use combineForward as a filter if we later // get the info for the combined character. This is more // expensive than using the filter. Using combinesBackward() // is safe. - if ii.combinesBackward() { - cccB := b[k-1].ccc - cccC := ii.ccc - blocked := false // b[i] blocked by starter or greater or equal CCC? - if cccB == 0 { - s = k - 1 - } else { - blocked = s != k-1 && cccB >= cccC - } - if !blocked { - combined := combine(rb.runeAt(s), rb.runeAt(i)) - if combined != 0 { - rb.assignRune(s, combined) - continue - } + if ii.combinesBackward() && !blocked { + combined := combine(rb.runeAt(s), rb.runeAt(i)) + if combined != 0 { + rb.assignRune(s, combined) + continue } } b[k] = b[i] diff --git a/vendor/golang.org/x/text/unicode/norm/forminfo.go b/vendor/golang.org/x/text/unicode/norm/forminfo.go index b3cf5d9b..956708ee 100644 --- a/vendor/golang.org/x/text/unicode/norm/forminfo.go +++ b/vendor/golang.org/x/text/unicode/norm/forminfo.go @@ -191,30 +191,30 @@ func (p Properties) TrailCCC() uint8 { return ccc[p.tccc] } +// Recomposition +// Each entry of recompMapPacked holds the two runes of the key and the +// composed rune of the value packed into a big-endian uint64 as three +// 21-bit fields, which is wide enough for any rune. +// Note that the recomposition map for NFC and NFKC are identical. + +const recompShift = 21 + func buildRecompMap() { - recompMap = make(map[uint32]rune, len(recompMapPacked)/8) + recompMap = make(map[uint64]rune, len(recompMapPacked)/8) var buf [8]byte for i := 0; i < len(recompMapPacked); i += 8 { copy(buf[:], recompMapPacked[i:i+8]) - key := binary.BigEndian.Uint32(buf[:4]) - val := binary.BigEndian.Uint32(buf[4:]) - recompMap[key] = rune(val) + e := binary.BigEndian.Uint64(buf[:]) + recompMap[e>>recompShift] = rune(e & (1<" + // 0x006C030C: 0x0000013E - "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 - "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 - "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 - "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 - "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 - "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 - "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C - "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D - "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E - "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F - "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 - "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 - "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 - "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 - "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 - "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 - "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 - "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 - "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A - "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B - "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C - "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D - "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E - "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F - "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 - "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 - "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 - "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 - "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 - "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 - "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 - "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 - "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A - "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B - "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C - "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D - "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E - "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F - "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 - "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 - "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 - "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 - "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 - "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 - "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 - "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 - "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 - "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 - "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A - "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B - "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C - "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D - "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E - "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 - "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 - "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF - "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 - "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD - "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE - "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF - "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 - "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 - "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 - "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 - "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 - "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 - "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 - "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 - "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 - "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 - "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA - "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB - "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC - "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE - "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF - "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 - "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 - "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 - "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 - "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 - "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 - "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 - "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 - "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA - "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB - "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC - "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED - "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE - "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF - "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 - "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 - "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 - "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 - "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 - "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA - "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB - "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC - "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD - "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE - "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF - "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 - "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 - "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 - "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 - "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 - "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 - "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 - "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 - "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 - "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 - "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A - "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B - "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C - "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D - "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E - "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F - "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 - "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 - "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 - "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 - "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 - "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 - "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 - "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 - "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 - "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 - "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A - "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B - "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E - "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F - "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 - "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 - "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 - "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 - "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A - "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B - "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C - "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D - "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E - "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F - "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 - "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 - "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 - "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 - "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 - "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 - "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 - "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 - "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A - "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C - "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E - "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F - "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 - "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA - "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB - "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC - "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD - "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE - "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF - "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 - "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA - "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB - "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC - "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD - "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE - "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 - "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 - "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 - "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 - "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 - "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 - "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C - "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D - "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E - "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 - "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 - "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 - "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 - "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 - "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 - "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C - "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D - "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E - "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 - "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 - "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 - "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 - "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 - "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 - "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 - "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 - "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 - "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 - "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA - "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB - "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC - "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD - "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE - "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF - "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 - "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 - "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 - "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 - "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 - "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 - "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA - "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB - "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC - "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED - "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE - "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF - "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 - "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 - "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 - "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 - "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 - "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 - "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 - "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 - "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 - "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 - "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 - "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 - "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 - "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 - "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 - "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 - "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 - "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 - "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 - "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB - "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC - "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 - "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B - "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C - "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 - "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA - "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB - "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC - "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 - "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 - "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 - "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 - "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA - "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB - "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A - "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B - "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C - "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA - "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC - "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD - "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE - "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 - "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 - "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 - "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A - "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C - "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E - "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 - "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B - "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D - "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 - "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 - "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 - "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 - "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 - "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 - "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 - "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 - "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 - "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 - "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 - "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 - "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 - "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A - "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B - "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C - "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D - "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E - "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F - "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 - "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 - "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 - "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 - "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 - "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 - "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 - "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 - "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 - "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 - "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A - "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B - "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C - "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D - "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E - "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F - "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 - "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 - "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 - "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 - "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 - "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 - "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 - "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 - "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 - "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 - "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A - "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B - "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C - "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D - "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E - "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F - "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 - "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 - "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 - "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 - "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 - "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 - "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 - "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 - "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 - "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 - "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A - "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B - "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C - "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D - "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E - "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F - "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 - "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 - "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 - "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 - "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 - "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 - "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 - "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 - "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 - "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 - "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A - "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B - "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C - "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D - "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E - "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F - "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 - "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 - "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 - "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 - "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 - "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 - "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 - "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 - "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 - "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 - "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A - "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B - "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C - "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D - "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E - "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F - "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 - "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 - "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 - "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 - "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 - "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 - "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 - "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 - "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 - "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 - "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A - "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B - "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C - "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D - "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E - "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F - "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 - "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 - "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 - "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 - "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 - "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 - "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 - "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 - "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 - "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 - "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A - "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B - "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C - "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D - "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E - "\x00v\x03#\x00\x00\x1e\x7f" + // 0x00760323: 0x00001E7F - "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 - "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 - "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 - "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 - "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 - "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 - "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 - "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 - "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 - "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 - "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A - "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B - "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C - "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D - "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E - "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F - "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 - "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 - "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 - "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 - "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 - "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 - "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 - "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 - "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 - "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 - "\x01\x7f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B - "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 - "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 - "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 - "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 - "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 - "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 - "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 - "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 - "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 - "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 - "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA - "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB - "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC - "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD - "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE - "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF - "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 - "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 - "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 - "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 - "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 - "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 - "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 - "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 - "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 - "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 - "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA - "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB - "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC - "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD - "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE - "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF - "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 - "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 - "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 - "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 - "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 - "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 - "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 - "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 - "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 - "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 - "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA - "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB - "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC - "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD - "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE - "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF - "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 - "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 - "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 - "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 - "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 - "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 - "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 - "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 - "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 - "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 - "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA - "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB - "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC - "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD - "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE - "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF - "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 - "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 - "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 - "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 - "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 - "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 - "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 - "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 - "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 - "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 - "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA - "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB - "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC - "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED - "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE - "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF - "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 - "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 - "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 - "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 - "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 - "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 - "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 - "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 - "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 - "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 - "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 - "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 - "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 - "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 - "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 - "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 - "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 - "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 - "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 - "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 - "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A - "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B - "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C - "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D - "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E - "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F - "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 - "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 - "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 - "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 - "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 - "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 - "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 - "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 - "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A - "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B - "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C - "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D - "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 - "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 - "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 - "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 - "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 - "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 - "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 - "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 - "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 - "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 - "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A - "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B - "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C - "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D - "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E - "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F - "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 - "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 - "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 - "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 - "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 - "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 - "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 - "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 - "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 - "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 - "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A - "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B - "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C - "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D - "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E - "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F - "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 - "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 - "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 - "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 - "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 - "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 - "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 - "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 - "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A - "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B - "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C - "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D - "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 - "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 - "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 - "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 - "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 - "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 - "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 - "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 - "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 - "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B - "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D - "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F - "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 - "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 - "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 - "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 - "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 - "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 - "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 - "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 - "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 - "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 - "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A - "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B - "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C - "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D - "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E - "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F - "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 - "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 - "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 - "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 - "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 - "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A - "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C - "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 - "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 - "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 - "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 - "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 - "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 - "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 - "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 - "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 - "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 - "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A - "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B - "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C - "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D - "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E - "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F - "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 - "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 - "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 - "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 - "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 - "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 - "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 - "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 - "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 - "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 - "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A - "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B - "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C - "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D - "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E - "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F - "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 - "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 - "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 - "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 - "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 - "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 - "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 - "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 - "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 - "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 - "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA - "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB - "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC - "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD - "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE - "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF - "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 - "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 - "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 - "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 - "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 - "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 - "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 - "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 - "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 - "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA - "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC - "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 - "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 - "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 - "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 - "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 - "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 - "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 - "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA - "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC - "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD - "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE - "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF - "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 - "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 - "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 - "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 - "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 - "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 - "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 - "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA - "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD - "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE - "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF - "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 - "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 - "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 - "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 - "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 - "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 - "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 - "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 - "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 - "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA - "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC - "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED - "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 - "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 - "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 - "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 - "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 - "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 - "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA - "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC - "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A - "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B - "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE - "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD - "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE - "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF - "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 - "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 - "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C - "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 - "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 - "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 - "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 - "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 - "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 - "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 - "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 - "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D - "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E - "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F - "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 - "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 - "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 - "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 - "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 - "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 - "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 - "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 - "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 - "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 - "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 - "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 - "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC - "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD - "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE - "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF - "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 - "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 - "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 - "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 - "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA - "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB - "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC - "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED - "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C - "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E - "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 - "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 - "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 - "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 - "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 - "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A - "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C - "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E - "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 - "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 - "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 - "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 - "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 - "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 - "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 - "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 - "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 - "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 - "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 - "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 - "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A - "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C - "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D - "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 - "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E - "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC - "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE - "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 - "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 - "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 - "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 - "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 - "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA - "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC - "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE - "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 - "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 - "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 - "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 - "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 - "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 - "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 - "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 - "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 - "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 - "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 - "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 - "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA - "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC - "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD - "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 - "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 - "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 - "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 - "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA - "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE - "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A - "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C - "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB - "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E - "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F - "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B - "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C - "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB - "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC - "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE - "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA - "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB - "\x195\x190\x00\x01\x198" + // 0x19351930: 0x00011938 + "\x00\x01\x04\x00`\x00\x00\xc0" + // 0x00041 0x00300: 0x000C0 + "\x00\x01\x04\x00` \x00\xc1" + // 0x00041 0x00301: 0x000C1 + "\x00\x01\x04\x00`@\x00\xc2" + // 0x00041 0x00302: 0x000C2 + "\x00\x01\x04\x00``\x00\xc3" + // 0x00041 0x00303: 0x000C3 + "\x00\x01\x04\x00a\x00\x00\xc4" + // 0x00041 0x00308: 0x000C4 + "\x00\x01\x04\x00a@\x00\xc5" + // 0x00041 0x0030A: 0x000C5 + "\x00\x01\f\x00d\xe0\x00\xc7" + // 0x00043 0x00327: 0x000C7 + "\x00\x01\x14\x00`\x00\x00\xc8" + // 0x00045 0x00300: 0x000C8 + "\x00\x01\x14\x00` \x00\xc9" + // 0x00045 0x00301: 0x000C9 + "\x00\x01\x14\x00`@\x00\xca" + // 0x00045 0x00302: 0x000CA + "\x00\x01\x14\x00a\x00\x00\xcb" + // 0x00045 0x00308: 0x000CB + "\x00\x01$\x00`\x00\x00\xcc" + // 0x00049 0x00300: 0x000CC + "\x00\x01$\x00` \x00\xcd" + // 0x00049 0x00301: 0x000CD + "\x00\x01$\x00`@\x00\xce" + // 0x00049 0x00302: 0x000CE + "\x00\x01$\x00a\x00\x00\xcf" + // 0x00049 0x00308: 0x000CF + "\x00\x018\x00``\x00\xd1" + // 0x0004E 0x00303: 0x000D1 + "\x00\x01<\x00`\x00\x00\xd2" + // 0x0004F 0x00300: 0x000D2 + "\x00\x01<\x00` \x00\xd3" + // 0x0004F 0x00301: 0x000D3 + "\x00\x01<\x00`@\x00\xd4" + // 0x0004F 0x00302: 0x000D4 + "\x00\x01<\x00``\x00\xd5" + // 0x0004F 0x00303: 0x000D5 + "\x00\x01<\x00a\x00\x00\xd6" + // 0x0004F 0x00308: 0x000D6 + "\x00\x01T\x00`\x00\x00\xd9" + // 0x00055 0x00300: 0x000D9 + "\x00\x01T\x00` \x00\xda" + // 0x00055 0x00301: 0x000DA + "\x00\x01T\x00`@\x00\xdb" + // 0x00055 0x00302: 0x000DB + "\x00\x01T\x00a\x00\x00\xdc" + // 0x00055 0x00308: 0x000DC + "\x00\x01d\x00` \x00\xdd" + // 0x00059 0x00301: 0x000DD + "\x00\x01\x84\x00`\x00\x00\xe0" + // 0x00061 0x00300: 0x000E0 + "\x00\x01\x84\x00` \x00\xe1" + // 0x00061 0x00301: 0x000E1 + "\x00\x01\x84\x00`@\x00\xe2" + // 0x00061 0x00302: 0x000E2 + "\x00\x01\x84\x00``\x00\xe3" + // 0x00061 0x00303: 0x000E3 + "\x00\x01\x84\x00a\x00\x00\xe4" + // 0x00061 0x00308: 0x000E4 + "\x00\x01\x84\x00a@\x00\xe5" + // 0x00061 0x0030A: 0x000E5 + "\x00\x01\x8c\x00d\xe0\x00\xe7" + // 0x00063 0x00327: 0x000E7 + "\x00\x01\x94\x00`\x00\x00\xe8" + // 0x00065 0x00300: 0x000E8 + "\x00\x01\x94\x00` \x00\xe9" + // 0x00065 0x00301: 0x000E9 + "\x00\x01\x94\x00`@\x00\xea" + // 0x00065 0x00302: 0x000EA + "\x00\x01\x94\x00a\x00\x00\xeb" + // 0x00065 0x00308: 0x000EB + "\x00\x01\xa4\x00`\x00\x00\xec" + // 0x00069 0x00300: 0x000EC + "\x00\x01\xa4\x00` \x00\xed" + // 0x00069 0x00301: 0x000ED + "\x00\x01\xa4\x00`@\x00\xee" + // 0x00069 0x00302: 0x000EE + "\x00\x01\xa4\x00a\x00\x00\xef" + // 0x00069 0x00308: 0x000EF + "\x00\x01\xb8\x00``\x00\xf1" + // 0x0006E 0x00303: 0x000F1 + "\x00\x01\xbc\x00`\x00\x00\xf2" + // 0x0006F 0x00300: 0x000F2 + "\x00\x01\xbc\x00` \x00\xf3" + // 0x0006F 0x00301: 0x000F3 + "\x00\x01\xbc\x00`@\x00\xf4" + // 0x0006F 0x00302: 0x000F4 + "\x00\x01\xbc\x00``\x00\xf5" + // 0x0006F 0x00303: 0x000F5 + "\x00\x01\xbc\x00a\x00\x00\xf6" + // 0x0006F 0x00308: 0x000F6 + "\x00\x01\xd4\x00`\x00\x00\xf9" + // 0x00075 0x00300: 0x000F9 + "\x00\x01\xd4\x00` \x00\xfa" + // 0x00075 0x00301: 0x000FA + "\x00\x01\xd4\x00`@\x00\xfb" + // 0x00075 0x00302: 0x000FB + "\x00\x01\xd4\x00a\x00\x00\xfc" + // 0x00075 0x00308: 0x000FC + "\x00\x01\xe4\x00` \x00\xfd" + // 0x00079 0x00301: 0x000FD + "\x00\x01\xe4\x00a\x00\x00\xff" + // 0x00079 0x00308: 0x000FF + "\x00\x01\x04\x00`\x80\x01\x00" + // 0x00041 0x00304: 0x00100 + "\x00\x01\x84\x00`\x80\x01\x01" + // 0x00061 0x00304: 0x00101 + "\x00\x01\x04\x00`\xc0\x01\x02" + // 0x00041 0x00306: 0x00102 + "\x00\x01\x84\x00`\xc0\x01\x03" + // 0x00061 0x00306: 0x00103 + "\x00\x01\x04\x00e\x00\x01\x04" + // 0x00041 0x00328: 0x00104 + "\x00\x01\x84\x00e\x00\x01\x05" + // 0x00061 0x00328: 0x00105 + "\x00\x01\f\x00` \x01\x06" + // 0x00043 0x00301: 0x00106 + "\x00\x01\x8c\x00` \x01\a" + // 0x00063 0x00301: 0x00107 + "\x00\x01\f\x00`@\x01\b" + // 0x00043 0x00302: 0x00108 + "\x00\x01\x8c\x00`@\x01\t" + // 0x00063 0x00302: 0x00109 + "\x00\x01\f\x00`\xe0\x01\n" + // 0x00043 0x00307: 0x0010A + "\x00\x01\x8c\x00`\xe0\x01\v" + // 0x00063 0x00307: 0x0010B + "\x00\x01\f\x00a\x80\x01\f" + // 0x00043 0x0030C: 0x0010C + "\x00\x01\x8c\x00a\x80\x01\r" + // 0x00063 0x0030C: 0x0010D + "\x00\x01\x10\x00a\x80\x01\x0e" + // 0x00044 0x0030C: 0x0010E + "\x00\x01\x90\x00a\x80\x01\x0f" + // 0x00064 0x0030C: 0x0010F + "\x00\x01\x14\x00`\x80\x01\x12" + // 0x00045 0x00304: 0x00112 + "\x00\x01\x94\x00`\x80\x01\x13" + // 0x00065 0x00304: 0x00113 + "\x00\x01\x14\x00`\xc0\x01\x14" + // 0x00045 0x00306: 0x00114 + "\x00\x01\x94\x00`\xc0\x01\x15" + // 0x00065 0x00306: 0x00115 + "\x00\x01\x14\x00`\xe0\x01\x16" + // 0x00045 0x00307: 0x00116 + "\x00\x01\x94\x00`\xe0\x01\x17" + // 0x00065 0x00307: 0x00117 + "\x00\x01\x14\x00e\x00\x01\x18" + // 0x00045 0x00328: 0x00118 + "\x00\x01\x94\x00e\x00\x01\x19" + // 0x00065 0x00328: 0x00119 + "\x00\x01\x14\x00a\x80\x01\x1a" + // 0x00045 0x0030C: 0x0011A + "\x00\x01\x94\x00a\x80\x01\x1b" + // 0x00065 0x0030C: 0x0011B + "\x00\x01\x1c\x00`@\x01\x1c" + // 0x00047 0x00302: 0x0011C + "\x00\x01\x9c\x00`@\x01\x1d" + // 0x00067 0x00302: 0x0011D + "\x00\x01\x1c\x00`\xc0\x01\x1e" + // 0x00047 0x00306: 0x0011E + "\x00\x01\x9c\x00`\xc0\x01\x1f" + // 0x00067 0x00306: 0x0011F + "\x00\x01\x1c\x00`\xe0\x01 " + // 0x00047 0x00307: 0x00120 + "\x00\x01\x9c\x00`\xe0\x01!" + // 0x00067 0x00307: 0x00121 + "\x00\x01\x1c\x00d\xe0\x01\"" + // 0x00047 0x00327: 0x00122 + "\x00\x01\x9c\x00d\xe0\x01#" + // 0x00067 0x00327: 0x00123 + "\x00\x01 \x00`@\x01$" + // 0x00048 0x00302: 0x00124 + "\x00\x01\xa0\x00`@\x01%" + // 0x00068 0x00302: 0x00125 + "\x00\x01$\x00``\x01(" + // 0x00049 0x00303: 0x00128 + "\x00\x01\xa4\x00``\x01)" + // 0x00069 0x00303: 0x00129 + "\x00\x01$\x00`\x80\x01*" + // 0x00049 0x00304: 0x0012A + "\x00\x01\xa4\x00`\x80\x01+" + // 0x00069 0x00304: 0x0012B + "\x00\x01$\x00`\xc0\x01," + // 0x00049 0x00306: 0x0012C + "\x00\x01\xa4\x00`\xc0\x01-" + // 0x00069 0x00306: 0x0012D + "\x00\x01$\x00e\x00\x01." + // 0x00049 0x00328: 0x0012E + "\x00\x01\xa4\x00e\x00\x01/" + // 0x00069 0x00328: 0x0012F + "\x00\x01$\x00`\xe0\x010" + // 0x00049 0x00307: 0x00130 + "\x00\x01(\x00`@\x014" + // 0x0004A 0x00302: 0x00134 + "\x00\x01\xa8\x00`@\x015" + // 0x0006A 0x00302: 0x00135 + "\x00\x01,\x00d\xe0\x016" + // 0x0004B 0x00327: 0x00136 + "\x00\x01\xac\x00d\xe0\x017" + // 0x0006B 0x00327: 0x00137 + "\x00\x010\x00` \x019" + // 0x0004C 0x00301: 0x00139 + "\x00\x01\xb0\x00` \x01:" + // 0x0006C 0x00301: 0x0013A + "\x00\x010\x00d\xe0\x01;" + // 0x0004C 0x00327: 0x0013B + "\x00\x01\xb0\x00d\xe0\x01<" + // 0x0006C 0x00327: 0x0013C + "\x00\x010\x00a\x80\x01=" + // 0x0004C 0x0030C: 0x0013D + "\x00\x01\xb0\x00a\x80\x01>" + // 0x0006C 0x0030C: 0x0013E + "\x00\x018\x00` \x01C" + // 0x0004E 0x00301: 0x00143 + "\x00\x01\xb8\x00` \x01D" + // 0x0006E 0x00301: 0x00144 + "\x00\x018\x00d\xe0\x01E" + // 0x0004E 0x00327: 0x00145 + "\x00\x01\xb8\x00d\xe0\x01F" + // 0x0006E 0x00327: 0x00146 + "\x00\x018\x00a\x80\x01G" + // 0x0004E 0x0030C: 0x00147 + "\x00\x01\xb8\x00a\x80\x01H" + // 0x0006E 0x0030C: 0x00148 + "\x00\x01<\x00`\x80\x01L" + // 0x0004F 0x00304: 0x0014C + "\x00\x01\xbc\x00`\x80\x01M" + // 0x0006F 0x00304: 0x0014D + "\x00\x01<\x00`\xc0\x01N" + // 0x0004F 0x00306: 0x0014E + "\x00\x01\xbc\x00`\xc0\x01O" + // 0x0006F 0x00306: 0x0014F + "\x00\x01<\x00a`\x01P" + // 0x0004F 0x0030B: 0x00150 + "\x00\x01\xbc\x00a`\x01Q" + // 0x0006F 0x0030B: 0x00151 + "\x00\x01H\x00` \x01T" + // 0x00052 0x00301: 0x00154 + "\x00\x01\xc8\x00` \x01U" + // 0x00072 0x00301: 0x00155 + "\x00\x01H\x00d\xe0\x01V" + // 0x00052 0x00327: 0x00156 + "\x00\x01\xc8\x00d\xe0\x01W" + // 0x00072 0x00327: 0x00157 + "\x00\x01H\x00a\x80\x01X" + // 0x00052 0x0030C: 0x00158 + "\x00\x01\xc8\x00a\x80\x01Y" + // 0x00072 0x0030C: 0x00159 + "\x00\x01L\x00` \x01Z" + // 0x00053 0x00301: 0x0015A + "\x00\x01\xcc\x00` \x01[" + // 0x00073 0x00301: 0x0015B + "\x00\x01L\x00`@\x01\\" + // 0x00053 0x00302: 0x0015C + "\x00\x01\xcc\x00`@\x01]" + // 0x00073 0x00302: 0x0015D + "\x00\x01L\x00d\xe0\x01^" + // 0x00053 0x00327: 0x0015E + "\x00\x01\xcc\x00d\xe0\x01_" + // 0x00073 0x00327: 0x0015F + "\x00\x01L\x00a\x80\x01`" + // 0x00053 0x0030C: 0x00160 + "\x00\x01\xcc\x00a\x80\x01a" + // 0x00073 0x0030C: 0x00161 + "\x00\x01P\x00d\xe0\x01b" + // 0x00054 0x00327: 0x00162 + "\x00\x01\xd0\x00d\xe0\x01c" + // 0x00074 0x00327: 0x00163 + "\x00\x01P\x00a\x80\x01d" + // 0x00054 0x0030C: 0x00164 + "\x00\x01\xd0\x00a\x80\x01e" + // 0x00074 0x0030C: 0x00165 + "\x00\x01T\x00``\x01h" + // 0x00055 0x00303: 0x00168 + "\x00\x01\xd4\x00``\x01i" + // 0x00075 0x00303: 0x00169 + "\x00\x01T\x00`\x80\x01j" + // 0x00055 0x00304: 0x0016A + "\x00\x01\xd4\x00`\x80\x01k" + // 0x00075 0x00304: 0x0016B + "\x00\x01T\x00`\xc0\x01l" + // 0x00055 0x00306: 0x0016C + "\x00\x01\xd4\x00`\xc0\x01m" + // 0x00075 0x00306: 0x0016D + "\x00\x01T\x00a@\x01n" + // 0x00055 0x0030A: 0x0016E + "\x00\x01\xd4\x00a@\x01o" + // 0x00075 0x0030A: 0x0016F + "\x00\x01T\x00a`\x01p" + // 0x00055 0x0030B: 0x00170 + "\x00\x01\xd4\x00a`\x01q" + // 0x00075 0x0030B: 0x00171 + "\x00\x01T\x00e\x00\x01r" + // 0x00055 0x00328: 0x00172 + "\x00\x01\xd4\x00e\x00\x01s" + // 0x00075 0x00328: 0x00173 + "\x00\x01\\\x00`@\x01t" + // 0x00057 0x00302: 0x00174 + "\x00\x01\xdc\x00`@\x01u" + // 0x00077 0x00302: 0x00175 + "\x00\x01d\x00`@\x01v" + // 0x00059 0x00302: 0x00176 + "\x00\x01\xe4\x00`@\x01w" + // 0x00079 0x00302: 0x00177 + "\x00\x01d\x00a\x00\x01x" + // 0x00059 0x00308: 0x00178 + "\x00\x01h\x00` \x01y" + // 0x0005A 0x00301: 0x00179 + "\x00\x01\xe8\x00` \x01z" + // 0x0007A 0x00301: 0x0017A + "\x00\x01h\x00`\xe0\x01{" + // 0x0005A 0x00307: 0x0017B + "\x00\x01\xe8\x00`\xe0\x01|" + // 0x0007A 0x00307: 0x0017C + "\x00\x01h\x00a\x80\x01}" + // 0x0005A 0x0030C: 0x0017D + "\x00\x01\xe8\x00a\x80\x01~" + // 0x0007A 0x0030C: 0x0017E + "\x00\x01<\x00c`\x01\xa0" + // 0x0004F 0x0031B: 0x001A0 + "\x00\x01\xbc\x00c`\x01\xa1" + // 0x0006F 0x0031B: 0x001A1 + "\x00\x01T\x00c`\x01\xaf" + // 0x00055 0x0031B: 0x001AF + "\x00\x01\xd4\x00c`\x01\xb0" + // 0x00075 0x0031B: 0x001B0 + "\x00\x01\x04\x00a\x80\x01\xcd" + // 0x00041 0x0030C: 0x001CD + "\x00\x01\x84\x00a\x80\x01\xce" + // 0x00061 0x0030C: 0x001CE + "\x00\x01$\x00a\x80\x01\xcf" + // 0x00049 0x0030C: 0x001CF + "\x00\x01\xa4\x00a\x80\x01\xd0" + // 0x00069 0x0030C: 0x001D0 + "\x00\x01<\x00a\x80\x01\xd1" + // 0x0004F 0x0030C: 0x001D1 + "\x00\x01\xbc\x00a\x80\x01\xd2" + // 0x0006F 0x0030C: 0x001D2 + "\x00\x01T\x00a\x80\x01\xd3" + // 0x00055 0x0030C: 0x001D3 + "\x00\x01\xd4\x00a\x80\x01\xd4" + // 0x00075 0x0030C: 0x001D4 + "\x00\x03p\x00`\x80\x01\xd5" + // 0x000DC 0x00304: 0x001D5 + "\x00\x03\xf0\x00`\x80\x01\xd6" + // 0x000FC 0x00304: 0x001D6 + "\x00\x03p\x00` \x01\xd7" + // 0x000DC 0x00301: 0x001D7 + "\x00\x03\xf0\x00` \x01\xd8" + // 0x000FC 0x00301: 0x001D8 + "\x00\x03p\x00a\x80\x01\xd9" + // 0x000DC 0x0030C: 0x001D9 + "\x00\x03\xf0\x00a\x80\x01\xda" + // 0x000FC 0x0030C: 0x001DA + "\x00\x03p\x00`\x00\x01\xdb" + // 0x000DC 0x00300: 0x001DB + "\x00\x03\xf0\x00`\x00\x01\xdc" + // 0x000FC 0x00300: 0x001DC + "\x00\x03\x10\x00`\x80\x01\xde" + // 0x000C4 0x00304: 0x001DE + "\x00\x03\x90\x00`\x80\x01\xdf" + // 0x000E4 0x00304: 0x001DF + "\x00\b\x98\x00`\x80\x01\xe0" + // 0x00226 0x00304: 0x001E0 + "\x00\b\x9c\x00`\x80\x01\xe1" + // 0x00227 0x00304: 0x001E1 + "\x00\x03\x18\x00`\x80\x01\xe2" + // 0x000C6 0x00304: 0x001E2 + "\x00\x03\x98\x00`\x80\x01\xe3" + // 0x000E6 0x00304: 0x001E3 + "\x00\x01\x1c\x00a\x80\x01\xe6" + // 0x00047 0x0030C: 0x001E6 + "\x00\x01\x9c\x00a\x80\x01\xe7" + // 0x00067 0x0030C: 0x001E7 + "\x00\x01,\x00a\x80\x01\xe8" + // 0x0004B 0x0030C: 0x001E8 + "\x00\x01\xac\x00a\x80\x01\xe9" + // 0x0006B 0x0030C: 0x001E9 + "\x00\x01<\x00e\x00\x01\xea" + // 0x0004F 0x00328: 0x001EA + "\x00\x01\xbc\x00e\x00\x01\xeb" + // 0x0006F 0x00328: 0x001EB + "\x00\a\xa8\x00`\x80\x01\xec" + // 0x001EA 0x00304: 0x001EC + "\x00\a\xac\x00`\x80\x01\xed" + // 0x001EB 0x00304: 0x001ED + "\x00\x06\xdc\x00a\x80\x01\xee" + // 0x001B7 0x0030C: 0x001EE + "\x00\nH\x00a\x80\x01\xef" + // 0x00292 0x0030C: 0x001EF + "\x00\x01\xa8\x00a\x80\x01\xf0" + // 0x0006A 0x0030C: 0x001F0 + "\x00\x01\x1c\x00` \x01\xf4" + // 0x00047 0x00301: 0x001F4 + "\x00\x01\x9c\x00` \x01\xf5" + // 0x00067 0x00301: 0x001F5 + "\x00\x018\x00`\x00\x01\xf8" + // 0x0004E 0x00300: 0x001F8 + "\x00\x01\xb8\x00`\x00\x01\xf9" + // 0x0006E 0x00300: 0x001F9 + "\x00\x03\x14\x00` \x01\xfa" + // 0x000C5 0x00301: 0x001FA + "\x00\x03\x94\x00` \x01\xfb" + // 0x000E5 0x00301: 0x001FB + "\x00\x03\x18\x00` \x01\xfc" + // 0x000C6 0x00301: 0x001FC + "\x00\x03\x98\x00` \x01\xfd" + // 0x000E6 0x00301: 0x001FD + "\x00\x03`\x00` \x01\xfe" + // 0x000D8 0x00301: 0x001FE + "\x00\x03\xe0\x00` \x01\xff" + // 0x000F8 0x00301: 0x001FF + "\x00\x01\x04\x00a\xe0\x02\x00" + // 0x00041 0x0030F: 0x00200 + "\x00\x01\x84\x00a\xe0\x02\x01" + // 0x00061 0x0030F: 0x00201 + "\x00\x01\x04\x00b \x02\x02" + // 0x00041 0x00311: 0x00202 + "\x00\x01\x84\x00b \x02\x03" + // 0x00061 0x00311: 0x00203 + "\x00\x01\x14\x00a\xe0\x02\x04" + // 0x00045 0x0030F: 0x00204 + "\x00\x01\x94\x00a\xe0\x02\x05" + // 0x00065 0x0030F: 0x00205 + "\x00\x01\x14\x00b \x02\x06" + // 0x00045 0x00311: 0x00206 + "\x00\x01\x94\x00b \x02\a" + // 0x00065 0x00311: 0x00207 + "\x00\x01$\x00a\xe0\x02\b" + // 0x00049 0x0030F: 0x00208 + "\x00\x01\xa4\x00a\xe0\x02\t" + // 0x00069 0x0030F: 0x00209 + "\x00\x01$\x00b \x02\n" + // 0x00049 0x00311: 0x0020A + "\x00\x01\xa4\x00b \x02\v" + // 0x00069 0x00311: 0x0020B + "\x00\x01<\x00a\xe0\x02\f" + // 0x0004F 0x0030F: 0x0020C + "\x00\x01\xbc\x00a\xe0\x02\r" + // 0x0006F 0x0030F: 0x0020D + "\x00\x01<\x00b \x02\x0e" + // 0x0004F 0x00311: 0x0020E + "\x00\x01\xbc\x00b \x02\x0f" + // 0x0006F 0x00311: 0x0020F + "\x00\x01H\x00a\xe0\x02\x10" + // 0x00052 0x0030F: 0x00210 + "\x00\x01\xc8\x00a\xe0\x02\x11" + // 0x00072 0x0030F: 0x00211 + "\x00\x01H\x00b \x02\x12" + // 0x00052 0x00311: 0x00212 + "\x00\x01\xc8\x00b \x02\x13" + // 0x00072 0x00311: 0x00213 + "\x00\x01T\x00a\xe0\x02\x14" + // 0x00055 0x0030F: 0x00214 + "\x00\x01\xd4\x00a\xe0\x02\x15" + // 0x00075 0x0030F: 0x00215 + "\x00\x01T\x00b \x02\x16" + // 0x00055 0x00311: 0x00216 + "\x00\x01\xd4\x00b \x02\x17" + // 0x00075 0x00311: 0x00217 + "\x00\x01L\x00d\xc0\x02\x18" + // 0x00053 0x00326: 0x00218 + "\x00\x01\xcc\x00d\xc0\x02\x19" + // 0x00073 0x00326: 0x00219 + "\x00\x01P\x00d\xc0\x02\x1a" + // 0x00054 0x00326: 0x0021A + "\x00\x01\xd0\x00d\xc0\x02\x1b" + // 0x00074 0x00326: 0x0021B + "\x00\x01 \x00a\x80\x02\x1e" + // 0x00048 0x0030C: 0x0021E + "\x00\x01\xa0\x00a\x80\x02\x1f" + // 0x00068 0x0030C: 0x0021F + "\x00\x01\x04\x00`\xe0\x02&" + // 0x00041 0x00307: 0x00226 + "\x00\x01\x84\x00`\xe0\x02'" + // 0x00061 0x00307: 0x00227 + "\x00\x01\x14\x00d\xe0\x02(" + // 0x00045 0x00327: 0x00228 + "\x00\x01\x94\x00d\xe0\x02)" + // 0x00065 0x00327: 0x00229 + "\x00\x03X\x00`\x80\x02*" + // 0x000D6 0x00304: 0x0022A + "\x00\x03\xd8\x00`\x80\x02+" + // 0x000F6 0x00304: 0x0022B + "\x00\x03T\x00`\x80\x02," + // 0x000D5 0x00304: 0x0022C + "\x00\x03\xd4\x00`\x80\x02-" + // 0x000F5 0x00304: 0x0022D + "\x00\x01<\x00`\xe0\x02." + // 0x0004F 0x00307: 0x0022E + "\x00\x01\xbc\x00`\xe0\x02/" + // 0x0006F 0x00307: 0x0022F + "\x00\b\xb8\x00`\x80\x020" + // 0x0022E 0x00304: 0x00230 + "\x00\b\xbc\x00`\x80\x021" + // 0x0022F 0x00304: 0x00231 + "\x00\x01d\x00`\x80\x022" + // 0x00059 0x00304: 0x00232 + "\x00\x01\xe4\x00`\x80\x023" + // 0x00079 0x00304: 0x00233 + "\x00\x02\xa0\x00` \x03\x85" + // 0x000A8 0x00301: 0x00385 + "\x00\x0eD\x00` \x03\x86" + // 0x00391 0x00301: 0x00386 + "\x00\x0eT\x00` \x03\x88" + // 0x00395 0x00301: 0x00388 + "\x00\x0e\\\x00` \x03\x89" + // 0x00397 0x00301: 0x00389 + "\x00\x0ed\x00` \x03\x8a" + // 0x00399 0x00301: 0x0038A + "\x00\x0e|\x00` \x03\x8c" + // 0x0039F 0x00301: 0x0038C + "\x00\x0e\x94\x00` \x03\x8e" + // 0x003A5 0x00301: 0x0038E + "\x00\x0e\xa4\x00` \x03\x8f" + // 0x003A9 0x00301: 0x0038F + "\x00\x0f(\x00` \x03\x90" + // 0x003CA 0x00301: 0x00390 + "\x00\x0ed\x00a\x00\x03\xaa" + // 0x00399 0x00308: 0x003AA + "\x00\x0e\x94\x00a\x00\x03\xab" + // 0x003A5 0x00308: 0x003AB + "\x00\x0e\xc4\x00` \x03\xac" + // 0x003B1 0x00301: 0x003AC + "\x00\x0e\xd4\x00` \x03\xad" + // 0x003B5 0x00301: 0x003AD + "\x00\x0e\xdc\x00` \x03\xae" + // 0x003B7 0x00301: 0x003AE + "\x00\x0e\xe4\x00` \x03\xaf" + // 0x003B9 0x00301: 0x003AF + "\x00\x0f,\x00` \x03\xb0" + // 0x003CB 0x00301: 0x003B0 + "\x00\x0e\xe4\x00a\x00\x03\xca" + // 0x003B9 0x00308: 0x003CA + "\x00\x0f\x14\x00a\x00\x03\xcb" + // 0x003C5 0x00308: 0x003CB + "\x00\x0e\xfc\x00` \x03\xcc" + // 0x003BF 0x00301: 0x003CC + "\x00\x0f\x14\x00` \x03\xcd" + // 0x003C5 0x00301: 0x003CD + "\x00\x0f$\x00` \x03\xce" + // 0x003C9 0x00301: 0x003CE + "\x00\x0fH\x00` \x03\xd3" + // 0x003D2 0x00301: 0x003D3 + "\x00\x0fH\x00a\x00\x03\xd4" + // 0x003D2 0x00308: 0x003D4 + "\x00\x10T\x00`\x00\x04\x00" + // 0x00415 0x00300: 0x00400 + "\x00\x10T\x00a\x00\x04\x01" + // 0x00415 0x00308: 0x00401 + "\x00\x10L\x00` \x04\x03" + // 0x00413 0x00301: 0x00403 + "\x00\x10\x18\x00a\x00\x04\a" + // 0x00406 0x00308: 0x00407 + "\x00\x10h\x00` \x04\f" + // 0x0041A 0x00301: 0x0040C + "\x00\x10`\x00`\x00\x04\r" + // 0x00418 0x00300: 0x0040D + "\x00\x10\x8c\x00`\xc0\x04\x0e" + // 0x00423 0x00306: 0x0040E + "\x00\x10`\x00`\xc0\x04\x19" + // 0x00418 0x00306: 0x00419 + "\x00\x10\xe0\x00`\xc0\x049" + // 0x00438 0x00306: 0x00439 + "\x00\x10\xd4\x00`\x00\x04P" + // 0x00435 0x00300: 0x00450 + "\x00\x10\xd4\x00a\x00\x04Q" + // 0x00435 0x00308: 0x00451 + "\x00\x10\xcc\x00` \x04S" + // 0x00433 0x00301: 0x00453 + "\x00\x11X\x00a\x00\x04W" + // 0x00456 0x00308: 0x00457 + "\x00\x10\xe8\x00` \x04\\" + // 0x0043A 0x00301: 0x0045C + "\x00\x10\xe0\x00`\x00\x04]" + // 0x00438 0x00300: 0x0045D + "\x00\x11\f\x00`\xc0\x04^" + // 0x00443 0x00306: 0x0045E + "\x00\x11\xd0\x00a\xe0\x04v" + // 0x00474 0x0030F: 0x00476 + "\x00\x11\xd4\x00a\xe0\x04w" + // 0x00475 0x0030F: 0x00477 + "\x00\x10X\x00`\xc0\x04\xc1" + // 0x00416 0x00306: 0x004C1 + "\x00\x10\xd8\x00`\xc0\x04\xc2" + // 0x00436 0x00306: 0x004C2 + "\x00\x10@\x00`\xc0\x04\xd0" + // 0x00410 0x00306: 0x004D0 + "\x00\x10\xc0\x00`\xc0\x04\xd1" + // 0x00430 0x00306: 0x004D1 + "\x00\x10@\x00a\x00\x04\xd2" + // 0x00410 0x00308: 0x004D2 + "\x00\x10\xc0\x00a\x00\x04\xd3" + // 0x00430 0x00308: 0x004D3 + "\x00\x10T\x00`\xc0\x04\xd6" + // 0x00415 0x00306: 0x004D6 + "\x00\x10\xd4\x00`\xc0\x04\xd7" + // 0x00435 0x00306: 0x004D7 + "\x00\x13`\x00a\x00\x04\xda" + // 0x004D8 0x00308: 0x004DA + "\x00\x13d\x00a\x00\x04\xdb" + // 0x004D9 0x00308: 0x004DB + "\x00\x10X\x00a\x00\x04\xdc" + // 0x00416 0x00308: 0x004DC + "\x00\x10\xd8\x00a\x00\x04\xdd" + // 0x00436 0x00308: 0x004DD + "\x00\x10\\\x00a\x00\x04\xde" + // 0x00417 0x00308: 0x004DE + "\x00\x10\xdc\x00a\x00\x04\xdf" + // 0x00437 0x00308: 0x004DF + "\x00\x10`\x00`\x80\x04\xe2" + // 0x00418 0x00304: 0x004E2 + "\x00\x10\xe0\x00`\x80\x04\xe3" + // 0x00438 0x00304: 0x004E3 + "\x00\x10`\x00a\x00\x04\xe4" + // 0x00418 0x00308: 0x004E4 + "\x00\x10\xe0\x00a\x00\x04\xe5" + // 0x00438 0x00308: 0x004E5 + "\x00\x10x\x00a\x00\x04\xe6" + // 0x0041E 0x00308: 0x004E6 + "\x00\x10\xf8\x00a\x00\x04\xe7" + // 0x0043E 0x00308: 0x004E7 + "\x00\x13\xa0\x00a\x00\x04\xea" + // 0x004E8 0x00308: 0x004EA + "\x00\x13\xa4\x00a\x00\x04\xeb" + // 0x004E9 0x00308: 0x004EB + "\x00\x10\xb4\x00a\x00\x04\xec" + // 0x0042D 0x00308: 0x004EC + "\x00\x114\x00a\x00\x04\xed" + // 0x0044D 0x00308: 0x004ED + "\x00\x10\x8c\x00`\x80\x04\xee" + // 0x00423 0x00304: 0x004EE + "\x00\x11\f\x00`\x80\x04\xef" + // 0x00443 0x00304: 0x004EF + "\x00\x10\x8c\x00a\x00\x04\xf0" + // 0x00423 0x00308: 0x004F0 + "\x00\x11\f\x00a\x00\x04\xf1" + // 0x00443 0x00308: 0x004F1 + "\x00\x10\x8c\x00a`\x04\xf2" + // 0x00423 0x0030B: 0x004F2 + "\x00\x11\f\x00a`\x04\xf3" + // 0x00443 0x0030B: 0x004F3 + "\x00\x10\x9c\x00a\x00\x04\xf4" + // 0x00427 0x00308: 0x004F4 + "\x00\x11\x1c\x00a\x00\x04\xf5" + // 0x00447 0x00308: 0x004F5 + "\x00\x10\xac\x00a\x00\x04\xf8" + // 0x0042B 0x00308: 0x004F8 + "\x00\x11,\x00a\x00\x04\xf9" + // 0x0044B 0x00308: 0x004F9 + "\x00\x18\x9c\x00\xca`\x06\"" + // 0x00627 0x00653: 0x00622 + "\x00\x18\x9c\x00ʀ\x06#" + // 0x00627 0x00654: 0x00623 + "\x00\x19 \x00ʀ\x06$" + // 0x00648 0x00654: 0x00624 + "\x00\x18\x9c\x00ʠ\x06%" + // 0x00627 0x00655: 0x00625 + "\x00\x19(\x00ʀ\x06&" + // 0x0064A 0x00654: 0x00626 + "\x00\x1bT\x00ʀ\x06\xc0" + // 0x006D5 0x00654: 0x006C0 + "\x00\x1b\x04\x00ʀ\x06\xc2" + // 0x006C1 0x00654: 0x006C2 + "\x00\x1bH\x00ʀ\x06\xd3" + // 0x006D2 0x00654: 0x006D3 + "\x00$\xa0\x01'\x80\t)" + // 0x00928 0x0093C: 0x00929 + "\x00$\xc0\x01'\x80\t1" + // 0x00930 0x0093C: 0x00931 + "\x00$\xcc\x01'\x80\t4" + // 0x00933 0x0093C: 0x00934 + "\x00'\x1c\x017\xc0\t\xcb" + // 0x009C7 0x009BE: 0x009CB + "\x00'\x1c\x01:\xe0\t\xcc" + // 0x009C7 0x009D7: 0x009CC + "\x00-\x1c\x01j\xc0\vH" + // 0x00B47 0x00B56: 0x00B48 + "\x00-\x1c\x01g\xc0\vK" + // 0x00B47 0x00B3E: 0x00B4B + "\x00-\x1c\x01j\xe0\vL" + // 0x00B47 0x00B57: 0x00B4C + "\x00.H\x01z\xe0\v\x94" + // 0x00B92 0x00BD7: 0x00B94 + "\x00/\x18\x01w\xc0\v\xca" + // 0x00BC6 0x00BBE: 0x00BCA + "\x00/\x1c\x01w\xc0\v\xcb" + // 0x00BC7 0x00BBE: 0x00BCB + "\x00/\x18\x01z\xe0\v\xcc" + // 0x00BC6 0x00BD7: 0x00BCC + "\x001\x18\x01\x8a\xc0\fH" + // 0x00C46 0x00C56: 0x00C48 + "\x002\xfc\x01\x9a\xa0\f\xc0" + // 0x00CBF 0x00CD5: 0x00CC0 + "\x003\x18\x01\x9a\xa0\f\xc7" + // 0x00CC6 0x00CD5: 0x00CC7 + "\x003\x18\x01\x9a\xc0\f\xc8" + // 0x00CC6 0x00CD6: 0x00CC8 + "\x003\x18\x01\x98@\f\xca" + // 0x00CC6 0x00CC2: 0x00CCA + "\x003(\x01\x9a\xa0\f\xcb" + // 0x00CCA 0x00CD5: 0x00CCB + "\x005\x18\x01\xa7\xc0\rJ" + // 0x00D46 0x00D3E: 0x00D4A + "\x005\x1c\x01\xa7\xc0\rK" + // 0x00D47 0x00D3E: 0x00D4B + "\x005\x18\x01\xaa\xe0\rL" + // 0x00D46 0x00D57: 0x00D4C + "\x007d\x01\xb9@\r\xda" + // 0x00DD9 0x00DCA: 0x00DDA + "\x007d\x01\xb9\xe0\r\xdc" + // 0x00DD9 0x00DCF: 0x00DDC + "\x007p\x01\xb9@\r\xdd" + // 0x00DDC 0x00DCA: 0x00DDD + "\x007d\x01\xbb\xe0\r\xde" + // 0x00DD9 0x00DDF: 0x00DDE + "\x00@\x94\x02\x05\xc0\x10&" + // 0x01025 0x0102E: 0x01026 + "\x00l\x14\x03f\xa0\x1b\x06" + // 0x01B05 0x01B35: 0x01B06 + "\x00l\x1c\x03f\xa0\x1b\b" + // 0x01B07 0x01B35: 0x01B08 + "\x00l$\x03f\xa0\x1b\n" + // 0x01B09 0x01B35: 0x01B0A + "\x00l,\x03f\xa0\x1b\f" + // 0x01B0B 0x01B35: 0x01B0C + "\x00l4\x03f\xa0\x1b\x0e" + // 0x01B0D 0x01B35: 0x01B0E + "\x00lD\x03f\xa0\x1b\x12" + // 0x01B11 0x01B35: 0x01B12 + "\x00l\xe8\x03f\xa0\x1b;" + // 0x01B3A 0x01B35: 0x01B3B + "\x00l\xf0\x03f\xa0\x1b=" + // 0x01B3C 0x01B35: 0x01B3D + "\x00l\xf8\x03f\xa0\x1b@" + // 0x01B3E 0x01B35: 0x01B40 + "\x00l\xfc\x03f\xa0\x1bA" + // 0x01B3F 0x01B35: 0x01B41 + "\x00m\b\x03f\xa0\x1bC" + // 0x01B42 0x01B35: 0x01B43 + "\x00\x01\x04\x00d\xa0\x1e\x00" + // 0x00041 0x00325: 0x01E00 + "\x00\x01\x84\x00d\xa0\x1e\x01" + // 0x00061 0x00325: 0x01E01 + "\x00\x01\b\x00`\xe0\x1e\x02" + // 0x00042 0x00307: 0x01E02 + "\x00\x01\x88\x00`\xe0\x1e\x03" + // 0x00062 0x00307: 0x01E03 + "\x00\x01\b\x00d`\x1e\x04" + // 0x00042 0x00323: 0x01E04 + "\x00\x01\x88\x00d`\x1e\x05" + // 0x00062 0x00323: 0x01E05 + "\x00\x01\b\x00f \x1e\x06" + // 0x00042 0x00331: 0x01E06 + "\x00\x01\x88\x00f \x1e\a" + // 0x00062 0x00331: 0x01E07 + "\x00\x03\x1c\x00` \x1e\b" + // 0x000C7 0x00301: 0x01E08 + "\x00\x03\x9c\x00` \x1e\t" + // 0x000E7 0x00301: 0x01E09 + "\x00\x01\x10\x00`\xe0\x1e\n" + // 0x00044 0x00307: 0x01E0A + "\x00\x01\x90\x00`\xe0\x1e\v" + // 0x00064 0x00307: 0x01E0B + "\x00\x01\x10\x00d`\x1e\f" + // 0x00044 0x00323: 0x01E0C + "\x00\x01\x90\x00d`\x1e\r" + // 0x00064 0x00323: 0x01E0D + "\x00\x01\x10\x00f \x1e\x0e" + // 0x00044 0x00331: 0x01E0E + "\x00\x01\x90\x00f \x1e\x0f" + // 0x00064 0x00331: 0x01E0F + "\x00\x01\x10\x00d\xe0\x1e\x10" + // 0x00044 0x00327: 0x01E10 + "\x00\x01\x90\x00d\xe0\x1e\x11" + // 0x00064 0x00327: 0x01E11 + "\x00\x01\x10\x00e\xa0\x1e\x12" + // 0x00044 0x0032D: 0x01E12 + "\x00\x01\x90\x00e\xa0\x1e\x13" + // 0x00064 0x0032D: 0x01E13 + "\x00\x04H\x00`\x00\x1e\x14" + // 0x00112 0x00300: 0x01E14 + "\x00\x04L\x00`\x00\x1e\x15" + // 0x00113 0x00300: 0x01E15 + "\x00\x04H\x00` \x1e\x16" + // 0x00112 0x00301: 0x01E16 + "\x00\x04L\x00` \x1e\x17" + // 0x00113 0x00301: 0x01E17 + "\x00\x01\x14\x00e\xa0\x1e\x18" + // 0x00045 0x0032D: 0x01E18 + "\x00\x01\x94\x00e\xa0\x1e\x19" + // 0x00065 0x0032D: 0x01E19 + "\x00\x01\x14\x00f\x00\x1e\x1a" + // 0x00045 0x00330: 0x01E1A + "\x00\x01\x94\x00f\x00\x1e\x1b" + // 0x00065 0x00330: 0x01E1B + "\x00\b\xa0\x00`\xc0\x1e\x1c" + // 0x00228 0x00306: 0x01E1C + "\x00\b\xa4\x00`\xc0\x1e\x1d" + // 0x00229 0x00306: 0x01E1D + "\x00\x01\x18\x00`\xe0\x1e\x1e" + // 0x00046 0x00307: 0x01E1E + "\x00\x01\x98\x00`\xe0\x1e\x1f" + // 0x00066 0x00307: 0x01E1F + "\x00\x01\x1c\x00`\x80\x1e " + // 0x00047 0x00304: 0x01E20 + "\x00\x01\x9c\x00`\x80\x1e!" + // 0x00067 0x00304: 0x01E21 + "\x00\x01 \x00`\xe0\x1e\"" + // 0x00048 0x00307: 0x01E22 + "\x00\x01\xa0\x00`\xe0\x1e#" + // 0x00068 0x00307: 0x01E23 + "\x00\x01 \x00d`\x1e$" + // 0x00048 0x00323: 0x01E24 + "\x00\x01\xa0\x00d`\x1e%" + // 0x00068 0x00323: 0x01E25 + "\x00\x01 \x00a\x00\x1e&" + // 0x00048 0x00308: 0x01E26 + "\x00\x01\xa0\x00a\x00\x1e'" + // 0x00068 0x00308: 0x01E27 + "\x00\x01 \x00d\xe0\x1e(" + // 0x00048 0x00327: 0x01E28 + "\x00\x01\xa0\x00d\xe0\x1e)" + // 0x00068 0x00327: 0x01E29 + "\x00\x01 \x00e\xc0\x1e*" + // 0x00048 0x0032E: 0x01E2A + "\x00\x01\xa0\x00e\xc0\x1e+" + // 0x00068 0x0032E: 0x01E2B + "\x00\x01$\x00f\x00\x1e," + // 0x00049 0x00330: 0x01E2C + "\x00\x01\xa4\x00f\x00\x1e-" + // 0x00069 0x00330: 0x01E2D + "\x00\x03<\x00` \x1e." + // 0x000CF 0x00301: 0x01E2E + "\x00\x03\xbc\x00` \x1e/" + // 0x000EF 0x00301: 0x01E2F + "\x00\x01,\x00` \x1e0" + // 0x0004B 0x00301: 0x01E30 + "\x00\x01\xac\x00` \x1e1" + // 0x0006B 0x00301: 0x01E31 + "\x00\x01,\x00d`\x1e2" + // 0x0004B 0x00323: 0x01E32 + "\x00\x01\xac\x00d`\x1e3" + // 0x0006B 0x00323: 0x01E33 + "\x00\x01,\x00f \x1e4" + // 0x0004B 0x00331: 0x01E34 + "\x00\x01\xac\x00f \x1e5" + // 0x0006B 0x00331: 0x01E35 + "\x00\x010\x00d`\x1e6" + // 0x0004C 0x00323: 0x01E36 + "\x00\x01\xb0\x00d`\x1e7" + // 0x0006C 0x00323: 0x01E37 + "\x00x\xd8\x00`\x80\x1e8" + // 0x01E36 0x00304: 0x01E38 + "\x00x\xdc\x00`\x80\x1e9" + // 0x01E37 0x00304: 0x01E39 + "\x00\x010\x00f \x1e:" + // 0x0004C 0x00331: 0x01E3A + "\x00\x01\xb0\x00f \x1e;" + // 0x0006C 0x00331: 0x01E3B + "\x00\x010\x00e\xa0\x1e<" + // 0x0004C 0x0032D: 0x01E3C + "\x00\x01\xb0\x00e\xa0\x1e=" + // 0x0006C 0x0032D: 0x01E3D + "\x00\x014\x00` \x1e>" + // 0x0004D 0x00301: 0x01E3E + "\x00\x01\xb4\x00` \x1e?" + // 0x0006D 0x00301: 0x01E3F + "\x00\x014\x00`\xe0\x1e@" + // 0x0004D 0x00307: 0x01E40 + "\x00\x01\xb4\x00`\xe0\x1eA" + // 0x0006D 0x00307: 0x01E41 + "\x00\x014\x00d`\x1eB" + // 0x0004D 0x00323: 0x01E42 + "\x00\x01\xb4\x00d`\x1eC" + // 0x0006D 0x00323: 0x01E43 + "\x00\x018\x00`\xe0\x1eD" + // 0x0004E 0x00307: 0x01E44 + "\x00\x01\xb8\x00`\xe0\x1eE" + // 0x0006E 0x00307: 0x01E45 + "\x00\x018\x00d`\x1eF" + // 0x0004E 0x00323: 0x01E46 + "\x00\x01\xb8\x00d`\x1eG" + // 0x0006E 0x00323: 0x01E47 + "\x00\x018\x00f \x1eH" + // 0x0004E 0x00331: 0x01E48 + "\x00\x01\xb8\x00f \x1eI" + // 0x0006E 0x00331: 0x01E49 + "\x00\x018\x00e\xa0\x1eJ" + // 0x0004E 0x0032D: 0x01E4A + "\x00\x01\xb8\x00e\xa0\x1eK" + // 0x0006E 0x0032D: 0x01E4B + "\x00\x03T\x00` \x1eL" + // 0x000D5 0x00301: 0x01E4C + "\x00\x03\xd4\x00` \x1eM" + // 0x000F5 0x00301: 0x01E4D + "\x00\x03T\x00a\x00\x1eN" + // 0x000D5 0x00308: 0x01E4E + "\x00\x03\xd4\x00a\x00\x1eO" + // 0x000F5 0x00308: 0x01E4F + "\x00\x050\x00`\x00\x1eP" + // 0x0014C 0x00300: 0x01E50 + "\x00\x054\x00`\x00\x1eQ" + // 0x0014D 0x00300: 0x01E51 + "\x00\x050\x00` \x1eR" + // 0x0014C 0x00301: 0x01E52 + "\x00\x054\x00` \x1eS" + // 0x0014D 0x00301: 0x01E53 + "\x00\x01@\x00` \x1eT" + // 0x00050 0x00301: 0x01E54 + "\x00\x01\xc0\x00` \x1eU" + // 0x00070 0x00301: 0x01E55 + "\x00\x01@\x00`\xe0\x1eV" + // 0x00050 0x00307: 0x01E56 + "\x00\x01\xc0\x00`\xe0\x1eW" + // 0x00070 0x00307: 0x01E57 + "\x00\x01H\x00`\xe0\x1eX" + // 0x00052 0x00307: 0x01E58 + "\x00\x01\xc8\x00`\xe0\x1eY" + // 0x00072 0x00307: 0x01E59 + "\x00\x01H\x00d`\x1eZ" + // 0x00052 0x00323: 0x01E5A + "\x00\x01\xc8\x00d`\x1e[" + // 0x00072 0x00323: 0x01E5B + "\x00yh\x00`\x80\x1e\\" + // 0x01E5A 0x00304: 0x01E5C + "\x00yl\x00`\x80\x1e]" + // 0x01E5B 0x00304: 0x01E5D + "\x00\x01H\x00f \x1e^" + // 0x00052 0x00331: 0x01E5E + "\x00\x01\xc8\x00f \x1e_" + // 0x00072 0x00331: 0x01E5F + "\x00\x01L\x00`\xe0\x1e`" + // 0x00053 0x00307: 0x01E60 + "\x00\x01\xcc\x00`\xe0\x1ea" + // 0x00073 0x00307: 0x01E61 + "\x00\x01L\x00d`\x1eb" + // 0x00053 0x00323: 0x01E62 + "\x00\x01\xcc\x00d`\x1ec" + // 0x00073 0x00323: 0x01E63 + "\x00\x05h\x00`\xe0\x1ed" + // 0x0015A 0x00307: 0x01E64 + "\x00\x05l\x00`\xe0\x1ee" + // 0x0015B 0x00307: 0x01E65 + "\x00\x05\x80\x00`\xe0\x1ef" + // 0x00160 0x00307: 0x01E66 + "\x00\x05\x84\x00`\xe0\x1eg" + // 0x00161 0x00307: 0x01E67 + "\x00y\x88\x00`\xe0\x1eh" + // 0x01E62 0x00307: 0x01E68 + "\x00y\x8c\x00`\xe0\x1ei" + // 0x01E63 0x00307: 0x01E69 + "\x00\x01P\x00`\xe0\x1ej" + // 0x00054 0x00307: 0x01E6A + "\x00\x01\xd0\x00`\xe0\x1ek" + // 0x00074 0x00307: 0x01E6B + "\x00\x01P\x00d`\x1el" + // 0x00054 0x00323: 0x01E6C + "\x00\x01\xd0\x00d`\x1em" + // 0x00074 0x00323: 0x01E6D + "\x00\x01P\x00f \x1en" + // 0x00054 0x00331: 0x01E6E + "\x00\x01\xd0\x00f \x1eo" + // 0x00074 0x00331: 0x01E6F + "\x00\x01P\x00e\xa0\x1ep" + // 0x00054 0x0032D: 0x01E70 + "\x00\x01\xd0\x00e\xa0\x1eq" + // 0x00074 0x0032D: 0x01E71 + "\x00\x01T\x00d\x80\x1er" + // 0x00055 0x00324: 0x01E72 + "\x00\x01\xd4\x00d\x80\x1es" + // 0x00075 0x00324: 0x01E73 + "\x00\x01T\x00f\x00\x1et" + // 0x00055 0x00330: 0x01E74 + "\x00\x01\xd4\x00f\x00\x1eu" + // 0x00075 0x00330: 0x01E75 + "\x00\x01T\x00e\xa0\x1ev" + // 0x00055 0x0032D: 0x01E76 + "\x00\x01\xd4\x00e\xa0\x1ew" + // 0x00075 0x0032D: 0x01E77 + "\x00\x05\xa0\x00` \x1ex" + // 0x00168 0x00301: 0x01E78 + "\x00\x05\xa4\x00` \x1ey" + // 0x00169 0x00301: 0x01E79 + "\x00\x05\xa8\x00a\x00\x1ez" + // 0x0016A 0x00308: 0x01E7A + "\x00\x05\xac\x00a\x00\x1e{" + // 0x0016B 0x00308: 0x01E7B + "\x00\x01X\x00``\x1e|" + // 0x00056 0x00303: 0x01E7C + "\x00\x01\xd8\x00``\x1e}" + // 0x00076 0x00303: 0x01E7D + "\x00\x01X\x00d`\x1e~" + // 0x00056 0x00323: 0x01E7E + "\x00\x01\xd8\x00d`\x1e\x7f" + // 0x00076 0x00323: 0x01E7F + "\x00\x01\\\x00`\x00\x1e\x80" + // 0x00057 0x00300: 0x01E80 + "\x00\x01\xdc\x00`\x00\x1e\x81" + // 0x00077 0x00300: 0x01E81 + "\x00\x01\\\x00` \x1e\x82" + // 0x00057 0x00301: 0x01E82 + "\x00\x01\xdc\x00` \x1e\x83" + // 0x00077 0x00301: 0x01E83 + "\x00\x01\\\x00a\x00\x1e\x84" + // 0x00057 0x00308: 0x01E84 + "\x00\x01\xdc\x00a\x00\x1e\x85" + // 0x00077 0x00308: 0x01E85 + "\x00\x01\\\x00`\xe0\x1e\x86" + // 0x00057 0x00307: 0x01E86 + "\x00\x01\xdc\x00`\xe0\x1e\x87" + // 0x00077 0x00307: 0x01E87 + "\x00\x01\\\x00d`\x1e\x88" + // 0x00057 0x00323: 0x01E88 + "\x00\x01\xdc\x00d`\x1e\x89" + // 0x00077 0x00323: 0x01E89 + "\x00\x01`\x00`\xe0\x1e\x8a" + // 0x00058 0x00307: 0x01E8A + "\x00\x01\xe0\x00`\xe0\x1e\x8b" + // 0x00078 0x00307: 0x01E8B + "\x00\x01`\x00a\x00\x1e\x8c" + // 0x00058 0x00308: 0x01E8C + "\x00\x01\xe0\x00a\x00\x1e\x8d" + // 0x00078 0x00308: 0x01E8D + "\x00\x01d\x00`\xe0\x1e\x8e" + // 0x00059 0x00307: 0x01E8E + "\x00\x01\xe4\x00`\xe0\x1e\x8f" + // 0x00079 0x00307: 0x01E8F + "\x00\x01h\x00`@\x1e\x90" + // 0x0005A 0x00302: 0x01E90 + "\x00\x01\xe8\x00`@\x1e\x91" + // 0x0007A 0x00302: 0x01E91 + "\x00\x01h\x00d`\x1e\x92" + // 0x0005A 0x00323: 0x01E92 + "\x00\x01\xe8\x00d`\x1e\x93" + // 0x0007A 0x00323: 0x01E93 + "\x00\x01h\x00f \x1e\x94" + // 0x0005A 0x00331: 0x01E94 + "\x00\x01\xe8\x00f \x1e\x95" + // 0x0007A 0x00331: 0x01E95 + "\x00\x01\xa0\x00f \x1e\x96" + // 0x00068 0x00331: 0x01E96 + "\x00\x01\xd0\x00a\x00\x1e\x97" + // 0x00074 0x00308: 0x01E97 + "\x00\x01\xdc\x00a@\x1e\x98" + // 0x00077 0x0030A: 0x01E98 + "\x00\x01\xe4\x00a@\x1e\x99" + // 0x00079 0x0030A: 0x01E99 + "\x00\x05\xfc\x00`\xe0\x1e\x9b" + // 0x0017F 0x00307: 0x01E9B + "\x00\x01\x04\x00d`\x1e\xa0" + // 0x00041 0x00323: 0x01EA0 + "\x00\x01\x84\x00d`\x1e\xa1" + // 0x00061 0x00323: 0x01EA1 + "\x00\x01\x04\x00a \x1e\xa2" + // 0x00041 0x00309: 0x01EA2 + "\x00\x01\x84\x00a \x1e\xa3" + // 0x00061 0x00309: 0x01EA3 + "\x00\x03\b\x00` \x1e\xa4" + // 0x000C2 0x00301: 0x01EA4 + "\x00\x03\x88\x00` \x1e\xa5" + // 0x000E2 0x00301: 0x01EA5 + "\x00\x03\b\x00`\x00\x1e\xa6" + // 0x000C2 0x00300: 0x01EA6 + "\x00\x03\x88\x00`\x00\x1e\xa7" + // 0x000E2 0x00300: 0x01EA7 + "\x00\x03\b\x00a \x1e\xa8" + // 0x000C2 0x00309: 0x01EA8 + "\x00\x03\x88\x00a \x1e\xa9" + // 0x000E2 0x00309: 0x01EA9 + "\x00\x03\b\x00``\x1e\xaa" + // 0x000C2 0x00303: 0x01EAA + "\x00\x03\x88\x00``\x1e\xab" + // 0x000E2 0x00303: 0x01EAB + "\x00z\x80\x00`@\x1e\xac" + // 0x01EA0 0x00302: 0x01EAC + "\x00z\x84\x00`@\x1e\xad" + // 0x01EA1 0x00302: 0x01EAD + "\x00\x04\b\x00` \x1e\xae" + // 0x00102 0x00301: 0x01EAE + "\x00\x04\f\x00` \x1e\xaf" + // 0x00103 0x00301: 0x01EAF + "\x00\x04\b\x00`\x00\x1e\xb0" + // 0x00102 0x00300: 0x01EB0 + "\x00\x04\f\x00`\x00\x1e\xb1" + // 0x00103 0x00300: 0x01EB1 + "\x00\x04\b\x00a \x1e\xb2" + // 0x00102 0x00309: 0x01EB2 + "\x00\x04\f\x00a \x1e\xb3" + // 0x00103 0x00309: 0x01EB3 + "\x00\x04\b\x00``\x1e\xb4" + // 0x00102 0x00303: 0x01EB4 + "\x00\x04\f\x00``\x1e\xb5" + // 0x00103 0x00303: 0x01EB5 + "\x00z\x80\x00`\xc0\x1e\xb6" + // 0x01EA0 0x00306: 0x01EB6 + "\x00z\x84\x00`\xc0\x1e\xb7" + // 0x01EA1 0x00306: 0x01EB7 + "\x00\x01\x14\x00d`\x1e\xb8" + // 0x00045 0x00323: 0x01EB8 + "\x00\x01\x94\x00d`\x1e\xb9" + // 0x00065 0x00323: 0x01EB9 + "\x00\x01\x14\x00a \x1e\xba" + // 0x00045 0x00309: 0x01EBA + "\x00\x01\x94\x00a \x1e\xbb" + // 0x00065 0x00309: 0x01EBB + "\x00\x01\x14\x00``\x1e\xbc" + // 0x00045 0x00303: 0x01EBC + "\x00\x01\x94\x00``\x1e\xbd" + // 0x00065 0x00303: 0x01EBD + "\x00\x03(\x00` \x1e\xbe" + // 0x000CA 0x00301: 0x01EBE + "\x00\x03\xa8\x00` \x1e\xbf" + // 0x000EA 0x00301: 0x01EBF + "\x00\x03(\x00`\x00\x1e\xc0" + // 0x000CA 0x00300: 0x01EC0 + "\x00\x03\xa8\x00`\x00\x1e\xc1" + // 0x000EA 0x00300: 0x01EC1 + "\x00\x03(\x00a \x1e\xc2" + // 0x000CA 0x00309: 0x01EC2 + "\x00\x03\xa8\x00a \x1e\xc3" + // 0x000EA 0x00309: 0x01EC3 + "\x00\x03(\x00``\x1e\xc4" + // 0x000CA 0x00303: 0x01EC4 + "\x00\x03\xa8\x00``\x1e\xc5" + // 0x000EA 0x00303: 0x01EC5 + "\x00z\xe0\x00`@\x1e\xc6" + // 0x01EB8 0x00302: 0x01EC6 + "\x00z\xe4\x00`@\x1e\xc7" + // 0x01EB9 0x00302: 0x01EC7 + "\x00\x01$\x00a \x1e\xc8" + // 0x00049 0x00309: 0x01EC8 + "\x00\x01\xa4\x00a \x1e\xc9" + // 0x00069 0x00309: 0x01EC9 + "\x00\x01$\x00d`\x1e\xca" + // 0x00049 0x00323: 0x01ECA + "\x00\x01\xa4\x00d`\x1e\xcb" + // 0x00069 0x00323: 0x01ECB + "\x00\x01<\x00d`\x1e\xcc" + // 0x0004F 0x00323: 0x01ECC + "\x00\x01\xbc\x00d`\x1e\xcd" + // 0x0006F 0x00323: 0x01ECD + "\x00\x01<\x00a \x1e\xce" + // 0x0004F 0x00309: 0x01ECE + "\x00\x01\xbc\x00a \x1e\xcf" + // 0x0006F 0x00309: 0x01ECF + "\x00\x03P\x00` \x1e\xd0" + // 0x000D4 0x00301: 0x01ED0 + "\x00\x03\xd0\x00` \x1e\xd1" + // 0x000F4 0x00301: 0x01ED1 + "\x00\x03P\x00`\x00\x1e\xd2" + // 0x000D4 0x00300: 0x01ED2 + "\x00\x03\xd0\x00`\x00\x1e\xd3" + // 0x000F4 0x00300: 0x01ED3 + "\x00\x03P\x00a \x1e\xd4" + // 0x000D4 0x00309: 0x01ED4 + "\x00\x03\xd0\x00a \x1e\xd5" + // 0x000F4 0x00309: 0x01ED5 + "\x00\x03P\x00``\x1e\xd6" + // 0x000D4 0x00303: 0x01ED6 + "\x00\x03\xd0\x00``\x1e\xd7" + // 0x000F4 0x00303: 0x01ED7 + "\x00{0\x00`@\x1e\xd8" + // 0x01ECC 0x00302: 0x01ED8 + "\x00{4\x00`@\x1e\xd9" + // 0x01ECD 0x00302: 0x01ED9 + "\x00\x06\x80\x00` \x1e\xda" + // 0x001A0 0x00301: 0x01EDA + "\x00\x06\x84\x00` \x1e\xdb" + // 0x001A1 0x00301: 0x01EDB + "\x00\x06\x80\x00`\x00\x1e\xdc" + // 0x001A0 0x00300: 0x01EDC + "\x00\x06\x84\x00`\x00\x1e\xdd" + // 0x001A1 0x00300: 0x01EDD + "\x00\x06\x80\x00a \x1e\xde" + // 0x001A0 0x00309: 0x01EDE + "\x00\x06\x84\x00a \x1e\xdf" + // 0x001A1 0x00309: 0x01EDF + "\x00\x06\x80\x00``\x1e\xe0" + // 0x001A0 0x00303: 0x01EE0 + "\x00\x06\x84\x00``\x1e\xe1" + // 0x001A1 0x00303: 0x01EE1 + "\x00\x06\x80\x00d`\x1e\xe2" + // 0x001A0 0x00323: 0x01EE2 + "\x00\x06\x84\x00d`\x1e\xe3" + // 0x001A1 0x00323: 0x01EE3 + "\x00\x01T\x00d`\x1e\xe4" + // 0x00055 0x00323: 0x01EE4 + "\x00\x01\xd4\x00d`\x1e\xe5" + // 0x00075 0x00323: 0x01EE5 + "\x00\x01T\x00a \x1e\xe6" + // 0x00055 0x00309: 0x01EE6 + "\x00\x01\xd4\x00a \x1e\xe7" + // 0x00075 0x00309: 0x01EE7 + "\x00\x06\xbc\x00` \x1e\xe8" + // 0x001AF 0x00301: 0x01EE8 + "\x00\x06\xc0\x00` \x1e\xe9" + // 0x001B0 0x00301: 0x01EE9 + "\x00\x06\xbc\x00`\x00\x1e\xea" + // 0x001AF 0x00300: 0x01EEA + "\x00\x06\xc0\x00`\x00\x1e\xeb" + // 0x001B0 0x00300: 0x01EEB + "\x00\x06\xbc\x00a \x1e\xec" + // 0x001AF 0x00309: 0x01EEC + "\x00\x06\xc0\x00a \x1e\xed" + // 0x001B0 0x00309: 0x01EED + "\x00\x06\xbc\x00``\x1e\xee" + // 0x001AF 0x00303: 0x01EEE + "\x00\x06\xc0\x00``\x1e\xef" + // 0x001B0 0x00303: 0x01EEF + "\x00\x06\xbc\x00d`\x1e\xf0" + // 0x001AF 0x00323: 0x01EF0 + "\x00\x06\xc0\x00d`\x1e\xf1" + // 0x001B0 0x00323: 0x01EF1 + "\x00\x01d\x00`\x00\x1e\xf2" + // 0x00059 0x00300: 0x01EF2 + "\x00\x01\xe4\x00`\x00\x1e\xf3" + // 0x00079 0x00300: 0x01EF3 + "\x00\x01d\x00d`\x1e\xf4" + // 0x00059 0x00323: 0x01EF4 + "\x00\x01\xe4\x00d`\x1e\xf5" + // 0x00079 0x00323: 0x01EF5 + "\x00\x01d\x00a \x1e\xf6" + // 0x00059 0x00309: 0x01EF6 + "\x00\x01\xe4\x00a \x1e\xf7" + // 0x00079 0x00309: 0x01EF7 + "\x00\x01d\x00``\x1e\xf8" + // 0x00059 0x00303: 0x01EF8 + "\x00\x01\xe4\x00``\x1e\xf9" + // 0x00079 0x00303: 0x01EF9 + "\x00\x0e\xc4\x00b`\x1f\x00" + // 0x003B1 0x00313: 0x01F00 + "\x00\x0e\xc4\x00b\x80\x1f\x01" + // 0x003B1 0x00314: 0x01F01 + "\x00|\x00\x00`\x00\x1f\x02" + // 0x01F00 0x00300: 0x01F02 + "\x00|\x04\x00`\x00\x1f\x03" + // 0x01F01 0x00300: 0x01F03 + "\x00|\x00\x00` \x1f\x04" + // 0x01F00 0x00301: 0x01F04 + "\x00|\x04\x00` \x1f\x05" + // 0x01F01 0x00301: 0x01F05 + "\x00|\x00\x00h@\x1f\x06" + // 0x01F00 0x00342: 0x01F06 + "\x00|\x04\x00h@\x1f\a" + // 0x01F01 0x00342: 0x01F07 + "\x00\x0eD\x00b`\x1f\b" + // 0x00391 0x00313: 0x01F08 + "\x00\x0eD\x00b\x80\x1f\t" + // 0x00391 0x00314: 0x01F09 + "\x00| \x00`\x00\x1f\n" + // 0x01F08 0x00300: 0x01F0A + "\x00|$\x00`\x00\x1f\v" + // 0x01F09 0x00300: 0x01F0B + "\x00| \x00` \x1f\f" + // 0x01F08 0x00301: 0x01F0C + "\x00|$\x00` \x1f\r" + // 0x01F09 0x00301: 0x01F0D + "\x00| \x00h@\x1f\x0e" + // 0x01F08 0x00342: 0x01F0E + "\x00|$\x00h@\x1f\x0f" + // 0x01F09 0x00342: 0x01F0F + "\x00\x0e\xd4\x00b`\x1f\x10" + // 0x003B5 0x00313: 0x01F10 + "\x00\x0e\xd4\x00b\x80\x1f\x11" + // 0x003B5 0x00314: 0x01F11 + "\x00|@\x00`\x00\x1f\x12" + // 0x01F10 0x00300: 0x01F12 + "\x00|D\x00`\x00\x1f\x13" + // 0x01F11 0x00300: 0x01F13 + "\x00|@\x00` \x1f\x14" + // 0x01F10 0x00301: 0x01F14 + "\x00|D\x00` \x1f\x15" + // 0x01F11 0x00301: 0x01F15 + "\x00\x0eT\x00b`\x1f\x18" + // 0x00395 0x00313: 0x01F18 + "\x00\x0eT\x00b\x80\x1f\x19" + // 0x00395 0x00314: 0x01F19 + "\x00|`\x00`\x00\x1f\x1a" + // 0x01F18 0x00300: 0x01F1A + "\x00|d\x00`\x00\x1f\x1b" + // 0x01F19 0x00300: 0x01F1B + "\x00|`\x00` \x1f\x1c" + // 0x01F18 0x00301: 0x01F1C + "\x00|d\x00` \x1f\x1d" + // 0x01F19 0x00301: 0x01F1D + "\x00\x0e\xdc\x00b`\x1f " + // 0x003B7 0x00313: 0x01F20 + "\x00\x0e\xdc\x00b\x80\x1f!" + // 0x003B7 0x00314: 0x01F21 + "\x00|\x80\x00`\x00\x1f\"" + // 0x01F20 0x00300: 0x01F22 + "\x00|\x84\x00`\x00\x1f#" + // 0x01F21 0x00300: 0x01F23 + "\x00|\x80\x00` \x1f$" + // 0x01F20 0x00301: 0x01F24 + "\x00|\x84\x00` \x1f%" + // 0x01F21 0x00301: 0x01F25 + "\x00|\x80\x00h@\x1f&" + // 0x01F20 0x00342: 0x01F26 + "\x00|\x84\x00h@\x1f'" + // 0x01F21 0x00342: 0x01F27 + "\x00\x0e\\\x00b`\x1f(" + // 0x00397 0x00313: 0x01F28 + "\x00\x0e\\\x00b\x80\x1f)" + // 0x00397 0x00314: 0x01F29 + "\x00|\xa0\x00`\x00\x1f*" + // 0x01F28 0x00300: 0x01F2A + "\x00|\xa4\x00`\x00\x1f+" + // 0x01F29 0x00300: 0x01F2B + "\x00|\xa0\x00` \x1f," + // 0x01F28 0x00301: 0x01F2C + "\x00|\xa4\x00` \x1f-" + // 0x01F29 0x00301: 0x01F2D + "\x00|\xa0\x00h@\x1f." + // 0x01F28 0x00342: 0x01F2E + "\x00|\xa4\x00h@\x1f/" + // 0x01F29 0x00342: 0x01F2F + "\x00\x0e\xe4\x00b`\x1f0" + // 0x003B9 0x00313: 0x01F30 + "\x00\x0e\xe4\x00b\x80\x1f1" + // 0x003B9 0x00314: 0x01F31 + "\x00|\xc0\x00`\x00\x1f2" + // 0x01F30 0x00300: 0x01F32 + "\x00|\xc4\x00`\x00\x1f3" + // 0x01F31 0x00300: 0x01F33 + "\x00|\xc0\x00` \x1f4" + // 0x01F30 0x00301: 0x01F34 + "\x00|\xc4\x00` \x1f5" + // 0x01F31 0x00301: 0x01F35 + "\x00|\xc0\x00h@\x1f6" + // 0x01F30 0x00342: 0x01F36 + "\x00|\xc4\x00h@\x1f7" + // 0x01F31 0x00342: 0x01F37 + "\x00\x0ed\x00b`\x1f8" + // 0x00399 0x00313: 0x01F38 + "\x00\x0ed\x00b\x80\x1f9" + // 0x00399 0x00314: 0x01F39 + "\x00|\xe0\x00`\x00\x1f:" + // 0x01F38 0x00300: 0x01F3A + "\x00|\xe4\x00`\x00\x1f;" + // 0x01F39 0x00300: 0x01F3B + "\x00|\xe0\x00` \x1f<" + // 0x01F38 0x00301: 0x01F3C + "\x00|\xe4\x00` \x1f=" + // 0x01F39 0x00301: 0x01F3D + "\x00|\xe0\x00h@\x1f>" + // 0x01F38 0x00342: 0x01F3E + "\x00|\xe4\x00h@\x1f?" + // 0x01F39 0x00342: 0x01F3F + "\x00\x0e\xfc\x00b`\x1f@" + // 0x003BF 0x00313: 0x01F40 + "\x00\x0e\xfc\x00b\x80\x1fA" + // 0x003BF 0x00314: 0x01F41 + "\x00}\x00\x00`\x00\x1fB" + // 0x01F40 0x00300: 0x01F42 + "\x00}\x04\x00`\x00\x1fC" + // 0x01F41 0x00300: 0x01F43 + "\x00}\x00\x00` \x1fD" + // 0x01F40 0x00301: 0x01F44 + "\x00}\x04\x00` \x1fE" + // 0x01F41 0x00301: 0x01F45 + "\x00\x0e|\x00b`\x1fH" + // 0x0039F 0x00313: 0x01F48 + "\x00\x0e|\x00b\x80\x1fI" + // 0x0039F 0x00314: 0x01F49 + "\x00} \x00`\x00\x1fJ" + // 0x01F48 0x00300: 0x01F4A + "\x00}$\x00`\x00\x1fK" + // 0x01F49 0x00300: 0x01F4B + "\x00} \x00` \x1fL" + // 0x01F48 0x00301: 0x01F4C + "\x00}$\x00` \x1fM" + // 0x01F49 0x00301: 0x01F4D + "\x00\x0f\x14\x00b`\x1fP" + // 0x003C5 0x00313: 0x01F50 + "\x00\x0f\x14\x00b\x80\x1fQ" + // 0x003C5 0x00314: 0x01F51 + "\x00}@\x00`\x00\x1fR" + // 0x01F50 0x00300: 0x01F52 + "\x00}D\x00`\x00\x1fS" + // 0x01F51 0x00300: 0x01F53 + "\x00}@\x00` \x1fT" + // 0x01F50 0x00301: 0x01F54 + "\x00}D\x00` \x1fU" + // 0x01F51 0x00301: 0x01F55 + "\x00}@\x00h@\x1fV" + // 0x01F50 0x00342: 0x01F56 + "\x00}D\x00h@\x1fW" + // 0x01F51 0x00342: 0x01F57 + "\x00\x0e\x94\x00b\x80\x1fY" + // 0x003A5 0x00314: 0x01F59 + "\x00}d\x00`\x00\x1f[" + // 0x01F59 0x00300: 0x01F5B + "\x00}d\x00` \x1f]" + // 0x01F59 0x00301: 0x01F5D + "\x00}d\x00h@\x1f_" + // 0x01F59 0x00342: 0x01F5F + "\x00\x0f$\x00b`\x1f`" + // 0x003C9 0x00313: 0x01F60 + "\x00\x0f$\x00b\x80\x1fa" + // 0x003C9 0x00314: 0x01F61 + "\x00}\x80\x00`\x00\x1fb" + // 0x01F60 0x00300: 0x01F62 + "\x00}\x84\x00`\x00\x1fc" + // 0x01F61 0x00300: 0x01F63 + "\x00}\x80\x00` \x1fd" + // 0x01F60 0x00301: 0x01F64 + "\x00}\x84\x00` \x1fe" + // 0x01F61 0x00301: 0x01F65 + "\x00}\x80\x00h@\x1ff" + // 0x01F60 0x00342: 0x01F66 + "\x00}\x84\x00h@\x1fg" + // 0x01F61 0x00342: 0x01F67 + "\x00\x0e\xa4\x00b`\x1fh" + // 0x003A9 0x00313: 0x01F68 + "\x00\x0e\xa4\x00b\x80\x1fi" + // 0x003A9 0x00314: 0x01F69 + "\x00}\xa0\x00`\x00\x1fj" + // 0x01F68 0x00300: 0x01F6A + "\x00}\xa4\x00`\x00\x1fk" + // 0x01F69 0x00300: 0x01F6B + "\x00}\xa0\x00` \x1fl" + // 0x01F68 0x00301: 0x01F6C + "\x00}\xa4\x00` \x1fm" + // 0x01F69 0x00301: 0x01F6D + "\x00}\xa0\x00h@\x1fn" + // 0x01F68 0x00342: 0x01F6E + "\x00}\xa4\x00h@\x1fo" + // 0x01F69 0x00342: 0x01F6F + "\x00\x0e\xc4\x00`\x00\x1fp" + // 0x003B1 0x00300: 0x01F70 + "\x00\x0e\xd4\x00`\x00\x1fr" + // 0x003B5 0x00300: 0x01F72 + "\x00\x0e\xdc\x00`\x00\x1ft" + // 0x003B7 0x00300: 0x01F74 + "\x00\x0e\xe4\x00`\x00\x1fv" + // 0x003B9 0x00300: 0x01F76 + "\x00\x0e\xfc\x00`\x00\x1fx" + // 0x003BF 0x00300: 0x01F78 + "\x00\x0f\x14\x00`\x00\x1fz" + // 0x003C5 0x00300: 0x01F7A + "\x00\x0f$\x00`\x00\x1f|" + // 0x003C9 0x00300: 0x01F7C + "\x00|\x00\x00h\xa0\x1f\x80" + // 0x01F00 0x00345: 0x01F80 + "\x00|\x04\x00h\xa0\x1f\x81" + // 0x01F01 0x00345: 0x01F81 + "\x00|\b\x00h\xa0\x1f\x82" + // 0x01F02 0x00345: 0x01F82 + "\x00|\f\x00h\xa0\x1f\x83" + // 0x01F03 0x00345: 0x01F83 + "\x00|\x10\x00h\xa0\x1f\x84" + // 0x01F04 0x00345: 0x01F84 + "\x00|\x14\x00h\xa0\x1f\x85" + // 0x01F05 0x00345: 0x01F85 + "\x00|\x18\x00h\xa0\x1f\x86" + // 0x01F06 0x00345: 0x01F86 + "\x00|\x1c\x00h\xa0\x1f\x87" + // 0x01F07 0x00345: 0x01F87 + "\x00| \x00h\xa0\x1f\x88" + // 0x01F08 0x00345: 0x01F88 + "\x00|$\x00h\xa0\x1f\x89" + // 0x01F09 0x00345: 0x01F89 + "\x00|(\x00h\xa0\x1f\x8a" + // 0x01F0A 0x00345: 0x01F8A + "\x00|,\x00h\xa0\x1f\x8b" + // 0x01F0B 0x00345: 0x01F8B + "\x00|0\x00h\xa0\x1f\x8c" + // 0x01F0C 0x00345: 0x01F8C + "\x00|4\x00h\xa0\x1f\x8d" + // 0x01F0D 0x00345: 0x01F8D + "\x00|8\x00h\xa0\x1f\x8e" + // 0x01F0E 0x00345: 0x01F8E + "\x00|<\x00h\xa0\x1f\x8f" + // 0x01F0F 0x00345: 0x01F8F + "\x00|\x80\x00h\xa0\x1f\x90" + // 0x01F20 0x00345: 0x01F90 + "\x00|\x84\x00h\xa0\x1f\x91" + // 0x01F21 0x00345: 0x01F91 + "\x00|\x88\x00h\xa0\x1f\x92" + // 0x01F22 0x00345: 0x01F92 + "\x00|\x8c\x00h\xa0\x1f\x93" + // 0x01F23 0x00345: 0x01F93 + "\x00|\x90\x00h\xa0\x1f\x94" + // 0x01F24 0x00345: 0x01F94 + "\x00|\x94\x00h\xa0\x1f\x95" + // 0x01F25 0x00345: 0x01F95 + "\x00|\x98\x00h\xa0\x1f\x96" + // 0x01F26 0x00345: 0x01F96 + "\x00|\x9c\x00h\xa0\x1f\x97" + // 0x01F27 0x00345: 0x01F97 + "\x00|\xa0\x00h\xa0\x1f\x98" + // 0x01F28 0x00345: 0x01F98 + "\x00|\xa4\x00h\xa0\x1f\x99" + // 0x01F29 0x00345: 0x01F99 + "\x00|\xa8\x00h\xa0\x1f\x9a" + // 0x01F2A 0x00345: 0x01F9A + "\x00|\xac\x00h\xa0\x1f\x9b" + // 0x01F2B 0x00345: 0x01F9B + "\x00|\xb0\x00h\xa0\x1f\x9c" + // 0x01F2C 0x00345: 0x01F9C + "\x00|\xb4\x00h\xa0\x1f\x9d" + // 0x01F2D 0x00345: 0x01F9D + "\x00|\xb8\x00h\xa0\x1f\x9e" + // 0x01F2E 0x00345: 0x01F9E + "\x00|\xbc\x00h\xa0\x1f\x9f" + // 0x01F2F 0x00345: 0x01F9F + "\x00}\x80\x00h\xa0\x1f\xa0" + // 0x01F60 0x00345: 0x01FA0 + "\x00}\x84\x00h\xa0\x1f\xa1" + // 0x01F61 0x00345: 0x01FA1 + "\x00}\x88\x00h\xa0\x1f\xa2" + // 0x01F62 0x00345: 0x01FA2 + "\x00}\x8c\x00h\xa0\x1f\xa3" + // 0x01F63 0x00345: 0x01FA3 + "\x00}\x90\x00h\xa0\x1f\xa4" + // 0x01F64 0x00345: 0x01FA4 + "\x00}\x94\x00h\xa0\x1f\xa5" + // 0x01F65 0x00345: 0x01FA5 + "\x00}\x98\x00h\xa0\x1f\xa6" + // 0x01F66 0x00345: 0x01FA6 + "\x00}\x9c\x00h\xa0\x1f\xa7" + // 0x01F67 0x00345: 0x01FA7 + "\x00}\xa0\x00h\xa0\x1f\xa8" + // 0x01F68 0x00345: 0x01FA8 + "\x00}\xa4\x00h\xa0\x1f\xa9" + // 0x01F69 0x00345: 0x01FA9 + "\x00}\xa8\x00h\xa0\x1f\xaa" + // 0x01F6A 0x00345: 0x01FAA + "\x00}\xac\x00h\xa0\x1f\xab" + // 0x01F6B 0x00345: 0x01FAB + "\x00}\xb0\x00h\xa0\x1f\xac" + // 0x01F6C 0x00345: 0x01FAC + "\x00}\xb4\x00h\xa0\x1f\xad" + // 0x01F6D 0x00345: 0x01FAD + "\x00}\xb8\x00h\xa0\x1f\xae" + // 0x01F6E 0x00345: 0x01FAE + "\x00}\xbc\x00h\xa0\x1f\xaf" + // 0x01F6F 0x00345: 0x01FAF + "\x00\x0e\xc4\x00`\xc0\x1f\xb0" + // 0x003B1 0x00306: 0x01FB0 + "\x00\x0e\xc4\x00`\x80\x1f\xb1" + // 0x003B1 0x00304: 0x01FB1 + "\x00}\xc0\x00h\xa0\x1f\xb2" + // 0x01F70 0x00345: 0x01FB2 + "\x00\x0e\xc4\x00h\xa0\x1f\xb3" + // 0x003B1 0x00345: 0x01FB3 + "\x00\x0e\xb0\x00h\xa0\x1f\xb4" + // 0x003AC 0x00345: 0x01FB4 + "\x00\x0e\xc4\x00h@\x1f\xb6" + // 0x003B1 0x00342: 0x01FB6 + "\x00~\xd8\x00h\xa0\x1f\xb7" + // 0x01FB6 0x00345: 0x01FB7 + "\x00\x0eD\x00`\xc0\x1f\xb8" + // 0x00391 0x00306: 0x01FB8 + "\x00\x0eD\x00`\x80\x1f\xb9" + // 0x00391 0x00304: 0x01FB9 + "\x00\x0eD\x00`\x00\x1f\xba" + // 0x00391 0x00300: 0x01FBA + "\x00\x0eD\x00h\xa0\x1f\xbc" + // 0x00391 0x00345: 0x01FBC + "\x00\x02\xa0\x00h@\x1f\xc1" + // 0x000A8 0x00342: 0x01FC1 + "\x00}\xd0\x00h\xa0\x1f\xc2" + // 0x01F74 0x00345: 0x01FC2 + "\x00\x0e\xdc\x00h\xa0\x1f\xc3" + // 0x003B7 0x00345: 0x01FC3 + "\x00\x0e\xb8\x00h\xa0\x1f\xc4" + // 0x003AE 0x00345: 0x01FC4 + "\x00\x0e\xdc\x00h@\x1f\xc6" + // 0x003B7 0x00342: 0x01FC6 + "\x00\x7f\x18\x00h\xa0\x1f\xc7" + // 0x01FC6 0x00345: 0x01FC7 + "\x00\x0eT\x00`\x00\x1f\xc8" + // 0x00395 0x00300: 0x01FC8 + "\x00\x0e\\\x00`\x00\x1f\xca" + // 0x00397 0x00300: 0x01FCA + "\x00\x0e\\\x00h\xa0\x1f\xcc" + // 0x00397 0x00345: 0x01FCC + "\x00~\xfc\x00`\x00\x1f\xcd" + // 0x01FBF 0x00300: 0x01FCD + "\x00~\xfc\x00` \x1f\xce" + // 0x01FBF 0x00301: 0x01FCE + "\x00~\xfc\x00h@\x1f\xcf" + // 0x01FBF 0x00342: 0x01FCF + "\x00\x0e\xe4\x00`\xc0\x1f\xd0" + // 0x003B9 0x00306: 0x01FD0 + "\x00\x0e\xe4\x00`\x80\x1f\xd1" + // 0x003B9 0x00304: 0x01FD1 + "\x00\x0f(\x00`\x00\x1f\xd2" + // 0x003CA 0x00300: 0x01FD2 + "\x00\x0e\xe4\x00h@\x1f\xd6" + // 0x003B9 0x00342: 0x01FD6 + "\x00\x0f(\x00h@\x1f\xd7" + // 0x003CA 0x00342: 0x01FD7 + "\x00\x0ed\x00`\xc0\x1f\xd8" + // 0x00399 0x00306: 0x01FD8 + "\x00\x0ed\x00`\x80\x1f\xd9" + // 0x00399 0x00304: 0x01FD9 + "\x00\x0ed\x00`\x00\x1f\xda" + // 0x00399 0x00300: 0x01FDA + "\x00\x7f\xf8\x00`\x00\x1f\xdd" + // 0x01FFE 0x00300: 0x01FDD + "\x00\x7f\xf8\x00` \x1f\xde" + // 0x01FFE 0x00301: 0x01FDE + "\x00\x7f\xf8\x00h@\x1f\xdf" + // 0x01FFE 0x00342: 0x01FDF + "\x00\x0f\x14\x00`\xc0\x1f\xe0" + // 0x003C5 0x00306: 0x01FE0 + "\x00\x0f\x14\x00`\x80\x1f\xe1" + // 0x003C5 0x00304: 0x01FE1 + "\x00\x0f,\x00`\x00\x1f\xe2" + // 0x003CB 0x00300: 0x01FE2 + "\x00\x0f\x04\x00b`\x1f\xe4" + // 0x003C1 0x00313: 0x01FE4 + "\x00\x0f\x04\x00b\x80\x1f\xe5" + // 0x003C1 0x00314: 0x01FE5 + "\x00\x0f\x14\x00h@\x1f\xe6" + // 0x003C5 0x00342: 0x01FE6 + "\x00\x0f,\x00h@\x1f\xe7" + // 0x003CB 0x00342: 0x01FE7 + "\x00\x0e\x94\x00`\xc0\x1f\xe8" + // 0x003A5 0x00306: 0x01FE8 + "\x00\x0e\x94\x00`\x80\x1f\xe9" + // 0x003A5 0x00304: 0x01FE9 + "\x00\x0e\x94\x00`\x00\x1f\xea" + // 0x003A5 0x00300: 0x01FEA + "\x00\x0e\x84\x00b\x80\x1f\xec" + // 0x003A1 0x00314: 0x01FEC + "\x00\x02\xa0\x00`\x00\x1f\xed" + // 0x000A8 0x00300: 0x01FED + "\x00}\xf0\x00h\xa0\x1f\xf2" + // 0x01F7C 0x00345: 0x01FF2 + "\x00\x0f$\x00h\xa0\x1f\xf3" + // 0x003C9 0x00345: 0x01FF3 + "\x00\x0f8\x00h\xa0\x1f\xf4" + // 0x003CE 0x00345: 0x01FF4 + "\x00\x0f$\x00h@\x1f\xf6" + // 0x003C9 0x00342: 0x01FF6 + "\x00\x7f\xd8\x00h\xa0\x1f\xf7" + // 0x01FF6 0x00345: 0x01FF7 + "\x00\x0e|\x00`\x00\x1f\xf8" + // 0x0039F 0x00300: 0x01FF8 + "\x00\x0e\xa4\x00`\x00\x1f\xfa" + // 0x003A9 0x00300: 0x01FFA + "\x00\x0e\xa4\x00h\xa0\x1f\xfc" + // 0x003A9 0x00345: 0x01FFC + "\x00\x86@\x00g\x00!\x9a" + // 0x02190 0x00338: 0x0219A + "\x00\x86H\x00g\x00!\x9b" + // 0x02192 0x00338: 0x0219B + "\x00\x86P\x00g\x00!\xae" + // 0x02194 0x00338: 0x021AE + "\x00\x87@\x00g\x00!\xcd" + // 0x021D0 0x00338: 0x021CD + "\x00\x87P\x00g\x00!\xce" + // 0x021D4 0x00338: 0x021CE + "\x00\x87H\x00g\x00!\xcf" + // 0x021D2 0x00338: 0x021CF + "\x00\x88\f\x00g\x00\"\x04" + // 0x02203 0x00338: 0x02204 + "\x00\x88 \x00g\x00\"\t" + // 0x02208 0x00338: 0x02209 + "\x00\x88,\x00g\x00\"\f" + // 0x0220B 0x00338: 0x0220C + "\x00\x88\x8c\x00g\x00\"$" + // 0x02223 0x00338: 0x02224 + "\x00\x88\x94\x00g\x00\"&" + // 0x02225 0x00338: 0x02226 + "\x00\x88\xf0\x00g\x00\"A" + // 0x0223C 0x00338: 0x02241 + "\x00\x89\f\x00g\x00\"D" + // 0x02243 0x00338: 0x02244 + "\x00\x89\x14\x00g\x00\"G" + // 0x02245 0x00338: 0x02247 + "\x00\x89 \x00g\x00\"I" + // 0x02248 0x00338: 0x02249 + "\x00\x00\xf4\x00g\x00\"`" + // 0x0003D 0x00338: 0x02260 + "\x00\x89\x84\x00g\x00\"b" + // 0x02261 0x00338: 0x02262 + "\x00\x894\x00g\x00\"m" + // 0x0224D 0x00338: 0x0226D + "\x00\x00\xf0\x00g\x00\"n" + // 0x0003C 0x00338: 0x0226E + "\x00\x00\xf8\x00g\x00\"o" + // 0x0003E 0x00338: 0x0226F + "\x00\x89\x90\x00g\x00\"p" + // 0x02264 0x00338: 0x02270 + "\x00\x89\x94\x00g\x00\"q" + // 0x02265 0x00338: 0x02271 + "\x00\x89\xc8\x00g\x00\"t" + // 0x02272 0x00338: 0x02274 + "\x00\x89\xcc\x00g\x00\"u" + // 0x02273 0x00338: 0x02275 + "\x00\x89\xd8\x00g\x00\"x" + // 0x02276 0x00338: 0x02278 + "\x00\x89\xdc\x00g\x00\"y" + // 0x02277 0x00338: 0x02279 + "\x00\x89\xe8\x00g\x00\"\x80" + // 0x0227A 0x00338: 0x02280 + "\x00\x89\xec\x00g\x00\"\x81" + // 0x0227B 0x00338: 0x02281 + "\x00\x8a\b\x00g\x00\"\x84" + // 0x02282 0x00338: 0x02284 + "\x00\x8a\f\x00g\x00\"\x85" + // 0x02283 0x00338: 0x02285 + "\x00\x8a\x18\x00g\x00\"\x88" + // 0x02286 0x00338: 0x02288 + "\x00\x8a\x1c\x00g\x00\"\x89" + // 0x02287 0x00338: 0x02289 + "\x00\x8a\x88\x00g\x00\"\xac" + // 0x022A2 0x00338: 0x022AC + "\x00\x8a\xa0\x00g\x00\"\xad" + // 0x022A8 0x00338: 0x022AD + "\x00\x8a\xa4\x00g\x00\"\xae" + // 0x022A9 0x00338: 0x022AE + "\x00\x8a\xac\x00g\x00\"\xaf" + // 0x022AB 0x00338: 0x022AF + "\x00\x89\xf0\x00g\x00\"\xe0" + // 0x0227C 0x00338: 0x022E0 + "\x00\x89\xf4\x00g\x00\"\xe1" + // 0x0227D 0x00338: 0x022E1 + "\x00\x8aD\x00g\x00\"\xe2" + // 0x02291 0x00338: 0x022E2 + "\x00\x8aH\x00g\x00\"\xe3" + // 0x02292 0x00338: 0x022E3 + "\x00\x8a\xc8\x00g\x00\"\xea" + // 0x022B2 0x00338: 0x022EA + "\x00\x8a\xcc\x00g\x00\"\xeb" + // 0x022B3 0x00338: 0x022EB + "\x00\x8a\xd0\x00g\x00\"\xec" + // 0x022B4 0x00338: 0x022EC + "\x00\x8a\xd4\x00g\x00\"\xed" + // 0x022B5 0x00338: 0x022ED + "\x00\xc1,\x06\x13 0L" + // 0x0304B 0x03099: 0x0304C + "\x00\xc14\x06\x13 0N" + // 0x0304D 0x03099: 0x0304E + "\x00\xc1<\x06\x13 0P" + // 0x0304F 0x03099: 0x03050 + "\x00\xc1D\x06\x13 0R" + // 0x03051 0x03099: 0x03052 + "\x00\xc1L\x06\x13 0T" + // 0x03053 0x03099: 0x03054 + "\x00\xc1T\x06\x13 0V" + // 0x03055 0x03099: 0x03056 + "\x00\xc1\\\x06\x13 0X" + // 0x03057 0x03099: 0x03058 + "\x00\xc1d\x06\x13 0Z" + // 0x03059 0x03099: 0x0305A + "\x00\xc1l\x06\x13 0\\" + // 0x0305B 0x03099: 0x0305C + "\x00\xc1t\x06\x13 0^" + // 0x0305D 0x03099: 0x0305E + "\x00\xc1|\x06\x13 0`" + // 0x0305F 0x03099: 0x03060 + "\x00\xc1\x84\x06\x13 0b" + // 0x03061 0x03099: 0x03062 + "\x00\xc1\x90\x06\x13 0e" + // 0x03064 0x03099: 0x03065 + "\x00\xc1\x98\x06\x13 0g" + // 0x03066 0x03099: 0x03067 + "\x00\xc1\xa0\x06\x13 0i" + // 0x03068 0x03099: 0x03069 + "\x00\xc1\xbc\x06\x13 0p" + // 0x0306F 0x03099: 0x03070 + "\x00\xc1\xbc\x06\x13@0q" + // 0x0306F 0x0309A: 0x03071 + "\x00\xc1\xc8\x06\x13 0s" + // 0x03072 0x03099: 0x03073 + "\x00\xc1\xc8\x06\x13@0t" + // 0x03072 0x0309A: 0x03074 + "\x00\xc1\xd4\x06\x13 0v" + // 0x03075 0x03099: 0x03076 + "\x00\xc1\xd4\x06\x13@0w" + // 0x03075 0x0309A: 0x03077 + "\x00\xc1\xe0\x06\x13 0y" + // 0x03078 0x03099: 0x03079 + "\x00\xc1\xe0\x06\x13@0z" + // 0x03078 0x0309A: 0x0307A + "\x00\xc1\xec\x06\x13 0|" + // 0x0307B 0x03099: 0x0307C + "\x00\xc1\xec\x06\x13@0}" + // 0x0307B 0x0309A: 0x0307D + "\x00\xc1\x18\x06\x13 0\x94" + // 0x03046 0x03099: 0x03094 + "\x00\xc2t\x06\x13 0\x9e" + // 0x0309D 0x03099: 0x0309E + "\x00¬\x06\x13 0\xac" + // 0x030AB 0x03099: 0x030AC + "\x00´\x06\x13 0\xae" + // 0x030AD 0x03099: 0x030AE + "\x00¼\x06\x13 0\xb0" + // 0x030AF 0x03099: 0x030B0 + "\x00\xc2\xc4\x06\x13 0\xb2" + // 0x030B1 0x03099: 0x030B2 + "\x00\xc2\xcc\x06\x13 0\xb4" + // 0x030B3 0x03099: 0x030B4 + "\x00\xc2\xd4\x06\x13 0\xb6" + // 0x030B5 0x03099: 0x030B6 + "\x00\xc2\xdc\x06\x13 0\xb8" + // 0x030B7 0x03099: 0x030B8 + "\x00\xc2\xe4\x06\x13 0\xba" + // 0x030B9 0x03099: 0x030BA + "\x00\xc2\xec\x06\x13 0\xbc" + // 0x030BB 0x03099: 0x030BC + "\x00\xc2\xf4\x06\x13 0\xbe" + // 0x030BD 0x03099: 0x030BE + "\x00\xc2\xfc\x06\x13 0\xc0" + // 0x030BF 0x03099: 0x030C0 + "\x00\xc3\x04\x06\x13 0\xc2" + // 0x030C1 0x03099: 0x030C2 + "\x00\xc3\x10\x06\x13 0\xc5" + // 0x030C4 0x03099: 0x030C5 + "\x00\xc3\x18\x06\x13 0\xc7" + // 0x030C6 0x03099: 0x030C7 + "\x00\xc3 \x06\x13 0\xc9" + // 0x030C8 0x03099: 0x030C9 + "\x00\xc3<\x06\x13 0\xd0" + // 0x030CF 0x03099: 0x030D0 + "\x00\xc3<\x06\x13@0\xd1" + // 0x030CF 0x0309A: 0x030D1 + "\x00\xc3H\x06\x13 0\xd3" + // 0x030D2 0x03099: 0x030D3 + "\x00\xc3H\x06\x13@0\xd4" + // 0x030D2 0x0309A: 0x030D4 + "\x00\xc3T\x06\x13 0\xd6" + // 0x030D5 0x03099: 0x030D6 + "\x00\xc3T\x06\x13@0\xd7" + // 0x030D5 0x0309A: 0x030D7 + "\x00\xc3`\x06\x13 0\xd9" + // 0x030D8 0x03099: 0x030D9 + "\x00\xc3`\x06\x13@0\xda" + // 0x030D8 0x0309A: 0x030DA + "\x00\xc3l\x06\x13 0\xdc" + // 0x030DB 0x03099: 0x030DC + "\x00\xc3l\x06\x13@0\xdd" + // 0x030DB 0x0309A: 0x030DD + "\x00\u0098\x06\x13 0\xf4" + // 0x030A6 0x03099: 0x030F4 + "\x00ü\x06\x13 0\xf7" + // 0x030EF 0x03099: 0x030F7 + "\x00\xc3\xc0\x06\x13 0\xf8" + // 0x030F0 0x03099: 0x030F8 + "\x00\xc3\xc4\x06\x13 0\xf9" + // 0x030F1 0x03099: 0x030F9 + "\x00\xc3\xc8\x06\x13 0\xfa" + // 0x030F2 0x03099: 0x030FA + "\x00\xc3\xf4\x06\x13 0\xfe" + // 0x030FD 0x03099: 0x030FE + "\x04Bd\"\x17A\x10\x9a" + // 0x11099 0x110BA: 0x1109A + "\x04Bl\"\x17A\x10\x9c" + // 0x1109B 0x110BA: 0x1109C + "\x04B\x94\"\x17A\x10\xab" + // 0x110A5 0x110BA: 0x110AB + "\x04D\xc4\"$\xe1\x11." + // 0x11131 0x11127: 0x1112E + "\x04D\xc8\"$\xe1\x11/" + // 0x11132 0x11127: 0x1112F + "\x04M\x1c\"g\xc1\x13K" + // 0x11347 0x1133E: 0x1134B + "\x04M\x1c\"j\xe1\x13L" + // 0x11347 0x11357: 0x1134C + "\x04R\xe4\"\x97A\x14\xbb" + // 0x114B9 0x114BA: 0x114BB + "\x04R\xe4\"\x96\x01\x14\xbc" + // 0x114B9 0x114B0: 0x114BC + "\x04R\xe4\"\x97\xa1\x14\xbe" + // 0x114B9 0x114BD: 0x114BE + "\x04V\xe0\"\xb5\xe1\x15\xba" + // 0x115B8 0x115AF: 0x115BA + "\x04V\xe4\"\xb5\xe1\x15\xbb" + // 0x115B9 0x115AF: 0x115BB + "\x04d\xd4#&\x01\x198" + // 0x11935 0x11930: 0x11938 "" // Total size of tables: 56KB (57068 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/tables17.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables17.0.0.go index dfd555fc..c3231891 100644 --- a/vendor/golang.org/x/text/unicode/norm/tables17.0.0.go +++ b/vendor/golang.org/x/text/unicode/norm/tables17.0.0.go @@ -7135,970 +7135,970 @@ var nfkcSparseValues = [980]valueRange{ } // recompMap: 7688 bytes (entries only) -var recompMap map[uint32]rune +var recompMap map[uint64]rune var recompMapOnce sync.Once const recompMapPacked = "" + - "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0 - "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1 - "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2 - "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3 - "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4 - "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5 - "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7 - "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8 - "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9 - "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA - "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB - "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC - "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD - "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE - "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF - "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1 - "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2 - "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3 - "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4 - "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5 - "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6 - "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9 - "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA - "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB - "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC - "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD - "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0 - "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1 - "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2 - "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3 - "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4 - "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5 - "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7 - "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8 - "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9 - "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA - "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB - "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC - "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED - "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE - "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF - "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1 - "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2 - "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3 - "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4 - "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5 - "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6 - "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9 - "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA - "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB - "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC - "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD - "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF - "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100 - "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101 - "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102 - "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103 - "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104 - "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105 - "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106 - "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107 - "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108 - "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109 - "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A - "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B - "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C - "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D - "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E - "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F - "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112 - "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113 - "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114 - "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115 - "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116 - "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117 - "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118 - "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119 - "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A - "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B - "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C - "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D - "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E - "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F - "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120 - "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121 - "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122 - "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123 - "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124 - "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125 - "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128 - "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129 - "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A - "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B - "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C - "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D - "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E - "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F - "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130 - "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134 - "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135 - "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136 - "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137 - "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139 - "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A - "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B - "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C - "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D - "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E - "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 - "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 - "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 - "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 - "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 - "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 - "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C - "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D - "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E - "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F - "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 - "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 - "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 - "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 - "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 - "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 - "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 - "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 - "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A - "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B - "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C - "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D - "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E - "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F - "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 - "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 - "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 - "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 - "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 - "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 - "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 - "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 - "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A - "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B - "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C - "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D - "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E - "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F - "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 - "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 - "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 - "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 - "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 - "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 - "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 - "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 - "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 - "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 - "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A - "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B - "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C - "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D - "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E - "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 - "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 - "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF - "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 - "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD - "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE - "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF - "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 - "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 - "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 - "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 - "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 - "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 - "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 - "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 - "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 - "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 - "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA - "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB - "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC - "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE - "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF - "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 - "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 - "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 - "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 - "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 - "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 - "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 - "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 - "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA - "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB - "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC - "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED - "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE - "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF - "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 - "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 - "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 - "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 - "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 - "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA - "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB - "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC - "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD - "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE - "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF - "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 - "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 - "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 - "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 - "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 - "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 - "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 - "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 - "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 - "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 - "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A - "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B - "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C - "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D - "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E - "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F - "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 - "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 - "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 - "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 - "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 - "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 - "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 - "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 - "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 - "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 - "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A - "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B - "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E - "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F - "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 - "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 - "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 - "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 - "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A - "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B - "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C - "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D - "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E - "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F - "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 - "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 - "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 - "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 - "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 - "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 - "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 - "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 - "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A - "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C - "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E - "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F - "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 - "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA - "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB - "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC - "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD - "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE - "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF - "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 - "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA - "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB - "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC - "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD - "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE - "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 - "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 - "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 - "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 - "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 - "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 - "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C - "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D - "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E - "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 - "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 - "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 - "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 - "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 - "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 - "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C - "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D - "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E - "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 - "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 - "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 - "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 - "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 - "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 - "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 - "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 - "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 - "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 - "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA - "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB - "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC - "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD - "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE - "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF - "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 - "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 - "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 - "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 - "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 - "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 - "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA - "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB - "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC - "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED - "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE - "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF - "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 - "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 - "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 - "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 - "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 - "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 - "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 - "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 - "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 - "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 - "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 - "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 - "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 - "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 - "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 - "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 - "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 - "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 - "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 - "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB - "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC - "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 - "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B - "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C - "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 - "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA - "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB - "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC - "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 - "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 - "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 - "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 - "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA - "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB - "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A - "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B - "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C - "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA - "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC - "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD - "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE - "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 - "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 - "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 - "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A - "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C - "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E - "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 - "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B - "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D - "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 - "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 - "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 - "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 - "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 - "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 - "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 - "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 - "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 - "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 - "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 - "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 - "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 - "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A - "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B - "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C - "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D - "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E - "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F - "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 - "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 - "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 - "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 - "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 - "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 - "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 - "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 - "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 - "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 - "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A - "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B - "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C - "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D - "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E - "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F - "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 - "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 - "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 - "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 - "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 - "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 - "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 - "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 - "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 - "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 - "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A - "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B - "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C - "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D - "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E - "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F - "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 - "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 - "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 - "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 - "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 - "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 - "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 - "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 - "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 - "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 - "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A - "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B - "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C - "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D - "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E - "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F - "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 - "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 - "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 - "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 - "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 - "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 - "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 - "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 - "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 - "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 - "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A - "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B - "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C - "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D - "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E - "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F - "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 - "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 - "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 - "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 - "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 - "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 - "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 - "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 - "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 - "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 - "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A - "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B - "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C - "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D - "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E - "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F - "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 - "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 - "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 - "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 - "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 - "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 - "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 - "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 - "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 - "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 - "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A - "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B - "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C - "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D - "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E - "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F - "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 - "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 - "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 - "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 - "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 - "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 - "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 - "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 - "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 - "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 - "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A - "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B - "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C - "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D - "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E - "\x00v\x03#\x00\x00\x1e\x7f" + // 0x00760323: 0x00001E7F - "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 - "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 - "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 - "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 - "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 - "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 - "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 - "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 - "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 - "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 - "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A - "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B - "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C - "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D - "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E - "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F - "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 - "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 - "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 - "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 - "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 - "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 - "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 - "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 - "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 - "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 - "\x01\x7f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B - "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 - "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 - "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 - "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 - "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 - "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 - "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 - "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 - "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 - "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 - "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA - "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB - "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC - "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD - "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE - "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF - "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 - "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 - "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 - "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 - "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 - "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 - "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 - "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 - "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 - "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 - "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA - "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB - "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC - "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD - "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE - "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF - "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 - "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 - "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 - "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 - "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 - "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 - "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 - "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 - "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 - "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 - "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA - "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB - "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC - "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD - "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE - "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF - "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 - "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 - "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 - "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 - "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 - "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 - "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 - "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 - "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 - "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 - "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA - "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB - "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC - "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD - "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE - "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF - "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 - "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 - "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 - "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 - "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 - "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 - "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 - "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 - "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 - "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 - "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA - "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB - "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC - "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED - "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE - "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF - "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 - "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 - "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 - "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 - "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 - "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 - "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 - "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 - "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 - "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 - "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 - "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 - "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 - "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 - "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 - "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 - "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 - "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 - "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 - "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 - "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A - "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B - "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C - "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D - "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E - "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F - "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 - "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 - "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 - "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 - "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 - "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 - "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 - "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 - "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A - "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B - "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C - "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D - "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 - "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 - "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 - "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 - "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 - "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 - "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 - "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 - "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 - "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 - "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A - "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B - "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C - "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D - "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E - "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F - "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 - "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 - "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 - "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 - "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 - "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 - "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 - "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 - "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 - "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 - "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A - "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B - "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C - "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D - "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E - "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F - "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 - "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 - "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 - "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 - "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 - "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 - "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 - "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 - "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A - "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B - "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C - "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D - "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 - "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 - "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 - "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 - "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 - "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 - "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 - "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 - "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 - "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B - "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D - "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F - "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 - "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 - "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 - "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 - "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 - "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 - "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 - "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 - "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 - "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 - "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A - "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B - "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C - "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D - "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E - "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F - "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 - "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 - "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 - "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 - "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 - "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A - "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C - "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 - "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 - "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 - "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 - "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 - "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 - "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 - "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 - "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 - "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 - "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A - "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B - "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C - "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D - "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E - "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F - "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 - "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 - "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 - "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 - "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 - "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 - "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 - "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 - "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 - "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 - "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A - "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B - "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C - "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D - "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E - "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F - "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 - "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 - "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 - "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 - "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 - "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 - "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 - "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 - "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 - "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 - "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA - "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB - "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC - "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD - "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE - "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF - "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 - "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 - "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 - "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 - "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 - "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 - "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 - "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 - "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 - "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA - "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC - "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 - "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 - "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 - "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 - "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 - "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 - "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 - "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA - "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC - "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD - "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE - "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF - "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 - "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 - "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 - "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 - "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 - "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 - "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 - "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA - "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD - "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE - "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF - "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 - "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 - "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 - "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 - "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 - "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 - "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 - "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 - "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 - "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA - "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC - "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED - "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 - "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 - "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 - "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 - "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 - "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 - "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA - "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC - "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A - "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B - "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE - "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD - "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE - "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF - "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 - "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 - "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C - "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 - "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 - "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 - "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 - "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 - "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 - "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 - "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 - "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D - "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E - "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F - "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 - "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 - "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 - "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 - "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 - "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 - "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 - "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 - "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 - "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 - "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 - "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 - "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC - "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD - "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE - "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF - "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 - "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 - "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 - "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 - "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA - "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB - "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC - "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED - "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C - "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E - "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 - "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 - "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 - "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 - "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 - "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A - "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C - "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E - "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 - "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 - "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 - "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 - "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 - "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 - "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 - "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 - "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 - "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 - "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 - "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 - "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A - "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C - "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D - "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 - "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E - "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC - "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE - "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 - "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 - "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 - "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 - "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 - "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA - "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC - "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE - "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 - "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 - "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 - "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 - "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 - "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 - "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 - "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 - "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 - "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 - "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 - "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 - "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA - "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC - "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD - "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 - "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 - "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 - "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 - "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA - "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE - "\x05\xd2\x03\a\x00\x01\x05\xc9" + // 0x05D20307: 0x000105C9 - "\x05\xda\x03\a\x00\x01\x05\xe4" + // 0x05DA0307: 0x000105E4 - "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A - "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C - "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB - "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E - "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F - "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B - "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C - "\x13\x82\x13\xc9\x00\x01\x13\x83" + // 0x138213C9: 0x00011383 - "\x13\x84\x13\xbb\x00\x01\x13\x85" + // 0x138413BB: 0x00011385 - "\x13\x8b\x13\xc2\x00\x01\x13\x8e" + // 0x138B13C2: 0x0001138E - "\x13\x90\x13\xc9\x00\x01\x13\x91" + // 0x139013C9: 0x00011391 - "\x13\xc2\x13\xc2\x00\x01\x13\xc5" + // 0x13C213C2: 0x000113C5 - "\x13\xc2\x13\xb8\x00\x01\x13\xc7" + // 0x13C213B8: 0x000113C7 - "\x13\xc2\x13\xc9\x00\x01\x13\xc8" + // 0x13C213C9: 0x000113C8 - "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB - "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC - "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE - "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA - "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB - "\x195\x190\x00\x01\x198" + // 0x19351930: 0x00011938 - "a\x1ea\x1e\x00\x01a!" + // 0x611E611E: 0x00016121 - "a\x1ea)\x00\x01a\"" + // 0x611E6129: 0x00016122 - "a\x1ea\x1f\x00\x01a#" + // 0x611E611F: 0x00016123 - "a)a\x1f\x00\x01a$" + // 0x6129611F: 0x00016124 - "a\x1ea \x00\x01a%" + // 0x611E6120: 0x00016125 - "a!a\x1f\x00\x01a&" + // 0x6121611F: 0x00016126 - "a\"a\x1f\x00\x01a'" + // 0x6122611F: 0x00016127 - "a!a \x00\x01a(" + // 0x61216120: 0x00016128 - "mgmg\x00\x01mh" + // 0x6D676D67: 0x00016D68 - "mcmg\x00\x01mi" + // 0x6D636D67: 0x00016D69 - "mimg\x00\x01mj" + // 0x6D696D67: 0x00016D6A + "\x00\x01\x04\x00`\x00\x00\xc0" + // 0x00041 0x00300: 0x000C0 + "\x00\x01\x04\x00` \x00\xc1" + // 0x00041 0x00301: 0x000C1 + "\x00\x01\x04\x00`@\x00\xc2" + // 0x00041 0x00302: 0x000C2 + "\x00\x01\x04\x00``\x00\xc3" + // 0x00041 0x00303: 0x000C3 + "\x00\x01\x04\x00a\x00\x00\xc4" + // 0x00041 0x00308: 0x000C4 + "\x00\x01\x04\x00a@\x00\xc5" + // 0x00041 0x0030A: 0x000C5 + "\x00\x01\f\x00d\xe0\x00\xc7" + // 0x00043 0x00327: 0x000C7 + "\x00\x01\x14\x00`\x00\x00\xc8" + // 0x00045 0x00300: 0x000C8 + "\x00\x01\x14\x00` \x00\xc9" + // 0x00045 0x00301: 0x000C9 + "\x00\x01\x14\x00`@\x00\xca" + // 0x00045 0x00302: 0x000CA + "\x00\x01\x14\x00a\x00\x00\xcb" + // 0x00045 0x00308: 0x000CB + "\x00\x01$\x00`\x00\x00\xcc" + // 0x00049 0x00300: 0x000CC + "\x00\x01$\x00` \x00\xcd" + // 0x00049 0x00301: 0x000CD + "\x00\x01$\x00`@\x00\xce" + // 0x00049 0x00302: 0x000CE + "\x00\x01$\x00a\x00\x00\xcf" + // 0x00049 0x00308: 0x000CF + "\x00\x018\x00``\x00\xd1" + // 0x0004E 0x00303: 0x000D1 + "\x00\x01<\x00`\x00\x00\xd2" + // 0x0004F 0x00300: 0x000D2 + "\x00\x01<\x00` \x00\xd3" + // 0x0004F 0x00301: 0x000D3 + "\x00\x01<\x00`@\x00\xd4" + // 0x0004F 0x00302: 0x000D4 + "\x00\x01<\x00``\x00\xd5" + // 0x0004F 0x00303: 0x000D5 + "\x00\x01<\x00a\x00\x00\xd6" + // 0x0004F 0x00308: 0x000D6 + "\x00\x01T\x00`\x00\x00\xd9" + // 0x00055 0x00300: 0x000D9 + "\x00\x01T\x00` \x00\xda" + // 0x00055 0x00301: 0x000DA + "\x00\x01T\x00`@\x00\xdb" + // 0x00055 0x00302: 0x000DB + "\x00\x01T\x00a\x00\x00\xdc" + // 0x00055 0x00308: 0x000DC + "\x00\x01d\x00` \x00\xdd" + // 0x00059 0x00301: 0x000DD + "\x00\x01\x84\x00`\x00\x00\xe0" + // 0x00061 0x00300: 0x000E0 + "\x00\x01\x84\x00` \x00\xe1" + // 0x00061 0x00301: 0x000E1 + "\x00\x01\x84\x00`@\x00\xe2" + // 0x00061 0x00302: 0x000E2 + "\x00\x01\x84\x00``\x00\xe3" + // 0x00061 0x00303: 0x000E3 + "\x00\x01\x84\x00a\x00\x00\xe4" + // 0x00061 0x00308: 0x000E4 + "\x00\x01\x84\x00a@\x00\xe5" + // 0x00061 0x0030A: 0x000E5 + "\x00\x01\x8c\x00d\xe0\x00\xe7" + // 0x00063 0x00327: 0x000E7 + "\x00\x01\x94\x00`\x00\x00\xe8" + // 0x00065 0x00300: 0x000E8 + "\x00\x01\x94\x00` \x00\xe9" + // 0x00065 0x00301: 0x000E9 + "\x00\x01\x94\x00`@\x00\xea" + // 0x00065 0x00302: 0x000EA + "\x00\x01\x94\x00a\x00\x00\xeb" + // 0x00065 0x00308: 0x000EB + "\x00\x01\xa4\x00`\x00\x00\xec" + // 0x00069 0x00300: 0x000EC + "\x00\x01\xa4\x00` \x00\xed" + // 0x00069 0x00301: 0x000ED + "\x00\x01\xa4\x00`@\x00\xee" + // 0x00069 0x00302: 0x000EE + "\x00\x01\xa4\x00a\x00\x00\xef" + // 0x00069 0x00308: 0x000EF + "\x00\x01\xb8\x00``\x00\xf1" + // 0x0006E 0x00303: 0x000F1 + "\x00\x01\xbc\x00`\x00\x00\xf2" + // 0x0006F 0x00300: 0x000F2 + "\x00\x01\xbc\x00` \x00\xf3" + // 0x0006F 0x00301: 0x000F3 + "\x00\x01\xbc\x00`@\x00\xf4" + // 0x0006F 0x00302: 0x000F4 + "\x00\x01\xbc\x00``\x00\xf5" + // 0x0006F 0x00303: 0x000F5 + "\x00\x01\xbc\x00a\x00\x00\xf6" + // 0x0006F 0x00308: 0x000F6 + "\x00\x01\xd4\x00`\x00\x00\xf9" + // 0x00075 0x00300: 0x000F9 + "\x00\x01\xd4\x00` \x00\xfa" + // 0x00075 0x00301: 0x000FA + "\x00\x01\xd4\x00`@\x00\xfb" + // 0x00075 0x00302: 0x000FB + "\x00\x01\xd4\x00a\x00\x00\xfc" + // 0x00075 0x00308: 0x000FC + "\x00\x01\xe4\x00` \x00\xfd" + // 0x00079 0x00301: 0x000FD + "\x00\x01\xe4\x00a\x00\x00\xff" + // 0x00079 0x00308: 0x000FF + "\x00\x01\x04\x00`\x80\x01\x00" + // 0x00041 0x00304: 0x00100 + "\x00\x01\x84\x00`\x80\x01\x01" + // 0x00061 0x00304: 0x00101 + "\x00\x01\x04\x00`\xc0\x01\x02" + // 0x00041 0x00306: 0x00102 + "\x00\x01\x84\x00`\xc0\x01\x03" + // 0x00061 0x00306: 0x00103 + "\x00\x01\x04\x00e\x00\x01\x04" + // 0x00041 0x00328: 0x00104 + "\x00\x01\x84\x00e\x00\x01\x05" + // 0x00061 0x00328: 0x00105 + "\x00\x01\f\x00` \x01\x06" + // 0x00043 0x00301: 0x00106 + "\x00\x01\x8c\x00` \x01\a" + // 0x00063 0x00301: 0x00107 + "\x00\x01\f\x00`@\x01\b" + // 0x00043 0x00302: 0x00108 + "\x00\x01\x8c\x00`@\x01\t" + // 0x00063 0x00302: 0x00109 + "\x00\x01\f\x00`\xe0\x01\n" + // 0x00043 0x00307: 0x0010A + "\x00\x01\x8c\x00`\xe0\x01\v" + // 0x00063 0x00307: 0x0010B + "\x00\x01\f\x00a\x80\x01\f" + // 0x00043 0x0030C: 0x0010C + "\x00\x01\x8c\x00a\x80\x01\r" + // 0x00063 0x0030C: 0x0010D + "\x00\x01\x10\x00a\x80\x01\x0e" + // 0x00044 0x0030C: 0x0010E + "\x00\x01\x90\x00a\x80\x01\x0f" + // 0x00064 0x0030C: 0x0010F + "\x00\x01\x14\x00`\x80\x01\x12" + // 0x00045 0x00304: 0x00112 + "\x00\x01\x94\x00`\x80\x01\x13" + // 0x00065 0x00304: 0x00113 + "\x00\x01\x14\x00`\xc0\x01\x14" + // 0x00045 0x00306: 0x00114 + "\x00\x01\x94\x00`\xc0\x01\x15" + // 0x00065 0x00306: 0x00115 + "\x00\x01\x14\x00`\xe0\x01\x16" + // 0x00045 0x00307: 0x00116 + "\x00\x01\x94\x00`\xe0\x01\x17" + // 0x00065 0x00307: 0x00117 + "\x00\x01\x14\x00e\x00\x01\x18" + // 0x00045 0x00328: 0x00118 + "\x00\x01\x94\x00e\x00\x01\x19" + // 0x00065 0x00328: 0x00119 + "\x00\x01\x14\x00a\x80\x01\x1a" + // 0x00045 0x0030C: 0x0011A + "\x00\x01\x94\x00a\x80\x01\x1b" + // 0x00065 0x0030C: 0x0011B + "\x00\x01\x1c\x00`@\x01\x1c" + // 0x00047 0x00302: 0x0011C + "\x00\x01\x9c\x00`@\x01\x1d" + // 0x00067 0x00302: 0x0011D + "\x00\x01\x1c\x00`\xc0\x01\x1e" + // 0x00047 0x00306: 0x0011E + "\x00\x01\x9c\x00`\xc0\x01\x1f" + // 0x00067 0x00306: 0x0011F + "\x00\x01\x1c\x00`\xe0\x01 " + // 0x00047 0x00307: 0x00120 + "\x00\x01\x9c\x00`\xe0\x01!" + // 0x00067 0x00307: 0x00121 + "\x00\x01\x1c\x00d\xe0\x01\"" + // 0x00047 0x00327: 0x00122 + "\x00\x01\x9c\x00d\xe0\x01#" + // 0x00067 0x00327: 0x00123 + "\x00\x01 \x00`@\x01$" + // 0x00048 0x00302: 0x00124 + "\x00\x01\xa0\x00`@\x01%" + // 0x00068 0x00302: 0x00125 + "\x00\x01$\x00``\x01(" + // 0x00049 0x00303: 0x00128 + "\x00\x01\xa4\x00``\x01)" + // 0x00069 0x00303: 0x00129 + "\x00\x01$\x00`\x80\x01*" + // 0x00049 0x00304: 0x0012A + "\x00\x01\xa4\x00`\x80\x01+" + // 0x00069 0x00304: 0x0012B + "\x00\x01$\x00`\xc0\x01," + // 0x00049 0x00306: 0x0012C + "\x00\x01\xa4\x00`\xc0\x01-" + // 0x00069 0x00306: 0x0012D + "\x00\x01$\x00e\x00\x01." + // 0x00049 0x00328: 0x0012E + "\x00\x01\xa4\x00e\x00\x01/" + // 0x00069 0x00328: 0x0012F + "\x00\x01$\x00`\xe0\x010" + // 0x00049 0x00307: 0x00130 + "\x00\x01(\x00`@\x014" + // 0x0004A 0x00302: 0x00134 + "\x00\x01\xa8\x00`@\x015" + // 0x0006A 0x00302: 0x00135 + "\x00\x01,\x00d\xe0\x016" + // 0x0004B 0x00327: 0x00136 + "\x00\x01\xac\x00d\xe0\x017" + // 0x0006B 0x00327: 0x00137 + "\x00\x010\x00` \x019" + // 0x0004C 0x00301: 0x00139 + "\x00\x01\xb0\x00` \x01:" + // 0x0006C 0x00301: 0x0013A + "\x00\x010\x00d\xe0\x01;" + // 0x0004C 0x00327: 0x0013B + "\x00\x01\xb0\x00d\xe0\x01<" + // 0x0006C 0x00327: 0x0013C + "\x00\x010\x00a\x80\x01=" + // 0x0004C 0x0030C: 0x0013D + "\x00\x01\xb0\x00a\x80\x01>" + // 0x0006C 0x0030C: 0x0013E + "\x00\x018\x00` \x01C" + // 0x0004E 0x00301: 0x00143 + "\x00\x01\xb8\x00` \x01D" + // 0x0006E 0x00301: 0x00144 + "\x00\x018\x00d\xe0\x01E" + // 0x0004E 0x00327: 0x00145 + "\x00\x01\xb8\x00d\xe0\x01F" + // 0x0006E 0x00327: 0x00146 + "\x00\x018\x00a\x80\x01G" + // 0x0004E 0x0030C: 0x00147 + "\x00\x01\xb8\x00a\x80\x01H" + // 0x0006E 0x0030C: 0x00148 + "\x00\x01<\x00`\x80\x01L" + // 0x0004F 0x00304: 0x0014C + "\x00\x01\xbc\x00`\x80\x01M" + // 0x0006F 0x00304: 0x0014D + "\x00\x01<\x00`\xc0\x01N" + // 0x0004F 0x00306: 0x0014E + "\x00\x01\xbc\x00`\xc0\x01O" + // 0x0006F 0x00306: 0x0014F + "\x00\x01<\x00a`\x01P" + // 0x0004F 0x0030B: 0x00150 + "\x00\x01\xbc\x00a`\x01Q" + // 0x0006F 0x0030B: 0x00151 + "\x00\x01H\x00` \x01T" + // 0x00052 0x00301: 0x00154 + "\x00\x01\xc8\x00` \x01U" + // 0x00072 0x00301: 0x00155 + "\x00\x01H\x00d\xe0\x01V" + // 0x00052 0x00327: 0x00156 + "\x00\x01\xc8\x00d\xe0\x01W" + // 0x00072 0x00327: 0x00157 + "\x00\x01H\x00a\x80\x01X" + // 0x00052 0x0030C: 0x00158 + "\x00\x01\xc8\x00a\x80\x01Y" + // 0x00072 0x0030C: 0x00159 + "\x00\x01L\x00` \x01Z" + // 0x00053 0x00301: 0x0015A + "\x00\x01\xcc\x00` \x01[" + // 0x00073 0x00301: 0x0015B + "\x00\x01L\x00`@\x01\\" + // 0x00053 0x00302: 0x0015C + "\x00\x01\xcc\x00`@\x01]" + // 0x00073 0x00302: 0x0015D + "\x00\x01L\x00d\xe0\x01^" + // 0x00053 0x00327: 0x0015E + "\x00\x01\xcc\x00d\xe0\x01_" + // 0x00073 0x00327: 0x0015F + "\x00\x01L\x00a\x80\x01`" + // 0x00053 0x0030C: 0x00160 + "\x00\x01\xcc\x00a\x80\x01a" + // 0x00073 0x0030C: 0x00161 + "\x00\x01P\x00d\xe0\x01b" + // 0x00054 0x00327: 0x00162 + "\x00\x01\xd0\x00d\xe0\x01c" + // 0x00074 0x00327: 0x00163 + "\x00\x01P\x00a\x80\x01d" + // 0x00054 0x0030C: 0x00164 + "\x00\x01\xd0\x00a\x80\x01e" + // 0x00074 0x0030C: 0x00165 + "\x00\x01T\x00``\x01h" + // 0x00055 0x00303: 0x00168 + "\x00\x01\xd4\x00``\x01i" + // 0x00075 0x00303: 0x00169 + "\x00\x01T\x00`\x80\x01j" + // 0x00055 0x00304: 0x0016A + "\x00\x01\xd4\x00`\x80\x01k" + // 0x00075 0x00304: 0x0016B + "\x00\x01T\x00`\xc0\x01l" + // 0x00055 0x00306: 0x0016C + "\x00\x01\xd4\x00`\xc0\x01m" + // 0x00075 0x00306: 0x0016D + "\x00\x01T\x00a@\x01n" + // 0x00055 0x0030A: 0x0016E + "\x00\x01\xd4\x00a@\x01o" + // 0x00075 0x0030A: 0x0016F + "\x00\x01T\x00a`\x01p" + // 0x00055 0x0030B: 0x00170 + "\x00\x01\xd4\x00a`\x01q" + // 0x00075 0x0030B: 0x00171 + "\x00\x01T\x00e\x00\x01r" + // 0x00055 0x00328: 0x00172 + "\x00\x01\xd4\x00e\x00\x01s" + // 0x00075 0x00328: 0x00173 + "\x00\x01\\\x00`@\x01t" + // 0x00057 0x00302: 0x00174 + "\x00\x01\xdc\x00`@\x01u" + // 0x00077 0x00302: 0x00175 + "\x00\x01d\x00`@\x01v" + // 0x00059 0x00302: 0x00176 + "\x00\x01\xe4\x00`@\x01w" + // 0x00079 0x00302: 0x00177 + "\x00\x01d\x00a\x00\x01x" + // 0x00059 0x00308: 0x00178 + "\x00\x01h\x00` \x01y" + // 0x0005A 0x00301: 0x00179 + "\x00\x01\xe8\x00` \x01z" + // 0x0007A 0x00301: 0x0017A + "\x00\x01h\x00`\xe0\x01{" + // 0x0005A 0x00307: 0x0017B + "\x00\x01\xe8\x00`\xe0\x01|" + // 0x0007A 0x00307: 0x0017C + "\x00\x01h\x00a\x80\x01}" + // 0x0005A 0x0030C: 0x0017D + "\x00\x01\xe8\x00a\x80\x01~" + // 0x0007A 0x0030C: 0x0017E + "\x00\x01<\x00c`\x01\xa0" + // 0x0004F 0x0031B: 0x001A0 + "\x00\x01\xbc\x00c`\x01\xa1" + // 0x0006F 0x0031B: 0x001A1 + "\x00\x01T\x00c`\x01\xaf" + // 0x00055 0x0031B: 0x001AF + "\x00\x01\xd4\x00c`\x01\xb0" + // 0x00075 0x0031B: 0x001B0 + "\x00\x01\x04\x00a\x80\x01\xcd" + // 0x00041 0x0030C: 0x001CD + "\x00\x01\x84\x00a\x80\x01\xce" + // 0x00061 0x0030C: 0x001CE + "\x00\x01$\x00a\x80\x01\xcf" + // 0x00049 0x0030C: 0x001CF + "\x00\x01\xa4\x00a\x80\x01\xd0" + // 0x00069 0x0030C: 0x001D0 + "\x00\x01<\x00a\x80\x01\xd1" + // 0x0004F 0x0030C: 0x001D1 + "\x00\x01\xbc\x00a\x80\x01\xd2" + // 0x0006F 0x0030C: 0x001D2 + "\x00\x01T\x00a\x80\x01\xd3" + // 0x00055 0x0030C: 0x001D3 + "\x00\x01\xd4\x00a\x80\x01\xd4" + // 0x00075 0x0030C: 0x001D4 + "\x00\x03p\x00`\x80\x01\xd5" + // 0x000DC 0x00304: 0x001D5 + "\x00\x03\xf0\x00`\x80\x01\xd6" + // 0x000FC 0x00304: 0x001D6 + "\x00\x03p\x00` \x01\xd7" + // 0x000DC 0x00301: 0x001D7 + "\x00\x03\xf0\x00` \x01\xd8" + // 0x000FC 0x00301: 0x001D8 + "\x00\x03p\x00a\x80\x01\xd9" + // 0x000DC 0x0030C: 0x001D9 + "\x00\x03\xf0\x00a\x80\x01\xda" + // 0x000FC 0x0030C: 0x001DA + "\x00\x03p\x00`\x00\x01\xdb" + // 0x000DC 0x00300: 0x001DB + "\x00\x03\xf0\x00`\x00\x01\xdc" + // 0x000FC 0x00300: 0x001DC + "\x00\x03\x10\x00`\x80\x01\xde" + // 0x000C4 0x00304: 0x001DE + "\x00\x03\x90\x00`\x80\x01\xdf" + // 0x000E4 0x00304: 0x001DF + "\x00\b\x98\x00`\x80\x01\xe0" + // 0x00226 0x00304: 0x001E0 + "\x00\b\x9c\x00`\x80\x01\xe1" + // 0x00227 0x00304: 0x001E1 + "\x00\x03\x18\x00`\x80\x01\xe2" + // 0x000C6 0x00304: 0x001E2 + "\x00\x03\x98\x00`\x80\x01\xe3" + // 0x000E6 0x00304: 0x001E3 + "\x00\x01\x1c\x00a\x80\x01\xe6" + // 0x00047 0x0030C: 0x001E6 + "\x00\x01\x9c\x00a\x80\x01\xe7" + // 0x00067 0x0030C: 0x001E7 + "\x00\x01,\x00a\x80\x01\xe8" + // 0x0004B 0x0030C: 0x001E8 + "\x00\x01\xac\x00a\x80\x01\xe9" + // 0x0006B 0x0030C: 0x001E9 + "\x00\x01<\x00e\x00\x01\xea" + // 0x0004F 0x00328: 0x001EA + "\x00\x01\xbc\x00e\x00\x01\xeb" + // 0x0006F 0x00328: 0x001EB + "\x00\a\xa8\x00`\x80\x01\xec" + // 0x001EA 0x00304: 0x001EC + "\x00\a\xac\x00`\x80\x01\xed" + // 0x001EB 0x00304: 0x001ED + "\x00\x06\xdc\x00a\x80\x01\xee" + // 0x001B7 0x0030C: 0x001EE + "\x00\nH\x00a\x80\x01\xef" + // 0x00292 0x0030C: 0x001EF + "\x00\x01\xa8\x00a\x80\x01\xf0" + // 0x0006A 0x0030C: 0x001F0 + "\x00\x01\x1c\x00` \x01\xf4" + // 0x00047 0x00301: 0x001F4 + "\x00\x01\x9c\x00` \x01\xf5" + // 0x00067 0x00301: 0x001F5 + "\x00\x018\x00`\x00\x01\xf8" + // 0x0004E 0x00300: 0x001F8 + "\x00\x01\xb8\x00`\x00\x01\xf9" + // 0x0006E 0x00300: 0x001F9 + "\x00\x03\x14\x00` \x01\xfa" + // 0x000C5 0x00301: 0x001FA + "\x00\x03\x94\x00` \x01\xfb" + // 0x000E5 0x00301: 0x001FB + "\x00\x03\x18\x00` \x01\xfc" + // 0x000C6 0x00301: 0x001FC + "\x00\x03\x98\x00` \x01\xfd" + // 0x000E6 0x00301: 0x001FD + "\x00\x03`\x00` \x01\xfe" + // 0x000D8 0x00301: 0x001FE + "\x00\x03\xe0\x00` \x01\xff" + // 0x000F8 0x00301: 0x001FF + "\x00\x01\x04\x00a\xe0\x02\x00" + // 0x00041 0x0030F: 0x00200 + "\x00\x01\x84\x00a\xe0\x02\x01" + // 0x00061 0x0030F: 0x00201 + "\x00\x01\x04\x00b \x02\x02" + // 0x00041 0x00311: 0x00202 + "\x00\x01\x84\x00b \x02\x03" + // 0x00061 0x00311: 0x00203 + "\x00\x01\x14\x00a\xe0\x02\x04" + // 0x00045 0x0030F: 0x00204 + "\x00\x01\x94\x00a\xe0\x02\x05" + // 0x00065 0x0030F: 0x00205 + "\x00\x01\x14\x00b \x02\x06" + // 0x00045 0x00311: 0x00206 + "\x00\x01\x94\x00b \x02\a" + // 0x00065 0x00311: 0x00207 + "\x00\x01$\x00a\xe0\x02\b" + // 0x00049 0x0030F: 0x00208 + "\x00\x01\xa4\x00a\xe0\x02\t" + // 0x00069 0x0030F: 0x00209 + "\x00\x01$\x00b \x02\n" + // 0x00049 0x00311: 0x0020A + "\x00\x01\xa4\x00b \x02\v" + // 0x00069 0x00311: 0x0020B + "\x00\x01<\x00a\xe0\x02\f" + // 0x0004F 0x0030F: 0x0020C + "\x00\x01\xbc\x00a\xe0\x02\r" + // 0x0006F 0x0030F: 0x0020D + "\x00\x01<\x00b \x02\x0e" + // 0x0004F 0x00311: 0x0020E + "\x00\x01\xbc\x00b \x02\x0f" + // 0x0006F 0x00311: 0x0020F + "\x00\x01H\x00a\xe0\x02\x10" + // 0x00052 0x0030F: 0x00210 + "\x00\x01\xc8\x00a\xe0\x02\x11" + // 0x00072 0x0030F: 0x00211 + "\x00\x01H\x00b \x02\x12" + // 0x00052 0x00311: 0x00212 + "\x00\x01\xc8\x00b \x02\x13" + // 0x00072 0x00311: 0x00213 + "\x00\x01T\x00a\xe0\x02\x14" + // 0x00055 0x0030F: 0x00214 + "\x00\x01\xd4\x00a\xe0\x02\x15" + // 0x00075 0x0030F: 0x00215 + "\x00\x01T\x00b \x02\x16" + // 0x00055 0x00311: 0x00216 + "\x00\x01\xd4\x00b \x02\x17" + // 0x00075 0x00311: 0x00217 + "\x00\x01L\x00d\xc0\x02\x18" + // 0x00053 0x00326: 0x00218 + "\x00\x01\xcc\x00d\xc0\x02\x19" + // 0x00073 0x00326: 0x00219 + "\x00\x01P\x00d\xc0\x02\x1a" + // 0x00054 0x00326: 0x0021A + "\x00\x01\xd0\x00d\xc0\x02\x1b" + // 0x00074 0x00326: 0x0021B + "\x00\x01 \x00a\x80\x02\x1e" + // 0x00048 0x0030C: 0x0021E + "\x00\x01\xa0\x00a\x80\x02\x1f" + // 0x00068 0x0030C: 0x0021F + "\x00\x01\x04\x00`\xe0\x02&" + // 0x00041 0x00307: 0x00226 + "\x00\x01\x84\x00`\xe0\x02'" + // 0x00061 0x00307: 0x00227 + "\x00\x01\x14\x00d\xe0\x02(" + // 0x00045 0x00327: 0x00228 + "\x00\x01\x94\x00d\xe0\x02)" + // 0x00065 0x00327: 0x00229 + "\x00\x03X\x00`\x80\x02*" + // 0x000D6 0x00304: 0x0022A + "\x00\x03\xd8\x00`\x80\x02+" + // 0x000F6 0x00304: 0x0022B + "\x00\x03T\x00`\x80\x02," + // 0x000D5 0x00304: 0x0022C + "\x00\x03\xd4\x00`\x80\x02-" + // 0x000F5 0x00304: 0x0022D + "\x00\x01<\x00`\xe0\x02." + // 0x0004F 0x00307: 0x0022E + "\x00\x01\xbc\x00`\xe0\x02/" + // 0x0006F 0x00307: 0x0022F + "\x00\b\xb8\x00`\x80\x020" + // 0x0022E 0x00304: 0x00230 + "\x00\b\xbc\x00`\x80\x021" + // 0x0022F 0x00304: 0x00231 + "\x00\x01d\x00`\x80\x022" + // 0x00059 0x00304: 0x00232 + "\x00\x01\xe4\x00`\x80\x023" + // 0x00079 0x00304: 0x00233 + "\x00\x02\xa0\x00` \x03\x85" + // 0x000A8 0x00301: 0x00385 + "\x00\x0eD\x00` \x03\x86" + // 0x00391 0x00301: 0x00386 + "\x00\x0eT\x00` \x03\x88" + // 0x00395 0x00301: 0x00388 + "\x00\x0e\\\x00` \x03\x89" + // 0x00397 0x00301: 0x00389 + "\x00\x0ed\x00` \x03\x8a" + // 0x00399 0x00301: 0x0038A + "\x00\x0e|\x00` \x03\x8c" + // 0x0039F 0x00301: 0x0038C + "\x00\x0e\x94\x00` \x03\x8e" + // 0x003A5 0x00301: 0x0038E + "\x00\x0e\xa4\x00` \x03\x8f" + // 0x003A9 0x00301: 0x0038F + "\x00\x0f(\x00` \x03\x90" + // 0x003CA 0x00301: 0x00390 + "\x00\x0ed\x00a\x00\x03\xaa" + // 0x00399 0x00308: 0x003AA + "\x00\x0e\x94\x00a\x00\x03\xab" + // 0x003A5 0x00308: 0x003AB + "\x00\x0e\xc4\x00` \x03\xac" + // 0x003B1 0x00301: 0x003AC + "\x00\x0e\xd4\x00` \x03\xad" + // 0x003B5 0x00301: 0x003AD + "\x00\x0e\xdc\x00` \x03\xae" + // 0x003B7 0x00301: 0x003AE + "\x00\x0e\xe4\x00` \x03\xaf" + // 0x003B9 0x00301: 0x003AF + "\x00\x0f,\x00` \x03\xb0" + // 0x003CB 0x00301: 0x003B0 + "\x00\x0e\xe4\x00a\x00\x03\xca" + // 0x003B9 0x00308: 0x003CA + "\x00\x0f\x14\x00a\x00\x03\xcb" + // 0x003C5 0x00308: 0x003CB + "\x00\x0e\xfc\x00` \x03\xcc" + // 0x003BF 0x00301: 0x003CC + "\x00\x0f\x14\x00` \x03\xcd" + // 0x003C5 0x00301: 0x003CD + "\x00\x0f$\x00` \x03\xce" + // 0x003C9 0x00301: 0x003CE + "\x00\x0fH\x00` \x03\xd3" + // 0x003D2 0x00301: 0x003D3 + "\x00\x0fH\x00a\x00\x03\xd4" + // 0x003D2 0x00308: 0x003D4 + "\x00\x10T\x00`\x00\x04\x00" + // 0x00415 0x00300: 0x00400 + "\x00\x10T\x00a\x00\x04\x01" + // 0x00415 0x00308: 0x00401 + "\x00\x10L\x00` \x04\x03" + // 0x00413 0x00301: 0x00403 + "\x00\x10\x18\x00a\x00\x04\a" + // 0x00406 0x00308: 0x00407 + "\x00\x10h\x00` \x04\f" + // 0x0041A 0x00301: 0x0040C + "\x00\x10`\x00`\x00\x04\r" + // 0x00418 0x00300: 0x0040D + "\x00\x10\x8c\x00`\xc0\x04\x0e" + // 0x00423 0x00306: 0x0040E + "\x00\x10`\x00`\xc0\x04\x19" + // 0x00418 0x00306: 0x00419 + "\x00\x10\xe0\x00`\xc0\x049" + // 0x00438 0x00306: 0x00439 + "\x00\x10\xd4\x00`\x00\x04P" + // 0x00435 0x00300: 0x00450 + "\x00\x10\xd4\x00a\x00\x04Q" + // 0x00435 0x00308: 0x00451 + "\x00\x10\xcc\x00` \x04S" + // 0x00433 0x00301: 0x00453 + "\x00\x11X\x00a\x00\x04W" + // 0x00456 0x00308: 0x00457 + "\x00\x10\xe8\x00` \x04\\" + // 0x0043A 0x00301: 0x0045C + "\x00\x10\xe0\x00`\x00\x04]" + // 0x00438 0x00300: 0x0045D + "\x00\x11\f\x00`\xc0\x04^" + // 0x00443 0x00306: 0x0045E + "\x00\x11\xd0\x00a\xe0\x04v" + // 0x00474 0x0030F: 0x00476 + "\x00\x11\xd4\x00a\xe0\x04w" + // 0x00475 0x0030F: 0x00477 + "\x00\x10X\x00`\xc0\x04\xc1" + // 0x00416 0x00306: 0x004C1 + "\x00\x10\xd8\x00`\xc0\x04\xc2" + // 0x00436 0x00306: 0x004C2 + "\x00\x10@\x00`\xc0\x04\xd0" + // 0x00410 0x00306: 0x004D0 + "\x00\x10\xc0\x00`\xc0\x04\xd1" + // 0x00430 0x00306: 0x004D1 + "\x00\x10@\x00a\x00\x04\xd2" + // 0x00410 0x00308: 0x004D2 + "\x00\x10\xc0\x00a\x00\x04\xd3" + // 0x00430 0x00308: 0x004D3 + "\x00\x10T\x00`\xc0\x04\xd6" + // 0x00415 0x00306: 0x004D6 + "\x00\x10\xd4\x00`\xc0\x04\xd7" + // 0x00435 0x00306: 0x004D7 + "\x00\x13`\x00a\x00\x04\xda" + // 0x004D8 0x00308: 0x004DA + "\x00\x13d\x00a\x00\x04\xdb" + // 0x004D9 0x00308: 0x004DB + "\x00\x10X\x00a\x00\x04\xdc" + // 0x00416 0x00308: 0x004DC + "\x00\x10\xd8\x00a\x00\x04\xdd" + // 0x00436 0x00308: 0x004DD + "\x00\x10\\\x00a\x00\x04\xde" + // 0x00417 0x00308: 0x004DE + "\x00\x10\xdc\x00a\x00\x04\xdf" + // 0x00437 0x00308: 0x004DF + "\x00\x10`\x00`\x80\x04\xe2" + // 0x00418 0x00304: 0x004E2 + "\x00\x10\xe0\x00`\x80\x04\xe3" + // 0x00438 0x00304: 0x004E3 + "\x00\x10`\x00a\x00\x04\xe4" + // 0x00418 0x00308: 0x004E4 + "\x00\x10\xe0\x00a\x00\x04\xe5" + // 0x00438 0x00308: 0x004E5 + "\x00\x10x\x00a\x00\x04\xe6" + // 0x0041E 0x00308: 0x004E6 + "\x00\x10\xf8\x00a\x00\x04\xe7" + // 0x0043E 0x00308: 0x004E7 + "\x00\x13\xa0\x00a\x00\x04\xea" + // 0x004E8 0x00308: 0x004EA + "\x00\x13\xa4\x00a\x00\x04\xeb" + // 0x004E9 0x00308: 0x004EB + "\x00\x10\xb4\x00a\x00\x04\xec" + // 0x0042D 0x00308: 0x004EC + "\x00\x114\x00a\x00\x04\xed" + // 0x0044D 0x00308: 0x004ED + "\x00\x10\x8c\x00`\x80\x04\xee" + // 0x00423 0x00304: 0x004EE + "\x00\x11\f\x00`\x80\x04\xef" + // 0x00443 0x00304: 0x004EF + "\x00\x10\x8c\x00a\x00\x04\xf0" + // 0x00423 0x00308: 0x004F0 + "\x00\x11\f\x00a\x00\x04\xf1" + // 0x00443 0x00308: 0x004F1 + "\x00\x10\x8c\x00a`\x04\xf2" + // 0x00423 0x0030B: 0x004F2 + "\x00\x11\f\x00a`\x04\xf3" + // 0x00443 0x0030B: 0x004F3 + "\x00\x10\x9c\x00a\x00\x04\xf4" + // 0x00427 0x00308: 0x004F4 + "\x00\x11\x1c\x00a\x00\x04\xf5" + // 0x00447 0x00308: 0x004F5 + "\x00\x10\xac\x00a\x00\x04\xf8" + // 0x0042B 0x00308: 0x004F8 + "\x00\x11,\x00a\x00\x04\xf9" + // 0x0044B 0x00308: 0x004F9 + "\x00\x18\x9c\x00\xca`\x06\"" + // 0x00627 0x00653: 0x00622 + "\x00\x18\x9c\x00ʀ\x06#" + // 0x00627 0x00654: 0x00623 + "\x00\x19 \x00ʀ\x06$" + // 0x00648 0x00654: 0x00624 + "\x00\x18\x9c\x00ʠ\x06%" + // 0x00627 0x00655: 0x00625 + "\x00\x19(\x00ʀ\x06&" + // 0x0064A 0x00654: 0x00626 + "\x00\x1bT\x00ʀ\x06\xc0" + // 0x006D5 0x00654: 0x006C0 + "\x00\x1b\x04\x00ʀ\x06\xc2" + // 0x006C1 0x00654: 0x006C2 + "\x00\x1bH\x00ʀ\x06\xd3" + // 0x006D2 0x00654: 0x006D3 + "\x00$\xa0\x01'\x80\t)" + // 0x00928 0x0093C: 0x00929 + "\x00$\xc0\x01'\x80\t1" + // 0x00930 0x0093C: 0x00931 + "\x00$\xcc\x01'\x80\t4" + // 0x00933 0x0093C: 0x00934 + "\x00'\x1c\x017\xc0\t\xcb" + // 0x009C7 0x009BE: 0x009CB + "\x00'\x1c\x01:\xe0\t\xcc" + // 0x009C7 0x009D7: 0x009CC + "\x00-\x1c\x01j\xc0\vH" + // 0x00B47 0x00B56: 0x00B48 + "\x00-\x1c\x01g\xc0\vK" + // 0x00B47 0x00B3E: 0x00B4B + "\x00-\x1c\x01j\xe0\vL" + // 0x00B47 0x00B57: 0x00B4C + "\x00.H\x01z\xe0\v\x94" + // 0x00B92 0x00BD7: 0x00B94 + "\x00/\x18\x01w\xc0\v\xca" + // 0x00BC6 0x00BBE: 0x00BCA + "\x00/\x1c\x01w\xc0\v\xcb" + // 0x00BC7 0x00BBE: 0x00BCB + "\x00/\x18\x01z\xe0\v\xcc" + // 0x00BC6 0x00BD7: 0x00BCC + "\x001\x18\x01\x8a\xc0\fH" + // 0x00C46 0x00C56: 0x00C48 + "\x002\xfc\x01\x9a\xa0\f\xc0" + // 0x00CBF 0x00CD5: 0x00CC0 + "\x003\x18\x01\x9a\xa0\f\xc7" + // 0x00CC6 0x00CD5: 0x00CC7 + "\x003\x18\x01\x9a\xc0\f\xc8" + // 0x00CC6 0x00CD6: 0x00CC8 + "\x003\x18\x01\x98@\f\xca" + // 0x00CC6 0x00CC2: 0x00CCA + "\x003(\x01\x9a\xa0\f\xcb" + // 0x00CCA 0x00CD5: 0x00CCB + "\x005\x18\x01\xa7\xc0\rJ" + // 0x00D46 0x00D3E: 0x00D4A + "\x005\x1c\x01\xa7\xc0\rK" + // 0x00D47 0x00D3E: 0x00D4B + "\x005\x18\x01\xaa\xe0\rL" + // 0x00D46 0x00D57: 0x00D4C + "\x007d\x01\xb9@\r\xda" + // 0x00DD9 0x00DCA: 0x00DDA + "\x007d\x01\xb9\xe0\r\xdc" + // 0x00DD9 0x00DCF: 0x00DDC + "\x007p\x01\xb9@\r\xdd" + // 0x00DDC 0x00DCA: 0x00DDD + "\x007d\x01\xbb\xe0\r\xde" + // 0x00DD9 0x00DDF: 0x00DDE + "\x00@\x94\x02\x05\xc0\x10&" + // 0x01025 0x0102E: 0x01026 + "\x00l\x14\x03f\xa0\x1b\x06" + // 0x01B05 0x01B35: 0x01B06 + "\x00l\x1c\x03f\xa0\x1b\b" + // 0x01B07 0x01B35: 0x01B08 + "\x00l$\x03f\xa0\x1b\n" + // 0x01B09 0x01B35: 0x01B0A + "\x00l,\x03f\xa0\x1b\f" + // 0x01B0B 0x01B35: 0x01B0C + "\x00l4\x03f\xa0\x1b\x0e" + // 0x01B0D 0x01B35: 0x01B0E + "\x00lD\x03f\xa0\x1b\x12" + // 0x01B11 0x01B35: 0x01B12 + "\x00l\xe8\x03f\xa0\x1b;" + // 0x01B3A 0x01B35: 0x01B3B + "\x00l\xf0\x03f\xa0\x1b=" + // 0x01B3C 0x01B35: 0x01B3D + "\x00l\xf8\x03f\xa0\x1b@" + // 0x01B3E 0x01B35: 0x01B40 + "\x00l\xfc\x03f\xa0\x1bA" + // 0x01B3F 0x01B35: 0x01B41 + "\x00m\b\x03f\xa0\x1bC" + // 0x01B42 0x01B35: 0x01B43 + "\x00\x01\x04\x00d\xa0\x1e\x00" + // 0x00041 0x00325: 0x01E00 + "\x00\x01\x84\x00d\xa0\x1e\x01" + // 0x00061 0x00325: 0x01E01 + "\x00\x01\b\x00`\xe0\x1e\x02" + // 0x00042 0x00307: 0x01E02 + "\x00\x01\x88\x00`\xe0\x1e\x03" + // 0x00062 0x00307: 0x01E03 + "\x00\x01\b\x00d`\x1e\x04" + // 0x00042 0x00323: 0x01E04 + "\x00\x01\x88\x00d`\x1e\x05" + // 0x00062 0x00323: 0x01E05 + "\x00\x01\b\x00f \x1e\x06" + // 0x00042 0x00331: 0x01E06 + "\x00\x01\x88\x00f \x1e\a" + // 0x00062 0x00331: 0x01E07 + "\x00\x03\x1c\x00` \x1e\b" + // 0x000C7 0x00301: 0x01E08 + "\x00\x03\x9c\x00` \x1e\t" + // 0x000E7 0x00301: 0x01E09 + "\x00\x01\x10\x00`\xe0\x1e\n" + // 0x00044 0x00307: 0x01E0A + "\x00\x01\x90\x00`\xe0\x1e\v" + // 0x00064 0x00307: 0x01E0B + "\x00\x01\x10\x00d`\x1e\f" + // 0x00044 0x00323: 0x01E0C + "\x00\x01\x90\x00d`\x1e\r" + // 0x00064 0x00323: 0x01E0D + "\x00\x01\x10\x00f \x1e\x0e" + // 0x00044 0x00331: 0x01E0E + "\x00\x01\x90\x00f \x1e\x0f" + // 0x00064 0x00331: 0x01E0F + "\x00\x01\x10\x00d\xe0\x1e\x10" + // 0x00044 0x00327: 0x01E10 + "\x00\x01\x90\x00d\xe0\x1e\x11" + // 0x00064 0x00327: 0x01E11 + "\x00\x01\x10\x00e\xa0\x1e\x12" + // 0x00044 0x0032D: 0x01E12 + "\x00\x01\x90\x00e\xa0\x1e\x13" + // 0x00064 0x0032D: 0x01E13 + "\x00\x04H\x00`\x00\x1e\x14" + // 0x00112 0x00300: 0x01E14 + "\x00\x04L\x00`\x00\x1e\x15" + // 0x00113 0x00300: 0x01E15 + "\x00\x04H\x00` \x1e\x16" + // 0x00112 0x00301: 0x01E16 + "\x00\x04L\x00` \x1e\x17" + // 0x00113 0x00301: 0x01E17 + "\x00\x01\x14\x00e\xa0\x1e\x18" + // 0x00045 0x0032D: 0x01E18 + "\x00\x01\x94\x00e\xa0\x1e\x19" + // 0x00065 0x0032D: 0x01E19 + "\x00\x01\x14\x00f\x00\x1e\x1a" + // 0x00045 0x00330: 0x01E1A + "\x00\x01\x94\x00f\x00\x1e\x1b" + // 0x00065 0x00330: 0x01E1B + "\x00\b\xa0\x00`\xc0\x1e\x1c" + // 0x00228 0x00306: 0x01E1C + "\x00\b\xa4\x00`\xc0\x1e\x1d" + // 0x00229 0x00306: 0x01E1D + "\x00\x01\x18\x00`\xe0\x1e\x1e" + // 0x00046 0x00307: 0x01E1E + "\x00\x01\x98\x00`\xe0\x1e\x1f" + // 0x00066 0x00307: 0x01E1F + "\x00\x01\x1c\x00`\x80\x1e " + // 0x00047 0x00304: 0x01E20 + "\x00\x01\x9c\x00`\x80\x1e!" + // 0x00067 0x00304: 0x01E21 + "\x00\x01 \x00`\xe0\x1e\"" + // 0x00048 0x00307: 0x01E22 + "\x00\x01\xa0\x00`\xe0\x1e#" + // 0x00068 0x00307: 0x01E23 + "\x00\x01 \x00d`\x1e$" + // 0x00048 0x00323: 0x01E24 + "\x00\x01\xa0\x00d`\x1e%" + // 0x00068 0x00323: 0x01E25 + "\x00\x01 \x00a\x00\x1e&" + // 0x00048 0x00308: 0x01E26 + "\x00\x01\xa0\x00a\x00\x1e'" + // 0x00068 0x00308: 0x01E27 + "\x00\x01 \x00d\xe0\x1e(" + // 0x00048 0x00327: 0x01E28 + "\x00\x01\xa0\x00d\xe0\x1e)" + // 0x00068 0x00327: 0x01E29 + "\x00\x01 \x00e\xc0\x1e*" + // 0x00048 0x0032E: 0x01E2A + "\x00\x01\xa0\x00e\xc0\x1e+" + // 0x00068 0x0032E: 0x01E2B + "\x00\x01$\x00f\x00\x1e," + // 0x00049 0x00330: 0x01E2C + "\x00\x01\xa4\x00f\x00\x1e-" + // 0x00069 0x00330: 0x01E2D + "\x00\x03<\x00` \x1e." + // 0x000CF 0x00301: 0x01E2E + "\x00\x03\xbc\x00` \x1e/" + // 0x000EF 0x00301: 0x01E2F + "\x00\x01,\x00` \x1e0" + // 0x0004B 0x00301: 0x01E30 + "\x00\x01\xac\x00` \x1e1" + // 0x0006B 0x00301: 0x01E31 + "\x00\x01,\x00d`\x1e2" + // 0x0004B 0x00323: 0x01E32 + "\x00\x01\xac\x00d`\x1e3" + // 0x0006B 0x00323: 0x01E33 + "\x00\x01,\x00f \x1e4" + // 0x0004B 0x00331: 0x01E34 + "\x00\x01\xac\x00f \x1e5" + // 0x0006B 0x00331: 0x01E35 + "\x00\x010\x00d`\x1e6" + // 0x0004C 0x00323: 0x01E36 + "\x00\x01\xb0\x00d`\x1e7" + // 0x0006C 0x00323: 0x01E37 + "\x00x\xd8\x00`\x80\x1e8" + // 0x01E36 0x00304: 0x01E38 + "\x00x\xdc\x00`\x80\x1e9" + // 0x01E37 0x00304: 0x01E39 + "\x00\x010\x00f \x1e:" + // 0x0004C 0x00331: 0x01E3A + "\x00\x01\xb0\x00f \x1e;" + // 0x0006C 0x00331: 0x01E3B + "\x00\x010\x00e\xa0\x1e<" + // 0x0004C 0x0032D: 0x01E3C + "\x00\x01\xb0\x00e\xa0\x1e=" + // 0x0006C 0x0032D: 0x01E3D + "\x00\x014\x00` \x1e>" + // 0x0004D 0x00301: 0x01E3E + "\x00\x01\xb4\x00` \x1e?" + // 0x0006D 0x00301: 0x01E3F + "\x00\x014\x00`\xe0\x1e@" + // 0x0004D 0x00307: 0x01E40 + "\x00\x01\xb4\x00`\xe0\x1eA" + // 0x0006D 0x00307: 0x01E41 + "\x00\x014\x00d`\x1eB" + // 0x0004D 0x00323: 0x01E42 + "\x00\x01\xb4\x00d`\x1eC" + // 0x0006D 0x00323: 0x01E43 + "\x00\x018\x00`\xe0\x1eD" + // 0x0004E 0x00307: 0x01E44 + "\x00\x01\xb8\x00`\xe0\x1eE" + // 0x0006E 0x00307: 0x01E45 + "\x00\x018\x00d`\x1eF" + // 0x0004E 0x00323: 0x01E46 + "\x00\x01\xb8\x00d`\x1eG" + // 0x0006E 0x00323: 0x01E47 + "\x00\x018\x00f \x1eH" + // 0x0004E 0x00331: 0x01E48 + "\x00\x01\xb8\x00f \x1eI" + // 0x0006E 0x00331: 0x01E49 + "\x00\x018\x00e\xa0\x1eJ" + // 0x0004E 0x0032D: 0x01E4A + "\x00\x01\xb8\x00e\xa0\x1eK" + // 0x0006E 0x0032D: 0x01E4B + "\x00\x03T\x00` \x1eL" + // 0x000D5 0x00301: 0x01E4C + "\x00\x03\xd4\x00` \x1eM" + // 0x000F5 0x00301: 0x01E4D + "\x00\x03T\x00a\x00\x1eN" + // 0x000D5 0x00308: 0x01E4E + "\x00\x03\xd4\x00a\x00\x1eO" + // 0x000F5 0x00308: 0x01E4F + "\x00\x050\x00`\x00\x1eP" + // 0x0014C 0x00300: 0x01E50 + "\x00\x054\x00`\x00\x1eQ" + // 0x0014D 0x00300: 0x01E51 + "\x00\x050\x00` \x1eR" + // 0x0014C 0x00301: 0x01E52 + "\x00\x054\x00` \x1eS" + // 0x0014D 0x00301: 0x01E53 + "\x00\x01@\x00` \x1eT" + // 0x00050 0x00301: 0x01E54 + "\x00\x01\xc0\x00` \x1eU" + // 0x00070 0x00301: 0x01E55 + "\x00\x01@\x00`\xe0\x1eV" + // 0x00050 0x00307: 0x01E56 + "\x00\x01\xc0\x00`\xe0\x1eW" + // 0x00070 0x00307: 0x01E57 + "\x00\x01H\x00`\xe0\x1eX" + // 0x00052 0x00307: 0x01E58 + "\x00\x01\xc8\x00`\xe0\x1eY" + // 0x00072 0x00307: 0x01E59 + "\x00\x01H\x00d`\x1eZ" + // 0x00052 0x00323: 0x01E5A + "\x00\x01\xc8\x00d`\x1e[" + // 0x00072 0x00323: 0x01E5B + "\x00yh\x00`\x80\x1e\\" + // 0x01E5A 0x00304: 0x01E5C + "\x00yl\x00`\x80\x1e]" + // 0x01E5B 0x00304: 0x01E5D + "\x00\x01H\x00f \x1e^" + // 0x00052 0x00331: 0x01E5E + "\x00\x01\xc8\x00f \x1e_" + // 0x00072 0x00331: 0x01E5F + "\x00\x01L\x00`\xe0\x1e`" + // 0x00053 0x00307: 0x01E60 + "\x00\x01\xcc\x00`\xe0\x1ea" + // 0x00073 0x00307: 0x01E61 + "\x00\x01L\x00d`\x1eb" + // 0x00053 0x00323: 0x01E62 + "\x00\x01\xcc\x00d`\x1ec" + // 0x00073 0x00323: 0x01E63 + "\x00\x05h\x00`\xe0\x1ed" + // 0x0015A 0x00307: 0x01E64 + "\x00\x05l\x00`\xe0\x1ee" + // 0x0015B 0x00307: 0x01E65 + "\x00\x05\x80\x00`\xe0\x1ef" + // 0x00160 0x00307: 0x01E66 + "\x00\x05\x84\x00`\xe0\x1eg" + // 0x00161 0x00307: 0x01E67 + "\x00y\x88\x00`\xe0\x1eh" + // 0x01E62 0x00307: 0x01E68 + "\x00y\x8c\x00`\xe0\x1ei" + // 0x01E63 0x00307: 0x01E69 + "\x00\x01P\x00`\xe0\x1ej" + // 0x00054 0x00307: 0x01E6A + "\x00\x01\xd0\x00`\xe0\x1ek" + // 0x00074 0x00307: 0x01E6B + "\x00\x01P\x00d`\x1el" + // 0x00054 0x00323: 0x01E6C + "\x00\x01\xd0\x00d`\x1em" + // 0x00074 0x00323: 0x01E6D + "\x00\x01P\x00f \x1en" + // 0x00054 0x00331: 0x01E6E + "\x00\x01\xd0\x00f \x1eo" + // 0x00074 0x00331: 0x01E6F + "\x00\x01P\x00e\xa0\x1ep" + // 0x00054 0x0032D: 0x01E70 + "\x00\x01\xd0\x00e\xa0\x1eq" + // 0x00074 0x0032D: 0x01E71 + "\x00\x01T\x00d\x80\x1er" + // 0x00055 0x00324: 0x01E72 + "\x00\x01\xd4\x00d\x80\x1es" + // 0x00075 0x00324: 0x01E73 + "\x00\x01T\x00f\x00\x1et" + // 0x00055 0x00330: 0x01E74 + "\x00\x01\xd4\x00f\x00\x1eu" + // 0x00075 0x00330: 0x01E75 + "\x00\x01T\x00e\xa0\x1ev" + // 0x00055 0x0032D: 0x01E76 + "\x00\x01\xd4\x00e\xa0\x1ew" + // 0x00075 0x0032D: 0x01E77 + "\x00\x05\xa0\x00` \x1ex" + // 0x00168 0x00301: 0x01E78 + "\x00\x05\xa4\x00` \x1ey" + // 0x00169 0x00301: 0x01E79 + "\x00\x05\xa8\x00a\x00\x1ez" + // 0x0016A 0x00308: 0x01E7A + "\x00\x05\xac\x00a\x00\x1e{" + // 0x0016B 0x00308: 0x01E7B + "\x00\x01X\x00``\x1e|" + // 0x00056 0x00303: 0x01E7C + "\x00\x01\xd8\x00``\x1e}" + // 0x00076 0x00303: 0x01E7D + "\x00\x01X\x00d`\x1e~" + // 0x00056 0x00323: 0x01E7E + "\x00\x01\xd8\x00d`\x1e\x7f" + // 0x00076 0x00323: 0x01E7F + "\x00\x01\\\x00`\x00\x1e\x80" + // 0x00057 0x00300: 0x01E80 + "\x00\x01\xdc\x00`\x00\x1e\x81" + // 0x00077 0x00300: 0x01E81 + "\x00\x01\\\x00` \x1e\x82" + // 0x00057 0x00301: 0x01E82 + "\x00\x01\xdc\x00` \x1e\x83" + // 0x00077 0x00301: 0x01E83 + "\x00\x01\\\x00a\x00\x1e\x84" + // 0x00057 0x00308: 0x01E84 + "\x00\x01\xdc\x00a\x00\x1e\x85" + // 0x00077 0x00308: 0x01E85 + "\x00\x01\\\x00`\xe0\x1e\x86" + // 0x00057 0x00307: 0x01E86 + "\x00\x01\xdc\x00`\xe0\x1e\x87" + // 0x00077 0x00307: 0x01E87 + "\x00\x01\\\x00d`\x1e\x88" + // 0x00057 0x00323: 0x01E88 + "\x00\x01\xdc\x00d`\x1e\x89" + // 0x00077 0x00323: 0x01E89 + "\x00\x01`\x00`\xe0\x1e\x8a" + // 0x00058 0x00307: 0x01E8A + "\x00\x01\xe0\x00`\xe0\x1e\x8b" + // 0x00078 0x00307: 0x01E8B + "\x00\x01`\x00a\x00\x1e\x8c" + // 0x00058 0x00308: 0x01E8C + "\x00\x01\xe0\x00a\x00\x1e\x8d" + // 0x00078 0x00308: 0x01E8D + "\x00\x01d\x00`\xe0\x1e\x8e" + // 0x00059 0x00307: 0x01E8E + "\x00\x01\xe4\x00`\xe0\x1e\x8f" + // 0x00079 0x00307: 0x01E8F + "\x00\x01h\x00`@\x1e\x90" + // 0x0005A 0x00302: 0x01E90 + "\x00\x01\xe8\x00`@\x1e\x91" + // 0x0007A 0x00302: 0x01E91 + "\x00\x01h\x00d`\x1e\x92" + // 0x0005A 0x00323: 0x01E92 + "\x00\x01\xe8\x00d`\x1e\x93" + // 0x0007A 0x00323: 0x01E93 + "\x00\x01h\x00f \x1e\x94" + // 0x0005A 0x00331: 0x01E94 + "\x00\x01\xe8\x00f \x1e\x95" + // 0x0007A 0x00331: 0x01E95 + "\x00\x01\xa0\x00f \x1e\x96" + // 0x00068 0x00331: 0x01E96 + "\x00\x01\xd0\x00a\x00\x1e\x97" + // 0x00074 0x00308: 0x01E97 + "\x00\x01\xdc\x00a@\x1e\x98" + // 0x00077 0x0030A: 0x01E98 + "\x00\x01\xe4\x00a@\x1e\x99" + // 0x00079 0x0030A: 0x01E99 + "\x00\x05\xfc\x00`\xe0\x1e\x9b" + // 0x0017F 0x00307: 0x01E9B + "\x00\x01\x04\x00d`\x1e\xa0" + // 0x00041 0x00323: 0x01EA0 + "\x00\x01\x84\x00d`\x1e\xa1" + // 0x00061 0x00323: 0x01EA1 + "\x00\x01\x04\x00a \x1e\xa2" + // 0x00041 0x00309: 0x01EA2 + "\x00\x01\x84\x00a \x1e\xa3" + // 0x00061 0x00309: 0x01EA3 + "\x00\x03\b\x00` \x1e\xa4" + // 0x000C2 0x00301: 0x01EA4 + "\x00\x03\x88\x00` \x1e\xa5" + // 0x000E2 0x00301: 0x01EA5 + "\x00\x03\b\x00`\x00\x1e\xa6" + // 0x000C2 0x00300: 0x01EA6 + "\x00\x03\x88\x00`\x00\x1e\xa7" + // 0x000E2 0x00300: 0x01EA7 + "\x00\x03\b\x00a \x1e\xa8" + // 0x000C2 0x00309: 0x01EA8 + "\x00\x03\x88\x00a \x1e\xa9" + // 0x000E2 0x00309: 0x01EA9 + "\x00\x03\b\x00``\x1e\xaa" + // 0x000C2 0x00303: 0x01EAA + "\x00\x03\x88\x00``\x1e\xab" + // 0x000E2 0x00303: 0x01EAB + "\x00z\x80\x00`@\x1e\xac" + // 0x01EA0 0x00302: 0x01EAC + "\x00z\x84\x00`@\x1e\xad" + // 0x01EA1 0x00302: 0x01EAD + "\x00\x04\b\x00` \x1e\xae" + // 0x00102 0x00301: 0x01EAE + "\x00\x04\f\x00` \x1e\xaf" + // 0x00103 0x00301: 0x01EAF + "\x00\x04\b\x00`\x00\x1e\xb0" + // 0x00102 0x00300: 0x01EB0 + "\x00\x04\f\x00`\x00\x1e\xb1" + // 0x00103 0x00300: 0x01EB1 + "\x00\x04\b\x00a \x1e\xb2" + // 0x00102 0x00309: 0x01EB2 + "\x00\x04\f\x00a \x1e\xb3" + // 0x00103 0x00309: 0x01EB3 + "\x00\x04\b\x00``\x1e\xb4" + // 0x00102 0x00303: 0x01EB4 + "\x00\x04\f\x00``\x1e\xb5" + // 0x00103 0x00303: 0x01EB5 + "\x00z\x80\x00`\xc0\x1e\xb6" + // 0x01EA0 0x00306: 0x01EB6 + "\x00z\x84\x00`\xc0\x1e\xb7" + // 0x01EA1 0x00306: 0x01EB7 + "\x00\x01\x14\x00d`\x1e\xb8" + // 0x00045 0x00323: 0x01EB8 + "\x00\x01\x94\x00d`\x1e\xb9" + // 0x00065 0x00323: 0x01EB9 + "\x00\x01\x14\x00a \x1e\xba" + // 0x00045 0x00309: 0x01EBA + "\x00\x01\x94\x00a \x1e\xbb" + // 0x00065 0x00309: 0x01EBB + "\x00\x01\x14\x00``\x1e\xbc" + // 0x00045 0x00303: 0x01EBC + "\x00\x01\x94\x00``\x1e\xbd" + // 0x00065 0x00303: 0x01EBD + "\x00\x03(\x00` \x1e\xbe" + // 0x000CA 0x00301: 0x01EBE + "\x00\x03\xa8\x00` \x1e\xbf" + // 0x000EA 0x00301: 0x01EBF + "\x00\x03(\x00`\x00\x1e\xc0" + // 0x000CA 0x00300: 0x01EC0 + "\x00\x03\xa8\x00`\x00\x1e\xc1" + // 0x000EA 0x00300: 0x01EC1 + "\x00\x03(\x00a \x1e\xc2" + // 0x000CA 0x00309: 0x01EC2 + "\x00\x03\xa8\x00a \x1e\xc3" + // 0x000EA 0x00309: 0x01EC3 + "\x00\x03(\x00``\x1e\xc4" + // 0x000CA 0x00303: 0x01EC4 + "\x00\x03\xa8\x00``\x1e\xc5" + // 0x000EA 0x00303: 0x01EC5 + "\x00z\xe0\x00`@\x1e\xc6" + // 0x01EB8 0x00302: 0x01EC6 + "\x00z\xe4\x00`@\x1e\xc7" + // 0x01EB9 0x00302: 0x01EC7 + "\x00\x01$\x00a \x1e\xc8" + // 0x00049 0x00309: 0x01EC8 + "\x00\x01\xa4\x00a \x1e\xc9" + // 0x00069 0x00309: 0x01EC9 + "\x00\x01$\x00d`\x1e\xca" + // 0x00049 0x00323: 0x01ECA + "\x00\x01\xa4\x00d`\x1e\xcb" + // 0x00069 0x00323: 0x01ECB + "\x00\x01<\x00d`\x1e\xcc" + // 0x0004F 0x00323: 0x01ECC + "\x00\x01\xbc\x00d`\x1e\xcd" + // 0x0006F 0x00323: 0x01ECD + "\x00\x01<\x00a \x1e\xce" + // 0x0004F 0x00309: 0x01ECE + "\x00\x01\xbc\x00a \x1e\xcf" + // 0x0006F 0x00309: 0x01ECF + "\x00\x03P\x00` \x1e\xd0" + // 0x000D4 0x00301: 0x01ED0 + "\x00\x03\xd0\x00` \x1e\xd1" + // 0x000F4 0x00301: 0x01ED1 + "\x00\x03P\x00`\x00\x1e\xd2" + // 0x000D4 0x00300: 0x01ED2 + "\x00\x03\xd0\x00`\x00\x1e\xd3" + // 0x000F4 0x00300: 0x01ED3 + "\x00\x03P\x00a \x1e\xd4" + // 0x000D4 0x00309: 0x01ED4 + "\x00\x03\xd0\x00a \x1e\xd5" + // 0x000F4 0x00309: 0x01ED5 + "\x00\x03P\x00``\x1e\xd6" + // 0x000D4 0x00303: 0x01ED6 + "\x00\x03\xd0\x00``\x1e\xd7" + // 0x000F4 0x00303: 0x01ED7 + "\x00{0\x00`@\x1e\xd8" + // 0x01ECC 0x00302: 0x01ED8 + "\x00{4\x00`@\x1e\xd9" + // 0x01ECD 0x00302: 0x01ED9 + "\x00\x06\x80\x00` \x1e\xda" + // 0x001A0 0x00301: 0x01EDA + "\x00\x06\x84\x00` \x1e\xdb" + // 0x001A1 0x00301: 0x01EDB + "\x00\x06\x80\x00`\x00\x1e\xdc" + // 0x001A0 0x00300: 0x01EDC + "\x00\x06\x84\x00`\x00\x1e\xdd" + // 0x001A1 0x00300: 0x01EDD + "\x00\x06\x80\x00a \x1e\xde" + // 0x001A0 0x00309: 0x01EDE + "\x00\x06\x84\x00a \x1e\xdf" + // 0x001A1 0x00309: 0x01EDF + "\x00\x06\x80\x00``\x1e\xe0" + // 0x001A0 0x00303: 0x01EE0 + "\x00\x06\x84\x00``\x1e\xe1" + // 0x001A1 0x00303: 0x01EE1 + "\x00\x06\x80\x00d`\x1e\xe2" + // 0x001A0 0x00323: 0x01EE2 + "\x00\x06\x84\x00d`\x1e\xe3" + // 0x001A1 0x00323: 0x01EE3 + "\x00\x01T\x00d`\x1e\xe4" + // 0x00055 0x00323: 0x01EE4 + "\x00\x01\xd4\x00d`\x1e\xe5" + // 0x00075 0x00323: 0x01EE5 + "\x00\x01T\x00a \x1e\xe6" + // 0x00055 0x00309: 0x01EE6 + "\x00\x01\xd4\x00a \x1e\xe7" + // 0x00075 0x00309: 0x01EE7 + "\x00\x06\xbc\x00` \x1e\xe8" + // 0x001AF 0x00301: 0x01EE8 + "\x00\x06\xc0\x00` \x1e\xe9" + // 0x001B0 0x00301: 0x01EE9 + "\x00\x06\xbc\x00`\x00\x1e\xea" + // 0x001AF 0x00300: 0x01EEA + "\x00\x06\xc0\x00`\x00\x1e\xeb" + // 0x001B0 0x00300: 0x01EEB + "\x00\x06\xbc\x00a \x1e\xec" + // 0x001AF 0x00309: 0x01EEC + "\x00\x06\xc0\x00a \x1e\xed" + // 0x001B0 0x00309: 0x01EED + "\x00\x06\xbc\x00``\x1e\xee" + // 0x001AF 0x00303: 0x01EEE + "\x00\x06\xc0\x00``\x1e\xef" + // 0x001B0 0x00303: 0x01EEF + "\x00\x06\xbc\x00d`\x1e\xf0" + // 0x001AF 0x00323: 0x01EF0 + "\x00\x06\xc0\x00d`\x1e\xf1" + // 0x001B0 0x00323: 0x01EF1 + "\x00\x01d\x00`\x00\x1e\xf2" + // 0x00059 0x00300: 0x01EF2 + "\x00\x01\xe4\x00`\x00\x1e\xf3" + // 0x00079 0x00300: 0x01EF3 + "\x00\x01d\x00d`\x1e\xf4" + // 0x00059 0x00323: 0x01EF4 + "\x00\x01\xe4\x00d`\x1e\xf5" + // 0x00079 0x00323: 0x01EF5 + "\x00\x01d\x00a \x1e\xf6" + // 0x00059 0x00309: 0x01EF6 + "\x00\x01\xe4\x00a \x1e\xf7" + // 0x00079 0x00309: 0x01EF7 + "\x00\x01d\x00``\x1e\xf8" + // 0x00059 0x00303: 0x01EF8 + "\x00\x01\xe4\x00``\x1e\xf9" + // 0x00079 0x00303: 0x01EF9 + "\x00\x0e\xc4\x00b`\x1f\x00" + // 0x003B1 0x00313: 0x01F00 + "\x00\x0e\xc4\x00b\x80\x1f\x01" + // 0x003B1 0x00314: 0x01F01 + "\x00|\x00\x00`\x00\x1f\x02" + // 0x01F00 0x00300: 0x01F02 + "\x00|\x04\x00`\x00\x1f\x03" + // 0x01F01 0x00300: 0x01F03 + "\x00|\x00\x00` \x1f\x04" + // 0x01F00 0x00301: 0x01F04 + "\x00|\x04\x00` \x1f\x05" + // 0x01F01 0x00301: 0x01F05 + "\x00|\x00\x00h@\x1f\x06" + // 0x01F00 0x00342: 0x01F06 + "\x00|\x04\x00h@\x1f\a" + // 0x01F01 0x00342: 0x01F07 + "\x00\x0eD\x00b`\x1f\b" + // 0x00391 0x00313: 0x01F08 + "\x00\x0eD\x00b\x80\x1f\t" + // 0x00391 0x00314: 0x01F09 + "\x00| \x00`\x00\x1f\n" + // 0x01F08 0x00300: 0x01F0A + "\x00|$\x00`\x00\x1f\v" + // 0x01F09 0x00300: 0x01F0B + "\x00| \x00` \x1f\f" + // 0x01F08 0x00301: 0x01F0C + "\x00|$\x00` \x1f\r" + // 0x01F09 0x00301: 0x01F0D + "\x00| \x00h@\x1f\x0e" + // 0x01F08 0x00342: 0x01F0E + "\x00|$\x00h@\x1f\x0f" + // 0x01F09 0x00342: 0x01F0F + "\x00\x0e\xd4\x00b`\x1f\x10" + // 0x003B5 0x00313: 0x01F10 + "\x00\x0e\xd4\x00b\x80\x1f\x11" + // 0x003B5 0x00314: 0x01F11 + "\x00|@\x00`\x00\x1f\x12" + // 0x01F10 0x00300: 0x01F12 + "\x00|D\x00`\x00\x1f\x13" + // 0x01F11 0x00300: 0x01F13 + "\x00|@\x00` \x1f\x14" + // 0x01F10 0x00301: 0x01F14 + "\x00|D\x00` \x1f\x15" + // 0x01F11 0x00301: 0x01F15 + "\x00\x0eT\x00b`\x1f\x18" + // 0x00395 0x00313: 0x01F18 + "\x00\x0eT\x00b\x80\x1f\x19" + // 0x00395 0x00314: 0x01F19 + "\x00|`\x00`\x00\x1f\x1a" + // 0x01F18 0x00300: 0x01F1A + "\x00|d\x00`\x00\x1f\x1b" + // 0x01F19 0x00300: 0x01F1B + "\x00|`\x00` \x1f\x1c" + // 0x01F18 0x00301: 0x01F1C + "\x00|d\x00` \x1f\x1d" + // 0x01F19 0x00301: 0x01F1D + "\x00\x0e\xdc\x00b`\x1f " + // 0x003B7 0x00313: 0x01F20 + "\x00\x0e\xdc\x00b\x80\x1f!" + // 0x003B7 0x00314: 0x01F21 + "\x00|\x80\x00`\x00\x1f\"" + // 0x01F20 0x00300: 0x01F22 + "\x00|\x84\x00`\x00\x1f#" + // 0x01F21 0x00300: 0x01F23 + "\x00|\x80\x00` \x1f$" + // 0x01F20 0x00301: 0x01F24 + "\x00|\x84\x00` \x1f%" + // 0x01F21 0x00301: 0x01F25 + "\x00|\x80\x00h@\x1f&" + // 0x01F20 0x00342: 0x01F26 + "\x00|\x84\x00h@\x1f'" + // 0x01F21 0x00342: 0x01F27 + "\x00\x0e\\\x00b`\x1f(" + // 0x00397 0x00313: 0x01F28 + "\x00\x0e\\\x00b\x80\x1f)" + // 0x00397 0x00314: 0x01F29 + "\x00|\xa0\x00`\x00\x1f*" + // 0x01F28 0x00300: 0x01F2A + "\x00|\xa4\x00`\x00\x1f+" + // 0x01F29 0x00300: 0x01F2B + "\x00|\xa0\x00` \x1f," + // 0x01F28 0x00301: 0x01F2C + "\x00|\xa4\x00` \x1f-" + // 0x01F29 0x00301: 0x01F2D + "\x00|\xa0\x00h@\x1f." + // 0x01F28 0x00342: 0x01F2E + "\x00|\xa4\x00h@\x1f/" + // 0x01F29 0x00342: 0x01F2F + "\x00\x0e\xe4\x00b`\x1f0" + // 0x003B9 0x00313: 0x01F30 + "\x00\x0e\xe4\x00b\x80\x1f1" + // 0x003B9 0x00314: 0x01F31 + "\x00|\xc0\x00`\x00\x1f2" + // 0x01F30 0x00300: 0x01F32 + "\x00|\xc4\x00`\x00\x1f3" + // 0x01F31 0x00300: 0x01F33 + "\x00|\xc0\x00` \x1f4" + // 0x01F30 0x00301: 0x01F34 + "\x00|\xc4\x00` \x1f5" + // 0x01F31 0x00301: 0x01F35 + "\x00|\xc0\x00h@\x1f6" + // 0x01F30 0x00342: 0x01F36 + "\x00|\xc4\x00h@\x1f7" + // 0x01F31 0x00342: 0x01F37 + "\x00\x0ed\x00b`\x1f8" + // 0x00399 0x00313: 0x01F38 + "\x00\x0ed\x00b\x80\x1f9" + // 0x00399 0x00314: 0x01F39 + "\x00|\xe0\x00`\x00\x1f:" + // 0x01F38 0x00300: 0x01F3A + "\x00|\xe4\x00`\x00\x1f;" + // 0x01F39 0x00300: 0x01F3B + "\x00|\xe0\x00` \x1f<" + // 0x01F38 0x00301: 0x01F3C + "\x00|\xe4\x00` \x1f=" + // 0x01F39 0x00301: 0x01F3D + "\x00|\xe0\x00h@\x1f>" + // 0x01F38 0x00342: 0x01F3E + "\x00|\xe4\x00h@\x1f?" + // 0x01F39 0x00342: 0x01F3F + "\x00\x0e\xfc\x00b`\x1f@" + // 0x003BF 0x00313: 0x01F40 + "\x00\x0e\xfc\x00b\x80\x1fA" + // 0x003BF 0x00314: 0x01F41 + "\x00}\x00\x00`\x00\x1fB" + // 0x01F40 0x00300: 0x01F42 + "\x00}\x04\x00`\x00\x1fC" + // 0x01F41 0x00300: 0x01F43 + "\x00}\x00\x00` \x1fD" + // 0x01F40 0x00301: 0x01F44 + "\x00}\x04\x00` \x1fE" + // 0x01F41 0x00301: 0x01F45 + "\x00\x0e|\x00b`\x1fH" + // 0x0039F 0x00313: 0x01F48 + "\x00\x0e|\x00b\x80\x1fI" + // 0x0039F 0x00314: 0x01F49 + "\x00} \x00`\x00\x1fJ" + // 0x01F48 0x00300: 0x01F4A + "\x00}$\x00`\x00\x1fK" + // 0x01F49 0x00300: 0x01F4B + "\x00} \x00` \x1fL" + // 0x01F48 0x00301: 0x01F4C + "\x00}$\x00` \x1fM" + // 0x01F49 0x00301: 0x01F4D + "\x00\x0f\x14\x00b`\x1fP" + // 0x003C5 0x00313: 0x01F50 + "\x00\x0f\x14\x00b\x80\x1fQ" + // 0x003C5 0x00314: 0x01F51 + "\x00}@\x00`\x00\x1fR" + // 0x01F50 0x00300: 0x01F52 + "\x00}D\x00`\x00\x1fS" + // 0x01F51 0x00300: 0x01F53 + "\x00}@\x00` \x1fT" + // 0x01F50 0x00301: 0x01F54 + "\x00}D\x00` \x1fU" + // 0x01F51 0x00301: 0x01F55 + "\x00}@\x00h@\x1fV" + // 0x01F50 0x00342: 0x01F56 + "\x00}D\x00h@\x1fW" + // 0x01F51 0x00342: 0x01F57 + "\x00\x0e\x94\x00b\x80\x1fY" + // 0x003A5 0x00314: 0x01F59 + "\x00}d\x00`\x00\x1f[" + // 0x01F59 0x00300: 0x01F5B + "\x00}d\x00` \x1f]" + // 0x01F59 0x00301: 0x01F5D + "\x00}d\x00h@\x1f_" + // 0x01F59 0x00342: 0x01F5F + "\x00\x0f$\x00b`\x1f`" + // 0x003C9 0x00313: 0x01F60 + "\x00\x0f$\x00b\x80\x1fa" + // 0x003C9 0x00314: 0x01F61 + "\x00}\x80\x00`\x00\x1fb" + // 0x01F60 0x00300: 0x01F62 + "\x00}\x84\x00`\x00\x1fc" + // 0x01F61 0x00300: 0x01F63 + "\x00}\x80\x00` \x1fd" + // 0x01F60 0x00301: 0x01F64 + "\x00}\x84\x00` \x1fe" + // 0x01F61 0x00301: 0x01F65 + "\x00}\x80\x00h@\x1ff" + // 0x01F60 0x00342: 0x01F66 + "\x00}\x84\x00h@\x1fg" + // 0x01F61 0x00342: 0x01F67 + "\x00\x0e\xa4\x00b`\x1fh" + // 0x003A9 0x00313: 0x01F68 + "\x00\x0e\xa4\x00b\x80\x1fi" + // 0x003A9 0x00314: 0x01F69 + "\x00}\xa0\x00`\x00\x1fj" + // 0x01F68 0x00300: 0x01F6A + "\x00}\xa4\x00`\x00\x1fk" + // 0x01F69 0x00300: 0x01F6B + "\x00}\xa0\x00` \x1fl" + // 0x01F68 0x00301: 0x01F6C + "\x00}\xa4\x00` \x1fm" + // 0x01F69 0x00301: 0x01F6D + "\x00}\xa0\x00h@\x1fn" + // 0x01F68 0x00342: 0x01F6E + "\x00}\xa4\x00h@\x1fo" + // 0x01F69 0x00342: 0x01F6F + "\x00\x0e\xc4\x00`\x00\x1fp" + // 0x003B1 0x00300: 0x01F70 + "\x00\x0e\xd4\x00`\x00\x1fr" + // 0x003B5 0x00300: 0x01F72 + "\x00\x0e\xdc\x00`\x00\x1ft" + // 0x003B7 0x00300: 0x01F74 + "\x00\x0e\xe4\x00`\x00\x1fv" + // 0x003B9 0x00300: 0x01F76 + "\x00\x0e\xfc\x00`\x00\x1fx" + // 0x003BF 0x00300: 0x01F78 + "\x00\x0f\x14\x00`\x00\x1fz" + // 0x003C5 0x00300: 0x01F7A + "\x00\x0f$\x00`\x00\x1f|" + // 0x003C9 0x00300: 0x01F7C + "\x00|\x00\x00h\xa0\x1f\x80" + // 0x01F00 0x00345: 0x01F80 + "\x00|\x04\x00h\xa0\x1f\x81" + // 0x01F01 0x00345: 0x01F81 + "\x00|\b\x00h\xa0\x1f\x82" + // 0x01F02 0x00345: 0x01F82 + "\x00|\f\x00h\xa0\x1f\x83" + // 0x01F03 0x00345: 0x01F83 + "\x00|\x10\x00h\xa0\x1f\x84" + // 0x01F04 0x00345: 0x01F84 + "\x00|\x14\x00h\xa0\x1f\x85" + // 0x01F05 0x00345: 0x01F85 + "\x00|\x18\x00h\xa0\x1f\x86" + // 0x01F06 0x00345: 0x01F86 + "\x00|\x1c\x00h\xa0\x1f\x87" + // 0x01F07 0x00345: 0x01F87 + "\x00| \x00h\xa0\x1f\x88" + // 0x01F08 0x00345: 0x01F88 + "\x00|$\x00h\xa0\x1f\x89" + // 0x01F09 0x00345: 0x01F89 + "\x00|(\x00h\xa0\x1f\x8a" + // 0x01F0A 0x00345: 0x01F8A + "\x00|,\x00h\xa0\x1f\x8b" + // 0x01F0B 0x00345: 0x01F8B + "\x00|0\x00h\xa0\x1f\x8c" + // 0x01F0C 0x00345: 0x01F8C + "\x00|4\x00h\xa0\x1f\x8d" + // 0x01F0D 0x00345: 0x01F8D + "\x00|8\x00h\xa0\x1f\x8e" + // 0x01F0E 0x00345: 0x01F8E + "\x00|<\x00h\xa0\x1f\x8f" + // 0x01F0F 0x00345: 0x01F8F + "\x00|\x80\x00h\xa0\x1f\x90" + // 0x01F20 0x00345: 0x01F90 + "\x00|\x84\x00h\xa0\x1f\x91" + // 0x01F21 0x00345: 0x01F91 + "\x00|\x88\x00h\xa0\x1f\x92" + // 0x01F22 0x00345: 0x01F92 + "\x00|\x8c\x00h\xa0\x1f\x93" + // 0x01F23 0x00345: 0x01F93 + "\x00|\x90\x00h\xa0\x1f\x94" + // 0x01F24 0x00345: 0x01F94 + "\x00|\x94\x00h\xa0\x1f\x95" + // 0x01F25 0x00345: 0x01F95 + "\x00|\x98\x00h\xa0\x1f\x96" + // 0x01F26 0x00345: 0x01F96 + "\x00|\x9c\x00h\xa0\x1f\x97" + // 0x01F27 0x00345: 0x01F97 + "\x00|\xa0\x00h\xa0\x1f\x98" + // 0x01F28 0x00345: 0x01F98 + "\x00|\xa4\x00h\xa0\x1f\x99" + // 0x01F29 0x00345: 0x01F99 + "\x00|\xa8\x00h\xa0\x1f\x9a" + // 0x01F2A 0x00345: 0x01F9A + "\x00|\xac\x00h\xa0\x1f\x9b" + // 0x01F2B 0x00345: 0x01F9B + "\x00|\xb0\x00h\xa0\x1f\x9c" + // 0x01F2C 0x00345: 0x01F9C + "\x00|\xb4\x00h\xa0\x1f\x9d" + // 0x01F2D 0x00345: 0x01F9D + "\x00|\xb8\x00h\xa0\x1f\x9e" + // 0x01F2E 0x00345: 0x01F9E + "\x00|\xbc\x00h\xa0\x1f\x9f" + // 0x01F2F 0x00345: 0x01F9F + "\x00}\x80\x00h\xa0\x1f\xa0" + // 0x01F60 0x00345: 0x01FA0 + "\x00}\x84\x00h\xa0\x1f\xa1" + // 0x01F61 0x00345: 0x01FA1 + "\x00}\x88\x00h\xa0\x1f\xa2" + // 0x01F62 0x00345: 0x01FA2 + "\x00}\x8c\x00h\xa0\x1f\xa3" + // 0x01F63 0x00345: 0x01FA3 + "\x00}\x90\x00h\xa0\x1f\xa4" + // 0x01F64 0x00345: 0x01FA4 + "\x00}\x94\x00h\xa0\x1f\xa5" + // 0x01F65 0x00345: 0x01FA5 + "\x00}\x98\x00h\xa0\x1f\xa6" + // 0x01F66 0x00345: 0x01FA6 + "\x00}\x9c\x00h\xa0\x1f\xa7" + // 0x01F67 0x00345: 0x01FA7 + "\x00}\xa0\x00h\xa0\x1f\xa8" + // 0x01F68 0x00345: 0x01FA8 + "\x00}\xa4\x00h\xa0\x1f\xa9" + // 0x01F69 0x00345: 0x01FA9 + "\x00}\xa8\x00h\xa0\x1f\xaa" + // 0x01F6A 0x00345: 0x01FAA + "\x00}\xac\x00h\xa0\x1f\xab" + // 0x01F6B 0x00345: 0x01FAB + "\x00}\xb0\x00h\xa0\x1f\xac" + // 0x01F6C 0x00345: 0x01FAC + "\x00}\xb4\x00h\xa0\x1f\xad" + // 0x01F6D 0x00345: 0x01FAD + "\x00}\xb8\x00h\xa0\x1f\xae" + // 0x01F6E 0x00345: 0x01FAE + "\x00}\xbc\x00h\xa0\x1f\xaf" + // 0x01F6F 0x00345: 0x01FAF + "\x00\x0e\xc4\x00`\xc0\x1f\xb0" + // 0x003B1 0x00306: 0x01FB0 + "\x00\x0e\xc4\x00`\x80\x1f\xb1" + // 0x003B1 0x00304: 0x01FB1 + "\x00}\xc0\x00h\xa0\x1f\xb2" + // 0x01F70 0x00345: 0x01FB2 + "\x00\x0e\xc4\x00h\xa0\x1f\xb3" + // 0x003B1 0x00345: 0x01FB3 + "\x00\x0e\xb0\x00h\xa0\x1f\xb4" + // 0x003AC 0x00345: 0x01FB4 + "\x00\x0e\xc4\x00h@\x1f\xb6" + // 0x003B1 0x00342: 0x01FB6 + "\x00~\xd8\x00h\xa0\x1f\xb7" + // 0x01FB6 0x00345: 0x01FB7 + "\x00\x0eD\x00`\xc0\x1f\xb8" + // 0x00391 0x00306: 0x01FB8 + "\x00\x0eD\x00`\x80\x1f\xb9" + // 0x00391 0x00304: 0x01FB9 + "\x00\x0eD\x00`\x00\x1f\xba" + // 0x00391 0x00300: 0x01FBA + "\x00\x0eD\x00h\xa0\x1f\xbc" + // 0x00391 0x00345: 0x01FBC + "\x00\x02\xa0\x00h@\x1f\xc1" + // 0x000A8 0x00342: 0x01FC1 + "\x00}\xd0\x00h\xa0\x1f\xc2" + // 0x01F74 0x00345: 0x01FC2 + "\x00\x0e\xdc\x00h\xa0\x1f\xc3" + // 0x003B7 0x00345: 0x01FC3 + "\x00\x0e\xb8\x00h\xa0\x1f\xc4" + // 0x003AE 0x00345: 0x01FC4 + "\x00\x0e\xdc\x00h@\x1f\xc6" + // 0x003B7 0x00342: 0x01FC6 + "\x00\x7f\x18\x00h\xa0\x1f\xc7" + // 0x01FC6 0x00345: 0x01FC7 + "\x00\x0eT\x00`\x00\x1f\xc8" + // 0x00395 0x00300: 0x01FC8 + "\x00\x0e\\\x00`\x00\x1f\xca" + // 0x00397 0x00300: 0x01FCA + "\x00\x0e\\\x00h\xa0\x1f\xcc" + // 0x00397 0x00345: 0x01FCC + "\x00~\xfc\x00`\x00\x1f\xcd" + // 0x01FBF 0x00300: 0x01FCD + "\x00~\xfc\x00` \x1f\xce" + // 0x01FBF 0x00301: 0x01FCE + "\x00~\xfc\x00h@\x1f\xcf" + // 0x01FBF 0x00342: 0x01FCF + "\x00\x0e\xe4\x00`\xc0\x1f\xd0" + // 0x003B9 0x00306: 0x01FD0 + "\x00\x0e\xe4\x00`\x80\x1f\xd1" + // 0x003B9 0x00304: 0x01FD1 + "\x00\x0f(\x00`\x00\x1f\xd2" + // 0x003CA 0x00300: 0x01FD2 + "\x00\x0e\xe4\x00h@\x1f\xd6" + // 0x003B9 0x00342: 0x01FD6 + "\x00\x0f(\x00h@\x1f\xd7" + // 0x003CA 0x00342: 0x01FD7 + "\x00\x0ed\x00`\xc0\x1f\xd8" + // 0x00399 0x00306: 0x01FD8 + "\x00\x0ed\x00`\x80\x1f\xd9" + // 0x00399 0x00304: 0x01FD9 + "\x00\x0ed\x00`\x00\x1f\xda" + // 0x00399 0x00300: 0x01FDA + "\x00\x7f\xf8\x00`\x00\x1f\xdd" + // 0x01FFE 0x00300: 0x01FDD + "\x00\x7f\xf8\x00` \x1f\xde" + // 0x01FFE 0x00301: 0x01FDE + "\x00\x7f\xf8\x00h@\x1f\xdf" + // 0x01FFE 0x00342: 0x01FDF + "\x00\x0f\x14\x00`\xc0\x1f\xe0" + // 0x003C5 0x00306: 0x01FE0 + "\x00\x0f\x14\x00`\x80\x1f\xe1" + // 0x003C5 0x00304: 0x01FE1 + "\x00\x0f,\x00`\x00\x1f\xe2" + // 0x003CB 0x00300: 0x01FE2 + "\x00\x0f\x04\x00b`\x1f\xe4" + // 0x003C1 0x00313: 0x01FE4 + "\x00\x0f\x04\x00b\x80\x1f\xe5" + // 0x003C1 0x00314: 0x01FE5 + "\x00\x0f\x14\x00h@\x1f\xe6" + // 0x003C5 0x00342: 0x01FE6 + "\x00\x0f,\x00h@\x1f\xe7" + // 0x003CB 0x00342: 0x01FE7 + "\x00\x0e\x94\x00`\xc0\x1f\xe8" + // 0x003A5 0x00306: 0x01FE8 + "\x00\x0e\x94\x00`\x80\x1f\xe9" + // 0x003A5 0x00304: 0x01FE9 + "\x00\x0e\x94\x00`\x00\x1f\xea" + // 0x003A5 0x00300: 0x01FEA + "\x00\x0e\x84\x00b\x80\x1f\xec" + // 0x003A1 0x00314: 0x01FEC + "\x00\x02\xa0\x00`\x00\x1f\xed" + // 0x000A8 0x00300: 0x01FED + "\x00}\xf0\x00h\xa0\x1f\xf2" + // 0x01F7C 0x00345: 0x01FF2 + "\x00\x0f$\x00h\xa0\x1f\xf3" + // 0x003C9 0x00345: 0x01FF3 + "\x00\x0f8\x00h\xa0\x1f\xf4" + // 0x003CE 0x00345: 0x01FF4 + "\x00\x0f$\x00h@\x1f\xf6" + // 0x003C9 0x00342: 0x01FF6 + "\x00\x7f\xd8\x00h\xa0\x1f\xf7" + // 0x01FF6 0x00345: 0x01FF7 + "\x00\x0e|\x00`\x00\x1f\xf8" + // 0x0039F 0x00300: 0x01FF8 + "\x00\x0e\xa4\x00`\x00\x1f\xfa" + // 0x003A9 0x00300: 0x01FFA + "\x00\x0e\xa4\x00h\xa0\x1f\xfc" + // 0x003A9 0x00345: 0x01FFC + "\x00\x86@\x00g\x00!\x9a" + // 0x02190 0x00338: 0x0219A + "\x00\x86H\x00g\x00!\x9b" + // 0x02192 0x00338: 0x0219B + "\x00\x86P\x00g\x00!\xae" + // 0x02194 0x00338: 0x021AE + "\x00\x87@\x00g\x00!\xcd" + // 0x021D0 0x00338: 0x021CD + "\x00\x87P\x00g\x00!\xce" + // 0x021D4 0x00338: 0x021CE + "\x00\x87H\x00g\x00!\xcf" + // 0x021D2 0x00338: 0x021CF + "\x00\x88\f\x00g\x00\"\x04" + // 0x02203 0x00338: 0x02204 + "\x00\x88 \x00g\x00\"\t" + // 0x02208 0x00338: 0x02209 + "\x00\x88,\x00g\x00\"\f" + // 0x0220B 0x00338: 0x0220C + "\x00\x88\x8c\x00g\x00\"$" + // 0x02223 0x00338: 0x02224 + "\x00\x88\x94\x00g\x00\"&" + // 0x02225 0x00338: 0x02226 + "\x00\x88\xf0\x00g\x00\"A" + // 0x0223C 0x00338: 0x02241 + "\x00\x89\f\x00g\x00\"D" + // 0x02243 0x00338: 0x02244 + "\x00\x89\x14\x00g\x00\"G" + // 0x02245 0x00338: 0x02247 + "\x00\x89 \x00g\x00\"I" + // 0x02248 0x00338: 0x02249 + "\x00\x00\xf4\x00g\x00\"`" + // 0x0003D 0x00338: 0x02260 + "\x00\x89\x84\x00g\x00\"b" + // 0x02261 0x00338: 0x02262 + "\x00\x894\x00g\x00\"m" + // 0x0224D 0x00338: 0x0226D + "\x00\x00\xf0\x00g\x00\"n" + // 0x0003C 0x00338: 0x0226E + "\x00\x00\xf8\x00g\x00\"o" + // 0x0003E 0x00338: 0x0226F + "\x00\x89\x90\x00g\x00\"p" + // 0x02264 0x00338: 0x02270 + "\x00\x89\x94\x00g\x00\"q" + // 0x02265 0x00338: 0x02271 + "\x00\x89\xc8\x00g\x00\"t" + // 0x02272 0x00338: 0x02274 + "\x00\x89\xcc\x00g\x00\"u" + // 0x02273 0x00338: 0x02275 + "\x00\x89\xd8\x00g\x00\"x" + // 0x02276 0x00338: 0x02278 + "\x00\x89\xdc\x00g\x00\"y" + // 0x02277 0x00338: 0x02279 + "\x00\x89\xe8\x00g\x00\"\x80" + // 0x0227A 0x00338: 0x02280 + "\x00\x89\xec\x00g\x00\"\x81" + // 0x0227B 0x00338: 0x02281 + "\x00\x8a\b\x00g\x00\"\x84" + // 0x02282 0x00338: 0x02284 + "\x00\x8a\f\x00g\x00\"\x85" + // 0x02283 0x00338: 0x02285 + "\x00\x8a\x18\x00g\x00\"\x88" + // 0x02286 0x00338: 0x02288 + "\x00\x8a\x1c\x00g\x00\"\x89" + // 0x02287 0x00338: 0x02289 + "\x00\x8a\x88\x00g\x00\"\xac" + // 0x022A2 0x00338: 0x022AC + "\x00\x8a\xa0\x00g\x00\"\xad" + // 0x022A8 0x00338: 0x022AD + "\x00\x8a\xa4\x00g\x00\"\xae" + // 0x022A9 0x00338: 0x022AE + "\x00\x8a\xac\x00g\x00\"\xaf" + // 0x022AB 0x00338: 0x022AF + "\x00\x89\xf0\x00g\x00\"\xe0" + // 0x0227C 0x00338: 0x022E0 + "\x00\x89\xf4\x00g\x00\"\xe1" + // 0x0227D 0x00338: 0x022E1 + "\x00\x8aD\x00g\x00\"\xe2" + // 0x02291 0x00338: 0x022E2 + "\x00\x8aH\x00g\x00\"\xe3" + // 0x02292 0x00338: 0x022E3 + "\x00\x8a\xc8\x00g\x00\"\xea" + // 0x022B2 0x00338: 0x022EA + "\x00\x8a\xcc\x00g\x00\"\xeb" + // 0x022B3 0x00338: 0x022EB + "\x00\x8a\xd0\x00g\x00\"\xec" + // 0x022B4 0x00338: 0x022EC + "\x00\x8a\xd4\x00g\x00\"\xed" + // 0x022B5 0x00338: 0x022ED + "\x00\xc1,\x06\x13 0L" + // 0x0304B 0x03099: 0x0304C + "\x00\xc14\x06\x13 0N" + // 0x0304D 0x03099: 0x0304E + "\x00\xc1<\x06\x13 0P" + // 0x0304F 0x03099: 0x03050 + "\x00\xc1D\x06\x13 0R" + // 0x03051 0x03099: 0x03052 + "\x00\xc1L\x06\x13 0T" + // 0x03053 0x03099: 0x03054 + "\x00\xc1T\x06\x13 0V" + // 0x03055 0x03099: 0x03056 + "\x00\xc1\\\x06\x13 0X" + // 0x03057 0x03099: 0x03058 + "\x00\xc1d\x06\x13 0Z" + // 0x03059 0x03099: 0x0305A + "\x00\xc1l\x06\x13 0\\" + // 0x0305B 0x03099: 0x0305C + "\x00\xc1t\x06\x13 0^" + // 0x0305D 0x03099: 0x0305E + "\x00\xc1|\x06\x13 0`" + // 0x0305F 0x03099: 0x03060 + "\x00\xc1\x84\x06\x13 0b" + // 0x03061 0x03099: 0x03062 + "\x00\xc1\x90\x06\x13 0e" + // 0x03064 0x03099: 0x03065 + "\x00\xc1\x98\x06\x13 0g" + // 0x03066 0x03099: 0x03067 + "\x00\xc1\xa0\x06\x13 0i" + // 0x03068 0x03099: 0x03069 + "\x00\xc1\xbc\x06\x13 0p" + // 0x0306F 0x03099: 0x03070 + "\x00\xc1\xbc\x06\x13@0q" + // 0x0306F 0x0309A: 0x03071 + "\x00\xc1\xc8\x06\x13 0s" + // 0x03072 0x03099: 0x03073 + "\x00\xc1\xc8\x06\x13@0t" + // 0x03072 0x0309A: 0x03074 + "\x00\xc1\xd4\x06\x13 0v" + // 0x03075 0x03099: 0x03076 + "\x00\xc1\xd4\x06\x13@0w" + // 0x03075 0x0309A: 0x03077 + "\x00\xc1\xe0\x06\x13 0y" + // 0x03078 0x03099: 0x03079 + "\x00\xc1\xe0\x06\x13@0z" + // 0x03078 0x0309A: 0x0307A + "\x00\xc1\xec\x06\x13 0|" + // 0x0307B 0x03099: 0x0307C + "\x00\xc1\xec\x06\x13@0}" + // 0x0307B 0x0309A: 0x0307D + "\x00\xc1\x18\x06\x13 0\x94" + // 0x03046 0x03099: 0x03094 + "\x00\xc2t\x06\x13 0\x9e" + // 0x0309D 0x03099: 0x0309E + "\x00¬\x06\x13 0\xac" + // 0x030AB 0x03099: 0x030AC + "\x00´\x06\x13 0\xae" + // 0x030AD 0x03099: 0x030AE + "\x00¼\x06\x13 0\xb0" + // 0x030AF 0x03099: 0x030B0 + "\x00\xc2\xc4\x06\x13 0\xb2" + // 0x030B1 0x03099: 0x030B2 + "\x00\xc2\xcc\x06\x13 0\xb4" + // 0x030B3 0x03099: 0x030B4 + "\x00\xc2\xd4\x06\x13 0\xb6" + // 0x030B5 0x03099: 0x030B6 + "\x00\xc2\xdc\x06\x13 0\xb8" + // 0x030B7 0x03099: 0x030B8 + "\x00\xc2\xe4\x06\x13 0\xba" + // 0x030B9 0x03099: 0x030BA + "\x00\xc2\xec\x06\x13 0\xbc" + // 0x030BB 0x03099: 0x030BC + "\x00\xc2\xf4\x06\x13 0\xbe" + // 0x030BD 0x03099: 0x030BE + "\x00\xc2\xfc\x06\x13 0\xc0" + // 0x030BF 0x03099: 0x030C0 + "\x00\xc3\x04\x06\x13 0\xc2" + // 0x030C1 0x03099: 0x030C2 + "\x00\xc3\x10\x06\x13 0\xc5" + // 0x030C4 0x03099: 0x030C5 + "\x00\xc3\x18\x06\x13 0\xc7" + // 0x030C6 0x03099: 0x030C7 + "\x00\xc3 \x06\x13 0\xc9" + // 0x030C8 0x03099: 0x030C9 + "\x00\xc3<\x06\x13 0\xd0" + // 0x030CF 0x03099: 0x030D0 + "\x00\xc3<\x06\x13@0\xd1" + // 0x030CF 0x0309A: 0x030D1 + "\x00\xc3H\x06\x13 0\xd3" + // 0x030D2 0x03099: 0x030D3 + "\x00\xc3H\x06\x13@0\xd4" + // 0x030D2 0x0309A: 0x030D4 + "\x00\xc3T\x06\x13 0\xd6" + // 0x030D5 0x03099: 0x030D6 + "\x00\xc3T\x06\x13@0\xd7" + // 0x030D5 0x0309A: 0x030D7 + "\x00\xc3`\x06\x13 0\xd9" + // 0x030D8 0x03099: 0x030D9 + "\x00\xc3`\x06\x13@0\xda" + // 0x030D8 0x0309A: 0x030DA + "\x00\xc3l\x06\x13 0\xdc" + // 0x030DB 0x03099: 0x030DC + "\x00\xc3l\x06\x13@0\xdd" + // 0x030DB 0x0309A: 0x030DD + "\x00\u0098\x06\x13 0\xf4" + // 0x030A6 0x03099: 0x030F4 + "\x00ü\x06\x13 0\xf7" + // 0x030EF 0x03099: 0x030F7 + "\x00\xc3\xc0\x06\x13 0\xf8" + // 0x030F0 0x03099: 0x030F8 + "\x00\xc3\xc4\x06\x13 0\xf9" + // 0x030F1 0x03099: 0x030F9 + "\x00\xc3\xc8\x06\x13 0\xfa" + // 0x030F2 0x03099: 0x030FA + "\x00\xc3\xf4\x06\x13 0\xfe" + // 0x030FD 0x03099: 0x030FE + "\x04\x17H\x00`\xe1\x05\xc9" + // 0x105D2 0x00307: 0x105C9 + "\x04\x17h\x00`\xe1\x05\xe4" + // 0x105DA 0x00307: 0x105E4 + "\x04Bd\"\x17A\x10\x9a" + // 0x11099 0x110BA: 0x1109A + "\x04Bl\"\x17A\x10\x9c" + // 0x1109B 0x110BA: 0x1109C + "\x04B\x94\"\x17A\x10\xab" + // 0x110A5 0x110BA: 0x110AB + "\x04D\xc4\"$\xe1\x11." + // 0x11131 0x11127: 0x1112E + "\x04D\xc8\"$\xe1\x11/" + // 0x11132 0x11127: 0x1112F + "\x04M\x1c\"g\xc1\x13K" + // 0x11347 0x1133E: 0x1134B + "\x04M\x1c\"j\xe1\x13L" + // 0x11347 0x11357: 0x1134C + "\x04N\b\"y!\x13\x83" + // 0x11382 0x113C9: 0x11383 + "\x04N\x10\"wa\x13\x85" + // 0x11384 0x113BB: 0x11385 + "\x04N,\"xA\x13\x8e" + // 0x1138B 0x113C2: 0x1138E + "\x04N@\"y!\x13\x91" + // 0x11390 0x113C9: 0x11391 + "\x04O\b\"xA\x13\xc5" + // 0x113C2 0x113C2: 0x113C5 + "\x04O\b\"w\x01\x13\xc7" + // 0x113C2 0x113B8: 0x113C7 + "\x04O\b\"y!\x13\xc8" + // 0x113C2 0x113C9: 0x113C8 + "\x04R\xe4\"\x97A\x14\xbb" + // 0x114B9 0x114BA: 0x114BB + "\x04R\xe4\"\x96\x01\x14\xbc" + // 0x114B9 0x114B0: 0x114BC + "\x04R\xe4\"\x97\xa1\x14\xbe" + // 0x114B9 0x114BD: 0x114BE + "\x04V\xe0\"\xb5\xe1\x15\xba" + // 0x115B8 0x115AF: 0x115BA + "\x04V\xe4\"\xb5\xe1\x15\xbb" + // 0x115B9 0x115AF: 0x115BB + "\x04d\xd4#&\x01\x198" + // 0x11935 0x11930: 0x11938 + "\x05\x84x,#\xc1a!" + // 0x1611E 0x1611E: 0x16121 + "\x05\x84x,%!a\"" + // 0x1611E 0x16129: 0x16122 + "\x05\x84x,#\xe1a#" + // 0x1611E 0x1611F: 0x16123 + "\x05\x84\xa4,#\xe1a$" + // 0x16129 0x1611F: 0x16124 + "\x05\x84x,$\x01a%" + // 0x1611E 0x16120: 0x16125 + "\x05\x84\x84,#\xe1a&" + // 0x16121 0x1611F: 0x16126 + "\x05\x84\x88,#\xe1a'" + // 0x16122 0x1611F: 0x16127 + "\x05\x84\x84,$\x01a(" + // 0x16121 0x16120: 0x16128 + "\x05\xb5\x9c-\xac\xe1mh" + // 0x16D67 0x16D67: 0x16D68 + "\x05\xb5\x8c-\xac\xe1mi" + // 0x16D63 0x16D67: 0x16D69 + "\x05\xb5\xa4-\xac\xe1mj" + // 0x16D69 0x16D67: 0x16D6A "" // Total size of tables: 57KB (58086 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/transform.go b/vendor/golang.org/x/text/unicode/norm/transform.go index a1d366ae..583230d4 100644 --- a/vendor/golang.org/x/text/unicode/norm/transform.go +++ b/vendor/golang.org/x/text/unicode/norm/transform.go @@ -33,7 +33,7 @@ func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) return nDst + n, nSrc + n, err } - if err == nil && n < len(src) && !atEOF { + if err == nil && n < len(src) { err = transform.ErrShortSrc } return n, n, err @@ -67,6 +67,7 @@ func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) nSrc = end // Next quickSpan. + var err error end = rb.nsrc eof := atEOF if n := nSrc + len(dst) - nDst; n < end { @@ -79,7 +80,7 @@ func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) nSrc += n nDst += n if ok { - if err == nil && n < rb.nsrc && !atEOF { + if err == nil && nSrc < rb.nsrc { err = transform.ErrShortSrc } return nDst, nSrc, err diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go index 239b10c4..1c482252 100644 --- a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go +++ b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go @@ -10,6 +10,7 @@ import ( "go/token" "iter" "reflect" + "strings" "golang.org/x/tools/go/ast/edge" ) @@ -110,6 +111,46 @@ func (c Cursor) String() string { return reflect.TypeOf(c.Node()).String() } +// GoString returns a string describing the cursor's path from the +// root, if any. +func (c Cursor) GoString() string { + if !c.Valid() { + return "(invalid)" + } + if c.index < 0 { + return "(root)" + } + // e.g "File.Decls[1].(*ast.GenDecl).Specs[0].(*ast.TypeSpec)" + // + // In hindsight even the File node should have reported a + // virtual ParentEdge of (Root_Files, i) where i is the index + // among the files passed to NewInspector. Then the path would + // read "(root).Files[i]", etc; but we missed the boat. + var buf strings.Builder + buf.WriteString("File") + var visit func(Cursor) + visit = func(c Cursor) { + ek, idx := c.ParentEdge() + if ek == edge.Invalid { + return // File + } + visit(c.Parent()) + fmt.Fprintf(&buf, ".%s", ek.FieldName()) + if idx >= 0 { + fmt.Fprintf(&buf, "[%d]", idx) + } + ftype := ek.FieldType() + if idx >= 0 { + ftype = ftype.Elem() // []T -> T + } + if ftype.Kind() == reflect.Interface { + fmt.Fprintf(&buf, ".(%T)", c.Node()) + } + } + visit(c) + return buf.String() +} + // indices return the [start, end) half-open interval of event indices. func (c Cursor) indices() (int32, int32) { if c.index < 0 { diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go index c546b1b6..06747a9d 100644 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ b/vendor/golang.org/x/tools/go/packages/visit.go @@ -5,11 +5,11 @@ package packages import ( - "cmp" "fmt" "iter" "os" - "slices" + + "golang.org/x/tools/internal/moremaps" ) // Visit visits all the packages in the import graph whose roots are @@ -40,7 +40,7 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { seen[pkg] = true if pre == nil || pre(pkg) { - for _, imp := range sorted(pkg.Imports) { // for determinism + for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism visit(imp) } } @@ -88,7 +88,7 @@ func Postorder(pkgs []*Package) iter.Seq[*Package] { visit = func(pkg *Package) bool { if !seen[pkg] { seen[pkg] = true - for _, imp := range sorted(pkg.Imports) { // for determinism + for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism if !visit(imp) { return false } @@ -106,28 +106,3 @@ func Postorder(pkgs []*Package) iter.Seq[*Package] { } } } - -// -- copied from golang.org.x/tools/gopls/internal/util/moremaps -- - -// sorted returns an iterator over the entries of m in key order. -func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] { - // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted. - return func(yield func(K, V) bool) { - keys := keySlice(m) - slices.Sort(keys) - for _, k := range keys { - if !yield(k, m[k]) { - break - } - } - } -} - -// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)). -func keySlice[M ~map[K]V, K comparable, V any](m M) []K { - r := make([]K, 0, len(m)) - for k := range m { - r = append(r, k) - } - return r -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/callee.go b/vendor/golang.org/x/tools/go/types/typeutil/callee.go deleted file mode 100644 index 3d24a8c6..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/callee.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeutil - -import ( - "go/ast" - "go/types" - _ "unsafe" // for linkname -) - -// Callee returns the named target of a function call, if any: -// a function, method, builtin, or variable. -// It returns nil for a T(x) conversion. -// -// Functions and methods may potentially have type parameters. -// -// Note: for calls of instantiated functions and methods, Callee returns -// the corresponding generic function or method on the generic type. -func Callee(info *types.Info, call *ast.CallExpr) types.Object { - obj := info.Uses[usedIdent(info, call.Fun)] - if obj == nil { - return nil - } - if _, ok := obj.(*types.TypeName); ok { - return nil - } - return obj -} - -// StaticCallee returns the target (function or method) of a static function -// call, if any. It returns nil for calls to builtins. -// -// Note: for calls of instantiated functions and methods, StaticCallee returns -// the corresponding generic function or method on the generic type. -func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { - obj := info.Uses[usedIdent(info, call.Fun)] - fn, _ := obj.(*types.Func) - if fn == nil || interfaceMethod(fn) { - return nil - } - return fn -} - -// usedIdent is the implementation of [internal/typesinternal.UsedIdent]. -// It returns the identifier associated with e. -// See typesinternal.UsedIdent for a fuller description. -// This function should live in typesinternal, but cannot because it would -// create an import cycle. -// -//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent -func usedIdent(info *types.Info, e ast.Expr) *ast.Ident { - if info.Types == nil || info.Uses == nil { - panic("one of info.Types or info.Uses is nil; both must be populated") - } - // Look through type instantiation if necessary. - switch d := ast.Unparen(e).(type) { - case *ast.IndexExpr: - if info.Types[d.Index].IsType() { - e = d.X - } - case *ast.IndexListExpr: - e = d.X - } - - switch e := ast.Unparen(e).(type) { - // info.Uses always has the object we want, even for selector expressions. - // We don't need info.Selections. - // See go/types/recording.go:recordSelection. - case *ast.Ident: - return e - case *ast.SelectorExpr: - return e.Sel - } - return nil -} - -// interfaceMethod reports whether its argument is a method of an interface. -// This function should live in typesinternal, but cannot because it would create an import cycle. -// -//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod -func interfaceMethod(f *types.Func) bool { - recv := f.Signature().Recv() - return recv != nil && types.IsInterface(recv.Type()) -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/imports.go b/vendor/golang.org/x/tools/go/types/typeutil/imports.go deleted file mode 100644 index b81ce0c3..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/imports.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 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 typeutil - -import "go/types" - -// Dependencies returns all dependencies of the specified packages. -// -// Dependent packages appear in topological order: if package P imports -// package Q, Q appears earlier than P in the result. -// The algorithm follows import statements in the order they -// appear in the source code, so the result is a total order. -func Dependencies(pkgs ...*types.Package) []*types.Package { - var result []*types.Package - seen := make(map[*types.Package]bool) - var visit func(pkgs []*types.Package) - visit = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !seen[p] { - seen[p] = true - visit(p.Imports()) - result = append(result, p) - } - } - } - visit(pkgs) - return result -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go deleted file mode 100644 index 36624572..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/map.go +++ /dev/null @@ -1,459 +0,0 @@ -// Copyright 2014 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 typeutil defines various utilities for types, such as [Map], -// a hash table that maps [types.Type] to any value. -package typeutil - -import ( - "bytes" - "fmt" - "go/types" - "hash/maphash" - - "golang.org/x/tools/internal/typeparams" -) - -// Map is a hash-table-based mapping from types (types.Type) to -// arbitrary values. The concrete types that implement -// the Type interface are pointers. Since they are not canonicalized, -// == cannot be used to check for equivalence, and thus we cannot -// simply use a Go map. -// -// Just as with map[K]V, a nil *Map is a valid empty map. -// -// Read-only map operations ([Map.At], [Map.Len], and so on) may -// safely be called concurrently. -// -// TODO(adonovan): deprecate in favor of https://go.dev/issues/69420 -// and 69559, if the latter proposals for a generic hash-map type and -// a types.Hash function are accepted. -type Map struct { - table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused - length int // number of map entries -} - -// entry is an entry (key/value association) in a hash bucket. -type entry struct { - key types.Type - value any -} - -// SetHasher has no effect. -// -// It is a relic of an optimization that is no longer profitable. Do -// not use [Hasher], [MakeHasher], or [SetHasher] in new code. -func (m *Map) SetHasher(Hasher) {} - -// Delete removes the entry with the given key, if any. -// It returns true if the entry was found. -func (m *Map) Delete(key types.Type) bool { - if m != nil && m.table != nil { - hash := hash(key) - bucket := m.table[hash] - for i, e := range bucket { - if e.key != nil && types.Identical(key, e.key) { - // We can't compact the bucket as it - // would disturb iterators. - bucket[i] = entry{} - m.length-- - return true - } - } - } - return false -} - -// At returns the map entry for the given key. -// The result is nil if the entry is not present. -func (m *Map) At(key types.Type) any { - if m != nil && m.table != nil { - for _, e := range m.table[hash(key)] { - if e.key != nil && types.Identical(key, e.key) { - return e.value - } - } - } - return nil -} - -// Set sets the map entry for key to val, -// and returns the previous entry, if any. -func (m *Map) Set(key types.Type, value any) (prev any) { - if m.table != nil { - hash := hash(key) - bucket := m.table[hash] - var hole *entry - for i, e := range bucket { - if e.key == nil { - hole = &bucket[i] - } else if types.Identical(key, e.key) { - prev = e.value - bucket[i].value = value - return - } - } - - if hole != nil { - *hole = entry{key, value} // overwrite deleted entry - } else { - m.table[hash] = append(bucket, entry{key, value}) - } - } else { - hash := hash(key) - m.table = map[uint32][]entry{hash: {entry{key, value}}} - } - - m.length++ - return -} - -// Len returns the number of map entries. -func (m *Map) Len() int { - if m != nil { - return m.length - } - return 0 -} - -// Iterate calls function f on each entry in the map in unspecified order. -// -// If f should mutate the map, Iterate provides the same guarantees as -// Go maps: if f deletes a map entry that Iterate has not yet reached, -// f will not be invoked for it, but if f inserts a map entry that -// Iterate has not yet reached, whether or not f will be invoked for -// it is unspecified. -func (m *Map) Iterate(f func(key types.Type, value any)) { - if m != nil { - for _, bucket := range m.table { - for _, e := range bucket { - if e.key != nil { - f(e.key, e.value) - } - } - } - } -} - -// Keys returns a new slice containing the set of map keys. -// The order is unspecified. -func (m *Map) Keys() []types.Type { - keys := make([]types.Type, 0, m.Len()) - m.Iterate(func(key types.Type, _ any) { - keys = append(keys, key) - }) - return keys -} - -func (m *Map) toString(values bool) string { - if m == nil { - return "{}" - } - var buf bytes.Buffer - fmt.Fprint(&buf, "{") - sep := "" - m.Iterate(func(key types.Type, value any) { - fmt.Fprint(&buf, sep) - sep = ", " - fmt.Fprint(&buf, key) - if values { - fmt.Fprintf(&buf, ": %q", value) - } - }) - fmt.Fprint(&buf, "}") - return buf.String() -} - -// String returns a string representation of the map's entries. -// Values are printed using fmt.Sprintf("%v", v). -// Order is unspecified. -func (m *Map) String() string { - return m.toString(true) -} - -// KeysString returns a string representation of the map's key set. -// Order is unspecified. -func (m *Map) KeysString() string { - return m.toString(false) -} - -// -- Hasher -- - -// hash returns the hash of type t. -// TODO(adonovan): replace by types.Hash when Go proposal #69420 is accepted. -func hash(t types.Type) uint32 { - return theHasher.Hash(t) -} - -// A Hasher provides a [Hasher.Hash] method to map a type to its hash value. -// Hashers are stateless, and all are equivalent. -type Hasher struct{} - -var theHasher Hasher - -// MakeHasher returns Hasher{}. -// Hashers are stateless; all are equivalent. -func MakeHasher() Hasher { return theHasher } - -// Hash computes a hash value for the given type t such that -// Identical(t, t') => Hash(t) == Hash(t'). -func (h Hasher) Hash(t types.Type) uint32 { - return hasher{inGenericSig: false}.hash(t) -} - -// hasher holds the state of a single Hash traversal: whether we are -// inside the signature of a generic function; this is used to -// optimize [hasher.hashTypeParam]. -type hasher struct{ inGenericSig bool } - -// hashString computes the Fowler–Noll–Vo hash of s. -func hashString(s string) uint32 { - var h uint32 - for i := 0; i < len(s); i++ { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -// hash computes the hash of t. -func (h hasher) hash(t types.Type) uint32 { - // See Identical for rationale. - switch t := t.(type) { - case *types.Basic: - return uint32(t.Kind()) - - case *types.Alias: - return h.hash(types.Unalias(t)) - - case *types.Array: - return 9043 + 2*uint32(t.Len()) + 3*h.hash(t.Elem()) - - case *types.Slice: - return 9049 + 2*h.hash(t.Elem()) - - case *types.Struct: - var hash uint32 = 9059 - for i, n := 0, t.NumFields(); i < n; i++ { - f := t.Field(i) - if f.Anonymous() { - hash += 8861 - } - hash += hashString(t.Tag(i)) - hash += hashString(f.Name()) // (ignore f.Pkg) - hash += h.hash(f.Type()) - } - return hash - - case *types.Pointer: - return 9067 + 2*h.hash(t.Elem()) - - case *types.Signature: - var hash uint32 = 9091 - if t.Variadic() { - hash *= 8863 - } - - tparams := t.TypeParams() - if n := tparams.Len(); n > 0 { - h.inGenericSig = true // affects constraints, params, and results - - for i := range n { - tparam := tparams.At(i) - hash += 7 * h.hash(tparam.Constraint()) - } - } - - return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) - - case *types.Union: - return h.hashUnion(t) - - case *types.Interface: - // Interfaces are identical if they have the same set of methods, with - // identical names and types, and they have the same set of type - // restrictions. See go/types.identical for more details. - var hash uint32 = 9103 - - // Hash methods. - for i, n := 0, t.NumMethods(); i < n; i++ { - // Method order is not significant. - // Ignore m.Pkg(). - m := t.Method(i) - // Use shallow hash on method signature to - // avoid anonymous interface cycles. - hash += 3*hashString(m.Name()) + 5*h.shallowHash(m.Type()) - } - - // Hash type restrictions. - terms, err := typeparams.InterfaceTermSet(t) - // if err != nil t has invalid type restrictions. - if err == nil { - hash += h.hashTermSet(terms) - } - - return hash - - case *types.Map: - return 9109 + 2*h.hash(t.Key()) + 3*h.hash(t.Elem()) - - case *types.Chan: - return 9127 + 2*uint32(t.Dir()) + 3*h.hash(t.Elem()) - - case *types.Named: - hash := h.hashTypeName(t.Obj()) - targs := t.TypeArgs() - for targ := range targs.Types() { - hash += 2 * h.hash(targ) - } - return hash - - case *types.TypeParam: - return h.hashTypeParam(t) - - case *types.Tuple: - return h.hashTuple(t) - } - - panic(fmt.Sprintf("%T: %v", t, t)) -} - -func (h hasher) hashTuple(tuple *types.Tuple) uint32 { - // See go/types.identicalTypes for rationale. - n := tuple.Len() - hash := 9137 + 2*uint32(n) - for i := range n { - hash += 3 * h.hash(tuple.At(i).Type()) - } - return hash -} - -func (h hasher) hashUnion(t *types.Union) uint32 { - // Hash type restrictions. - terms, err := typeparams.UnionTermSet(t) - // if err != nil t has invalid type restrictions. Fall back on a non-zero - // hash. - if err != nil { - return 9151 - } - return h.hashTermSet(terms) -} - -func (h hasher) hashTermSet(terms []*types.Term) uint32 { - hash := 9157 + 2*uint32(len(terms)) - for _, term := range terms { - // term order is not significant. - termHash := h.hash(term.Type()) - if term.Tilde() { - termHash *= 9161 - } - hash += 3 * termHash - } - return hash -} - -// hashTypeParam returns the hash of a type parameter. -func (h hasher) hashTypeParam(t *types.TypeParam) uint32 { - // Within the signature of a generic function, TypeParams are - // identical if they have the same index and constraint, so we - // hash them based on index. - // - // When we are outside a generic function, free TypeParams are - // identical iff they are the same object, so we can use a - // more discriminating hash consistent with object identity. - // This optimization saves [Map] about 4% when hashing all the - // types.Info.Types in the forward closure of net/http. - if !h.inGenericSig { - // Optimization: outside a generic function signature, - // use a more discrimating hash consistent with object identity. - return h.hashTypeName(t.Obj()) - } - return 9173 + 3*uint32(t.Index()) -} - -var theSeed = maphash.MakeSeed() - -// hashTypeName hashes the pointer of tname. -func (hasher) hashTypeName(tname *types.TypeName) uint32 { - // Since types.Identical uses == to compare TypeNames, - // the Hash function uses maphash.Comparable. - hash := maphash.Comparable(theSeed, tname) - return uint32(hash ^ (hash >> 32)) -} - -// shallowHash computes a hash of t without looking at any of its -// element Types, to avoid potential anonymous cycles in the types of -// interface methods. -// -// When an unnamed non-empty interface type appears anywhere among the -// arguments or results of an interface method, there is a potential -// for endless recursion. Consider: -// -// type X interface { m() []*interface { X } } -// -// The problem is that the Methods of the interface in m's result type -// include m itself; there is no mention of the named type X that -// might help us break the cycle. -// (See comment in go/types.identical, case *Interface, for more.) -func (h hasher) shallowHash(t types.Type) uint32 { - // t is the type of an interface method (Signature), - // its params or results (Tuples), or their immediate - // elements (mostly Slice, Pointer, Basic, Named), - // so there's no need to optimize anything else. - switch t := t.(type) { - case *types.Alias: - return h.shallowHash(types.Unalias(t)) - - case *types.Signature: - var hash uint32 = 604171 - if t.Variadic() { - hash *= 971767 - } - // The Signature/Tuple recursion is always finite - // and invariably shallow. - return hash + 1062599*h.shallowHash(t.Params()) + 1282529*h.shallowHash(t.Results()) - - case *types.Tuple: - n := t.Len() - hash := 9137 + 2*uint32(n) - for i := range n { - hash += 53471161 * h.shallowHash(t.At(i).Type()) - } - return hash - - case *types.Basic: - return 45212177 * uint32(t.Kind()) - - case *types.Array: - return 1524181 + 2*uint32(t.Len()) - - case *types.Slice: - return 2690201 - - case *types.Struct: - return 3326489 - - case *types.Pointer: - return 4393139 - - case *types.Union: - return 562448657 - - case *types.Interface: - return 2124679 // no recursion here - - case *types.Map: - return 9109 - - case *types.Chan: - return 9127 - - case *types.Named: - return h.hashTypeName(t.Obj()) - - case *types.TypeParam: - return h.hashTypeParam(t) - } - panic(fmt.Sprintf("shallowHash: %T: %v", t, t)) -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go deleted file mode 100644 index f7666028..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2014 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. - -// This file implements a cache of method sets. - -package typeutil - -import ( - "go/types" - "sync" -) - -// A MethodSetCache records the method set of each type T for which -// MethodSet(T) is called so that repeat queries are fast. -// The zero value is a ready-to-use cache instance. -type MethodSetCache struct { - mu sync.Mutex - named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N - others map[types.Type]*types.MethodSet // all other types -} - -// MethodSet returns the method set of type T. It is thread-safe. -// -// If cache is nil, this function is equivalent to types.NewMethodSet(T). -// Utility functions can thus expose an optional *MethodSetCache -// parameter to clients that care about performance. -func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { - if cache == nil { - return types.NewMethodSet(T) - } - cache.mu.Lock() - defer cache.mu.Unlock() - - switch T := types.Unalias(T).(type) { - case *types.Named: - return cache.lookupNamed(T).value - - case *types.Pointer: - if N, ok := types.Unalias(T.Elem()).(*types.Named); ok { - return cache.lookupNamed(N).pointer - } - } - - // all other types - // (The map uses pointer equivalence, not type identity.) - mset := cache.others[T] - if mset == nil { - mset = types.NewMethodSet(T) - if cache.others == nil { - cache.others = make(map[types.Type]*types.MethodSet) - } - cache.others[T] = mset - } - return mset -} - -func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { - if cache.named == nil { - cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) - } - // Avoid recomputing mset(*T) for each distinct Pointer - // instance whose underlying type is a named type. - msets, ok := cache.named[named] - if !ok { - msets.value = types.NewMethodSet(named) - msets.pointer = types.NewMethodSet(types.NewPointer(named)) - cache.named[named] = msets - } - return msets -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/ui.go b/vendor/golang.org/x/tools/go/types/typeutil/ui.go deleted file mode 100644 index 9dda6a25..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/ui.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 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 typeutil - -// This file defines utilities for user interfaces that display types. - -import ( - "go/types" -) - -// IntuitiveMethodSet returns the intuitive method set of a type T, -// which is the set of methods you can call on an addressable value of -// that type. -// -// The result always contains MethodSet(T), and is exactly MethodSet(T) -// for interface types and for pointer-to-concrete types. -// For all other concrete types T, the result additionally -// contains each method belonging to *T if there is no identically -// named method on T itself. -// -// This corresponds to user intuition about method sets; -// this function is intended only for user interfaces. -// -// The order of the result is as for types.MethodSet(T). -func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { - isPointerToConcrete := func(T types.Type) bool { - ptr, ok := types.Unalias(T).(*types.Pointer) - return ok && !types.IsInterface(ptr.Elem()) - } - - var result []*types.Selection - mset := msets.MethodSet(T) - if types.IsInterface(T) || isPointerToConcrete(T) { - for i, n := 0, mset.Len(); i < n; i++ { - result = append(result, mset.At(i)) - } - } else { - // T is some other concrete type. - // Report methods of T and *T, preferring those of T. - pmset := msets.MethodSet(types.NewPointer(T)) - for i, n := 0, pmset.Len(); i < n; i++ { - meth := pmset.At(i) - if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { - meth = m - } - result = append(result, meth) - } - - } - return result -} diff --git a/vendor/golang.org/x/tools/internal/moremaps/maps.go b/vendor/golang.org/x/tools/internal/moremaps/maps.go new file mode 100644 index 00000000..a1bae078 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/moremaps/maps.go @@ -0,0 +1,116 @@ +// Copyright 2023 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 moremaps contains more functions for working with maps. +package moremaps + +import ( + "cmp" + "iter" + "maps" + "slices" +) + +// Arbitrary returns an arbitrary (key, value) entry from the map and ok is true, if +// the map is not empty. Otherwise, it returns zero values for K and V, and false. +func Arbitrary[K comparable, V any](m map[K]V) (_ K, _ V, ok bool) { + for k, v := range m { + return k, v, true + } + return +} + +// Group returns a new non-nil map containing the elements of s grouped by the +// keys returned from the key func. +func Group[K comparable, V any](s []V, key func(V) K) map[K][]V { + m := make(map[K][]V) + for _, v := range s { + k := key(v) + m[k] = append(m[k], v) + } + return m +} + +// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)). +func KeySlice[M ~map[K]V, K comparable, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + return r +} + +// ValueSlice returns the values of the map M, like slices.Collect(maps.Values(m)). +func ValueSlice[M ~map[K]V, K comparable, V any](m M) []V { + r := make([]V, 0, len(m)) + for _, v := range m { + r = append(r, v) + } + return r +} + +// SameKeys reports whether x and y have equal sets of keys. +func SameKeys[K comparable, V1, V2 any](x map[K]V1, y map[K]V2) bool { + ignoreValues := func(V1, V2) bool { return true } + return maps.EqualFunc(x, y, ignoreValues) +} + +// Sorted returns an iterator over the entries of m in key order. +func Sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] { + // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted. + return func(yield func(K, V) bool) { + keys := KeySlice(m) + slices.Sort(keys) + for _, k := range keys { + if !yield(k, m[k]) { + break + } + } + } +} + +// SortedFunc returns an iterator over the entries of m in the key order determined by cmp. +func SortedFunc[M ~map[K]V, K comparable, V any](m M, cmp func(x, y K) int) iter.Seq2[K, V] { + // TODO(adonovan): use maps.SortedFunc if proposal #68598 is accepted. + return func(yield func(K, V) bool) { + keys := KeySlice(m) + slices.SortFunc(keys, cmp) + for _, k := range keys { + if !yield(k, m[k]) { + break + } + } + } +} + +// Delete is like delete(m, k) but reports whether deletion occurred. +func Delete[M ~map[K]V, K comparable, V any](m M, k K) bool { + pre := len(m) + delete(m, k) + return pre != len(m) +} + +// Entry is a key-value pair obtained from a map. +type Entry[K comparable, V any] struct { + Key K + Value V +} + +// Entries returns a new unordered array of the entries of a map. +func Entries[M ~map[K]V, K comparable, V any](m M) []Entry[K, V] { + entries := make([]Entry[K, V], 0, len(m)) + for k, v := range m { + entries = append(entries, Entry[K, V]{k, v}) + } + return entries +} + +// FromEntries returns a new map into which the entries have been inserted in order. +func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V { + m := make(map[K]V, len(entries)) + for _, e := range entries { + m[e.Key] = e.Value + } + return m +} diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go deleted file mode 100644 index cdae2b8e..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/common.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2021 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 typeparams contains common utilities for writing tools that -// interact with generic Go code, as introduced with Go 1.18. It -// supplements the standard library APIs. Notably, the StructuralTerms -// API computes a minimal representation of the structural -// restrictions on a type parameter. -// -// An external version of these APIs is available in the -// golang.org/x/exp/typeparams module. -package typeparams - -import ( - "go/ast" - "go/token" - "go/types" -) - -// UnpackIndexExpr extracts data from AST nodes that represent index -// expressions. -// -// For an ast.IndexExpr, the resulting indices slice will contain exactly one -// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable -// number of index expressions. -// -// For nodes that don't represent index expressions, the first return value of -// UnpackIndexExpr will be nil. -func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { - switch e := n.(type) { - case *ast.IndexExpr: - return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack - case *ast.IndexListExpr: - return e.X, e.Lbrack, e.Indices, e.Rbrack - } - return nil, token.NoPos, nil, token.NoPos -} - -// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on -// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 -// will panic. -func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { - switch len(indices) { - case 0: - panic("empty indices") - case 1: - return &ast.IndexExpr{ - X: x, - Lbrack: lbrack, - Index: indices[0], - Rbrack: rbrack, - } - default: - return &ast.IndexListExpr{ - X: x, - Lbrack: lbrack, - Indices: indices, - Rbrack: rbrack, - } - } -} - -// IsTypeParam reports whether t is a type parameter (or an alias of one). -func IsTypeParam(t types.Type) bool { - _, ok := types.Unalias(t).(*types.TypeParam) - return ok -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go deleted file mode 100644 index 2e05de46..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go +++ /dev/null @@ -1,157 +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 typeparams - -import ( - "fmt" - "go/types" -) - -// CoreType returns the core type of T or nil if T does not have a core type. -// -// As of Go1.25, the notion of a core type has been removed from the language spec. -// See https://go.dev/blog/coretypes for more details. -// TODO(mkalil): We should eventually consider removing all uses of CoreType. -func CoreType(T types.Type) types.Type { - U := T.Underlying() - if _, ok := U.(*types.Interface); !ok { - return U // for non-interface types, - } - - terms, err := NormalTerms(U) - if len(terms) == 0 || err != nil { - // len(terms) -> empty type set of interface. - // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. - return nil // no core type. - } - - U = terms[0].Type().Underlying() - var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) - for identical = 1; identical < len(terms); identical++ { - if !types.Identical(U, terms[identical].Type().Underlying()) { - break - } - } - - if identical == len(terms) { - // From the deprecated core types spec: - // "There is a single type U which is the underlying type of all types in the type set of T" - return U - } - ch, ok := U.(*types.Chan) - if !ok { - return nil // no core type as identical < len(terms) and U is not a channel. - } - // From the deprecated core types spec: - // "the type chan E if T contains only bidirectional channels, or the type chan<- E or - // <-chan E depending on the direction of the directional channels present." - for chans := identical; chans < len(terms); chans++ { - curr, ok := terms[chans].Type().Underlying().(*types.Chan) - if !ok { - return nil - } - if !types.Identical(ch.Elem(), curr.Elem()) { - return nil // channel elements are not identical. - } - if ch.Dir() == types.SendRecv { - // ch is bidirectional. We can safely always use curr's direction. - ch = curr - } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { - // ch and curr are not bidirectional and not the same direction. - return nil - } - } - return ch -} - -// NormalTerms returns a slice of terms representing the normalized structural -// type restrictions of a type, if any. -// -// For all types other than *types.TypeParam, *types.Interface, and -// *types.Union, this is just a single term with Tilde() == false and -// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see -// below. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration type -// T[P interface{~int; m()}] int the structural restriction of the type -// parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// NormalTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, NormalTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the type is -// invalid, exceeds complexity bounds, or has an empty type set. In the latter -// case, NormalTerms returns ErrEmptyTypeSet. -// -// NormalTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func NormalTerms(T types.Type) ([]*types.Term, error) { - // typeSetOf(T) == typeSetOf(Unalias(T)) - typ := types.Unalias(T) - if named, ok := typ.(*types.Named); ok { - typ = named.Underlying() - } - switch typ := typ.(type) { - case *types.TypeParam: - return StructuralTerms(typ) - case *types.Union: - return UnionTermSet(typ) - case *types.Interface: - return InterfaceTermSet(typ) - default: - return []*types.Term{types.NewTerm(false, T)}, nil - } -} - -// Deref returns the type of the variable pointed to by t, -// if t's core type is a pointer; otherwise it returns t. -// -// Do not assume that Deref(T)==T implies T is not a pointer: -// consider "type T *T", for example. -// -// TODO(adonovan): ideally this would live in typesinternal, but that -// creates an import cycle. Move there when we melt this package down. -func Deref(t types.Type) types.Type { - if ptr, ok := CoreType(t).(*types.Pointer); ok { - return ptr.Elem() - } - return t -} - -// MustDeref returns the type of the variable pointed to by t. -// It panics if t's core type is not a pointer. -// -// TODO(adonovan): ideally this would live in typesinternal, but that -// creates an import cycle. Move there when we melt this package down. -func MustDeref(t types.Type) types.Type { - if ptr, ok := CoreType(t).(*types.Pointer); ok { - return ptr.Elem() - } - panic(fmt.Sprintf("%v is not a pointer", t)) -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/free.go b/vendor/golang.org/x/tools/internal/typeparams/free.go deleted file mode 100644 index 4c391876..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/free.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2024 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 typeparams - -import ( - "go/types" -) - -// Free is a memoization of the set of free type parameters within a -// type. It makes a sequence of calls to [Free.Has] for overlapping -// types more efficient. The zero value is ready for use. -// -// NOTE: Adapted from go/types/infer.go. If it is later exported, factor. -type Free struct { - seen map[types.Type]bool -} - -// Has reports whether the specified type has a free type parameter. -func (w *Free) Has(typ types.Type) (res bool) { - // detect cycles - if x, ok := w.seen[typ]; ok { - return x - } - if w.seen == nil { - w.seen = make(map[types.Type]bool) - } - w.seen[typ] = false - defer func() { - w.seen[typ] = res - }() - - switch t := typ.(type) { - case nil, *types.Basic: // TODO(gri) should nil be handled here? - break - - case *types.Alias: - if t.TypeParams().Len() > t.TypeArgs().Len() { - return true // This is an uninstantiated Alias. - } - // The expansion of an alias can have free type parameters, - // whether or not the alias itself has type parameters: - // - // func _[K comparable]() { - // type Set = map[K]bool // free(Set) = {K} - // type MapTo[V] = map[K]V // free(Map[foo]) = {V} - // } - // - // So, we must Unalias. - return w.Has(types.Unalias(t)) - - case *types.Array: - return w.Has(t.Elem()) - - case *types.Slice: - return w.Has(t.Elem()) - - case *types.Struct: - for i, n := 0, t.NumFields(); i < n; i++ { - if w.Has(t.Field(i).Type()) { - return true - } - } - - case *types.Pointer: - return w.Has(t.Elem()) - - case *types.Tuple: - n := t.Len() - for i := range n { - if w.Has(t.At(i).Type()) { - return true - } - } - - case *types.Signature: - // t.tparams may not be nil if we are looking at a signature - // of a generic function type (or an interface method) that is - // part of the type we're testing. We don't care about these type - // parameters. - // Similarly, the receiver of a method may declare (rather than - // use) type parameters, we don't care about those either. - // Thus, we only need to look at the input and result parameters. - return w.Has(t.Params()) || w.Has(t.Results()) - - case *types.Interface: - for i, n := 0, t.NumMethods(); i < n; i++ { - if w.Has(t.Method(i).Type()) { - return true - } - } - terms, err := InterfaceTermSet(t) - if err != nil { - return false // ill typed - } - for _, term := range terms { - if w.Has(term.Type()) { - return true - } - } - - case *types.Map: - return w.Has(t.Key()) || w.Has(t.Elem()) - - case *types.Chan: - return w.Has(t.Elem()) - - case *types.Named: - args := t.TypeArgs() - if params := t.TypeParams(); params.Len() > args.Len() { - return true // this is an uninstantiated named type. - } - for i, n := 0, args.Len(); i < n; i++ { - if w.Has(args.At(i)) { - return true - } - } - return w.Has(t.Underlying()) // recurse for types local to parameterized functions - - case *types.TypeParam: - return true - - default: - panic(t) // unreachable - } - - return false -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go deleted file mode 100644 index 8d13f121..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2021 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 typeparams - -import ( - "errors" - "fmt" - "go/types" - "os" - "strings" -) - -//go:generate go run copytermlist.go - -const debug = false - -var ErrEmptyTypeSet = errors.New("empty type set") - -// StructuralTerms returns a slice of terms representing the normalized -// structural type restrictions of a type parameter, if any. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration -// -// type T[P interface{~int; m()}] int -// -// the structural restriction of the type parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// StructuralTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, StructuralTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the -// constraint interface is invalid, exceeds complexity bounds, or has an empty -// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. -// -// StructuralTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) { - constraint := tparam.Constraint() - if constraint == nil { - return nil, fmt.Errorf("%s has nil constraint", tparam) - } - iface, _ := constraint.Underlying().(*types.Interface) - if iface == nil { - return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) - } - return InterfaceTermSet(iface) -} - -// InterfaceTermSet computes the normalized terms for a constraint interface, -// returning an error if the term set cannot be computed or is empty. In the -// latter case, the error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) { - return computeTermSet(iface) -} - -// UnionTermSet computes the normalized terms for a union, returning an error -// if the term set cannot be computed or is empty. In the latter case, the -// error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func UnionTermSet(union *types.Union) ([]*types.Term, error) { - return computeTermSet(union) -} - -func computeTermSet(typ types.Type) ([]*types.Term, error) { - tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) - if err != nil { - return nil, err - } - if tset.terms.isEmpty() { - return nil, ErrEmptyTypeSet - } - if tset.terms.isAll() { - return nil, nil - } - var terms []*types.Term - for _, term := range tset.terms { - terms = append(terms, types.NewTerm(term.tilde, term.typ)) - } - return terms, nil -} - -// A termSet holds the normalized set of terms for a given type. -// -// The name termSet is intentionally distinct from 'type set': a type set is -// all types that implement a type (and includes method restrictions), whereas -// a term set just represents the structural restrictions on a type. -type termSet struct { - complete bool - terms termlist -} - -func indentf(depth int, format string, args ...any) { - fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) -} - -func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { - if t == nil { - panic("nil type") - } - - if debug { - indentf(depth, "%s", t.String()) - defer func() { - if err != nil { - indentf(depth, "=> %s", err) - } else { - indentf(depth, "=> %s", res.terms.String()) - } - }() - } - - const maxTermCount = 100 - if tset, ok := seen[t]; ok { - if !tset.complete { - return nil, fmt.Errorf("cycle detected in the declaration of %s", t) - } - return tset, nil - } - - // Mark the current type as seen to avoid infinite recursion. - tset := new(termSet) - defer func() { - tset.complete = true - }() - seen[t] = tset - - switch u := t.Underlying().(type) { - case *types.Interface: - // The term set of an interface is the intersection of the term sets of its - // embedded types. - tset.terms = allTermlist - for embedded := range u.EmbeddedTypes() { - if _, ok := embedded.Underlying().(*types.TypeParam); ok { - return nil, fmt.Errorf("invalid embedded type %T", embedded) - } - tset2, err := computeTermSetInternal(embedded, seen, depth+1) - if err != nil { - return nil, err - } - tset.terms = tset.terms.intersect(tset2.terms) - } - case *types.Union: - // The term set of a union is the union of term sets of its terms. - tset.terms = nil - for t := range u.Terms() { - var terms termlist - switch t.Type().Underlying().(type) { - case *types.Interface: - tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) - if err != nil { - return nil, err - } - terms = tset2.terms - case *types.TypeParam, *types.Union: - // A stand-alone type parameter or union is not permitted as union - // term. - return nil, fmt.Errorf("invalid union term %T", t) - default: - if t.Type() == types.Typ[types.Invalid] { - continue - } - terms = termlist{{t.Tilde(), t.Type()}} - } - tset.terms = tset.terms.union(terms) - if len(tset.terms) > maxTermCount { - return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) - } - } - case *types.TypeParam: - panic("unreachable") - default: - // For all other types, the term set is just a single non-tilde term - // holding the type itself. - if u != types.Typ[types.Invalid] { - tset.terms = termlist{{false, t}} - } - } - return tset, nil -} - -// under is a facade for the go/types internal function of the same name. It is -// used by typeterm.go. -func under(t types.Type) types.Type { - return t.Underlying() -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go deleted file mode 100644 index 9bc29143..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/termlist.go +++ /dev/null @@ -1,169 +0,0 @@ -// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. -// Source: ../../cmd/compile/internal/types2/termlist.go - -// Copyright 2021 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. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import ( - "go/types" - "strings" -) - -// A termlist represents the type set represented by the union -// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. -// A termlist is in normal form if all terms are disjoint. -// termlist operations don't require the operands to be in -// normal form. -type termlist []*term - -// allTermlist represents the set of all types. -// It is in normal form. -var allTermlist = termlist{new(term)} - -// termSep is the separator used between individual terms. -const termSep = " | " - -// String prints the termlist exactly (without normalization). -func (xl termlist) String() string { - if len(xl) == 0 { - return "∅" - } - var buf strings.Builder - for i, x := range xl { - if i > 0 { - buf.WriteString(termSep) - } - buf.WriteString(x.String()) - } - return buf.String() -} - -// isEmpty reports whether the termlist xl represents the empty set of types. -func (xl termlist) isEmpty() bool { - // If there's a non-nil term, the entire list is not empty. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil { - return false - } - } - return true -} - -// isAll reports whether the termlist xl represents the set of all types. -func (xl termlist) isAll() bool { - // If there's a 𝓤 term, the entire list is 𝓤. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil && x.typ == nil { - return true - } - } - return false -} - -// norm returns the normal form of xl. -func (xl termlist) norm() termlist { - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - used := make([]bool, len(xl)) - var rl termlist - for i, xi := range xl { - if xi == nil || used[i] { - continue - } - for j := i + 1; j < len(xl); j++ { - xj := xl[j] - if xj == nil || used[j] { - continue - } - if u1, u2 := xi.union(xj); u2 == nil { - // If we encounter a 𝓤 term, the entire list is 𝓤. - // Exit early. - // (Note that this is not just an optimization; - // if we continue, we may end up with a 𝓤 term - // and other terms and the result would not be - // in normal form.) - if u1.typ == nil { - return allTermlist - } - xi = u1 - used[j] = true // xj is now unioned into xi - ignore it in future iterations - } - } - rl = append(rl, xi) - } - return rl -} - -// union returns the union xl ∪ yl. -func (xl termlist) union(yl termlist) termlist { - return append(xl, yl...).norm() -} - -// intersect returns the intersection xl ∩ yl. -func (xl termlist) intersect(yl termlist) termlist { - if xl.isEmpty() || yl.isEmpty() { - return nil - } - - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - var rl termlist - for _, x := range xl { - for _, y := range yl { - if r := x.intersect(y); r != nil { - rl = append(rl, r) - } - } - } - return rl.norm() -} - -// equal reports whether xl and yl represent the same type set. -func (xl termlist) equal(yl termlist) bool { - // TODO(gri) this should be more efficient - return xl.subsetOf(yl) && yl.subsetOf(xl) -} - -// includes reports whether t ∈ xl. -func (xl termlist) includes(t types.Type) bool { - for _, x := range xl { - if x.includes(t) { - return true - } - } - return false -} - -// supersetOf reports whether y ⊆ xl. -func (xl termlist) supersetOf(y *term) bool { - for _, x := range xl { - if y.subsetOf(x) { - return true - } - } - return false -} - -// subsetOf reports whether xl ⊆ yl. -func (xl termlist) subsetOf(yl termlist) bool { - if yl.isEmpty() { - return xl.isEmpty() - } - - // each term x of xl must be a subset of yl - for _, x := range xl { - if !yl.supersetOf(x) { - return false // x is not a subset yl - } - } - return true -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go deleted file mode 100644 index fa758cdc..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go +++ /dev/null @@ -1,172 +0,0 @@ -// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. -// Source: ../../cmd/compile/internal/types2/typeterm.go - -// Copyright 2021 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. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import "go/types" - -// A term describes elementary type sets: -// -// ∅: (*term)(nil) == ∅ // set of no types (empty set) -// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) -// T: &term{false, T} == {T} // set of type T -// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t -type term struct { - tilde bool // valid if typ != nil - typ types.Type -} - -func (x *term) String() string { - switch { - case x == nil: - return "∅" - case x.typ == nil: - return "𝓤" - case x.tilde: - return "~" + x.typ.String() - default: - return x.typ.String() - } -} - -// equal reports whether x and y represent the same type set. -func (x *term) equal(y *term) bool { - // easy cases - switch { - case x == nil || y == nil: - return x == y - case x.typ == nil || y.typ == nil: - return x.typ == y.typ - } - // ∅ ⊂ x, y ⊂ 𝓤 - - return x.tilde == y.tilde && types.Identical(x.typ, y.typ) -} - -// union returns the union x ∪ y: zero, one, or two non-nil terms. -func (x *term) union(y *term) (_, _ *term) { - // easy cases - switch { - case x == nil && y == nil: - return nil, nil // ∅ ∪ ∅ == ∅ - case x == nil: - return y, nil // ∅ ∪ y == y - case y == nil: - return x, nil // x ∪ ∅ == x - case x.typ == nil: - return x, nil // 𝓤 ∪ y == 𝓤 - case y.typ == nil: - return y, nil // x ∪ 𝓤 == 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return x, y // x ∪ y == (x, y) if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∪ ~t == ~t - // ~t ∪ T == ~t - // T ∪ ~t == ~t - // T ∪ T == T - if x.tilde || !y.tilde { - return x, nil - } - return y, nil -} - -// intersect returns the intersection x ∩ y. -func (x *term) intersect(y *term) *term { - // easy cases - switch { - case x == nil || y == nil: - return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ - case x.typ == nil: - return y // 𝓤 ∩ y == y - case y.typ == nil: - return x // x ∩ 𝓤 == x - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return nil // x ∩ y == ∅ if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∩ ~t == ~t - // ~t ∩ T == T - // T ∩ ~t == T - // T ∩ T == T - if !x.tilde || y.tilde { - return x - } - return y -} - -// includes reports whether t ∈ x. -func (x *term) includes(t types.Type) bool { - // easy cases - switch { - case x == nil: - return false // t ∈ ∅ == false - case x.typ == nil: - return true // t ∈ 𝓤 == true - } - // ∅ ⊂ x ⊂ 𝓤 - - u := t - if x.tilde { - u = under(u) - } - return types.Identical(x.typ, u) -} - -// subsetOf reports whether x ⊆ y. -func (x *term) subsetOf(y *term) bool { - // easy cases - switch { - case x == nil: - return true // ∅ ⊆ y == true - case y == nil: - return false // x ⊆ ∅ == false since x != ∅ - case y.typ == nil: - return true // x ⊆ 𝓤 == true - case x.typ == nil: - return false // 𝓤 ⊆ y == false since y != 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return false // x ⊆ y == false if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ⊆ ~t == true - // ~t ⊆ T == false - // T ⊆ ~t == true - // T ⊆ T == true - return !x.tilde || y.tilde -} - -// disjoint reports whether x ∩ y == ∅. -// x.typ and y.typ must not be nil. -func (x *term) disjoint(y *term) bool { - if debug && (x.typ == nil || y.typ == nil) { - panic("invalid argument(s)") - } - ux := x.typ - if y.tilde { - ux = under(ux) - } - uy := y.typ - if x.tilde { - uy = under(uy) - } - return !types.Identical(ux, uy) -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go b/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go new file mode 100644 index 00000000..020defc3 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go @@ -0,0 +1,128 @@ +// Copyright 2026 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 typesinternal + +import ( + "go/ast" + "go/token" + "go/types" + + "golang.org/x/tools/go/ast/edge" + "golang.org/x/tools/go/ast/inspector" +) + +// IsAssignedOrAddressTaken reports whether the expression cur denotes a +// variable and appears in a context that assigns it or that takes its address, +// potentially leading to indirect assignment. +// +// These examples cause IsAssignedOrAddressTaken on the identifier for x to +// return true: +// +// x = 1 +// x++ +// x[i] = 1 (assume x is an array) +// x.a[i] = 1 (assume x.a is a non-pointer struct field) +// use(&x) +// +// whereas these cause it to return false: +// +// y = x +// f(x) +// use(x.a[i]) +// use(*x) +// +// The expression may itself be a compound, for example: +// +// use(&(*ptr)) => IsAssignedOrAddressTaken("*ptr") = true +// x.a[i] = 1 => IsAssignedOrAddressTaken("x.a") = true +// _ = x.a[i] => IsAssignedOrAddressTaken("x.a") = false +// +// A variable's declaration is not considered to be an assignment: +// +// var x int => IsAssignedOrAddressTaken(x) = false +// x := 1 => IsAssignedOrAddressTaken(x) = false +// +// TODO(adonovan): revisit the surprising behavior for declarations. +func IsAssignedOrAddressTaken(info *types.Info, cur inspector.Cursor) bool { + // Unfortunately we can't simply use info.Types[e].Assignable() + // as it is always true for a variable even when that variable is + // used only as an r-value. So we must inspect enclosing syntax. +outer: + // Ascend to outermost aggregate of which + // original cur is a part: + // x -> (x) | x.f | x[i] | x[i:j] + for cur = range cur.Enclosing() { + switch cur.ParentEdgeKind() { + case edge.ParenExpr_X: + // If x is an lvalue, then (x) is an lvalue. + case edge.SelectorExpr_X: + // If x is an lvalue, then x.f is an lvalue iff + // the selection does not traverse a pointer. + sel := cur.Parent().Node().(*ast.SelectorExpr) + if seln, ok := info.Selections[sel]; ok { + // Note: there is a bug in Indirect() where it spuriously returns true + // when both the selection receiver and parameter are pointers. However, + // it's okay in this case because there is no address taken when a + // pointer receiver method is called on a pointer type. + if seln.Indirect() { + return false + } + if seln.Kind() == types.MethodVal { + sig := seln.Obj().Type().(*types.Signature) + if is[*types.Pointer](sig.Recv().Type().Underlying()) { + t := seln.Recv() + // The receiver may be an embedded field, so we need + // to get the inner-most type (right before the method + // call in seln.Index()) + for _, idx := range seln.Index()[:len(seln.Index())-1] { + t = t.Underlying().(*types.Struct).Field(idx).Type() + } + if !is[*types.Pointer](t.Underlying()) { + return true // takes address of receiver + } + } + return false + } + } + case edge.IndexExpr_X, edge.SliceExpr_X: + // If x[i] or x[i:j] is an lvalue, + // then x is an lvalue iff x is an array. + if !is[*types.Array](info.TypeOf(cur.Node().(ast.Expr)).Underlying()) { + return false + } + default: + break outer + } + } + switch cur.ParentEdgeKind() { + case edge.AssignStmt_Lhs: + assign := cur.Parent().Node().(*ast.AssignStmt) + if assign.Tok != token.DEFINE { + return true // x = j or x += j + } + id := cur.Node().(*ast.Ident) + // Re-assigned identifiers are recorded in the Uses map. + if _, ok := info.Uses[id]; ok { + return true // reassignment of x (x, y := 1, 2) + } + case edge.RangeStmt_Key, edge.RangeStmt_Value: + rng := cur.Parent().Node().(*ast.RangeStmt) + if rng.Tok == token.ASSIGN { + return true // "for k, v = range x" is like an AssignStmt to k, v + } + case edge.IncDecStmt_X: + return true // x++, x-- + case edge.UnaryExpr_X: + if cur.Parent().Node().(*ast.UnaryExpr).Op == token.AND { + return true // &x + } + } + return false +} + +func is[T any](x any) bool { + _, ok := x.(T) + return ok +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go index 7ebe9768..d5c40a2e 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go @@ -8,7 +8,6 @@ import ( "fmt" "go/ast" "go/types" - _ "unsafe" // for go:linkname hack ) // CallKind describes the function position of an [*ast.CallExpr]. @@ -72,11 +71,15 @@ func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind { if tv.IsBuiltin() { return CallBuiltin } - obj := info.Uses[UsedIdent(info, call.Fun)] + id := UsedIdent(info, call.Fun) + if id == nil { + return CallDynamic + } + obj := info.Uses[id] // Classify the call by the type of the object, if any. switch obj := obj.(type) { case *types.Func: - if interfaceMethod(obj) { + if isInterfaceMethod(obj) { return CallInterface } return CallStatic @@ -127,11 +130,69 @@ func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind { // Note: if e is an instantiated function or method, UsedIdent returns // the corresponding generic function or method on the generic type. func UsedIdent(info *types.Info, e ast.Expr) *ast.Ident { - return usedIdent(info, e) + if info.Types == nil || info.Uses == nil { + panic("one of info.Types or info.Uses is nil; both must be populated") + } + // Look through type instantiation if necessary. + switch d := ast.Unparen(e).(type) { + case *ast.IndexExpr: + if info.Types[d.Index].IsType() { + e = d.X + } + case *ast.IndexListExpr: + e = d.X + } + + switch e := ast.Unparen(e).(type) { + // info.Uses always has the object we want, even for selector expressions. + // We don't need info.Selections. + // See go/types/recording.go:recordSelection. + case *ast.Ident: + return e + case *ast.SelectorExpr: + return e.Sel + } + return nil +} + +// See [golang.org/x/tools/go/types/typeutil.Callee]. +func Callee(info *types.Info, call *ast.CallExpr) types.Object { + id := UsedIdent(info, call.Fun) + if id == nil { + return nil + } + obj := info.Uses[id] + if obj == nil { + return nil + } + if _, ok := obj.(*types.TypeName); ok { + return nil + } + if fn, ok := obj.(*types.Func); ok { + return fn.Origin() + } + return obj } -//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent -func usedIdent(info *types.Info, e ast.Expr) *ast.Ident +// See [golang.org/x/tools/go/types/typeutil.StaticCallee]. +func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { + id := UsedIdent(info, call.Fun) + if id == nil { + return nil + } + obj := info.Uses[id] + if obj == nil { + return nil + } + fn, _ := obj.(*types.Func) + if fn == nil || isInterfaceMethod(fn) { + return nil + } + return fn.Origin() +} -//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod -func interfaceMethod(f *types.Func) bool +// isInterfaceMethod reports whether its argument is a method of an interface. +func isInterfaceMethod(f *types.Func) bool { + recv := f.Signature().Recv() + return recv != nil && types.IsInterface(recv.Type()) +} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/element.go b/vendor/golang.org/x/tools/internal/typesinternal/element.go index 89eeea16..bab37fbf 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/element.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/element.go @@ -7,8 +7,6 @@ package typesinternal import ( "fmt" "go/types" - - "golang.org/x/tools/go/types/typeutil" ) // ForEachElement calls f for type T and each type reachable from its @@ -16,25 +14,24 @@ import ( // type constructors; in addition, for each named type N, the type *N // is added to the result as it may have additional methods. // -// The caller must provide an initially empty set used to de-duplicate -// identical types, potentially across multiple calls to ForEachElement. -// (Its final value holds all the elements seen, matching the arguments -// passed to f.) +// The access argument passed to f indicates whether the type is +// inaccessible to reflection (for example, intermediate tuple types +// or underlying types of named types). // -// TODO(adonovan): share/harmonize with go/callgraph/rta. -func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T types.Type, f func(types.Type)) { - var visit func(T types.Type, skip bool) - visit = func(T types.Type, skip bool) { - if !skip { - if seen, _ := rtypes.Set(T, true).(bool); seen { - return // de-dup - } - - f(T) // notify caller of new element type +// The result of f indicates whether the caller has seen this type +// already, so we can prune the traversal. +// +// methodSetOf abstracts (*typeutil.MethodSetCache).MethodSet, +// avoiding an import cycle. +func ForEachElement(methodSetOf func(types.Type) *types.MethodSet, T types.Type, f func(T types.Type, access bool) bool) { + var visit func(T types.Type, access bool) + visit = func(T types.Type, access bool) { + if f(T, access) { + return // duplicate; prune descent } // Recursion over signatures of each method. - tmset := msets.MethodSet(T) + tmset := methodSetOf(T) for method := range tmset.Methods() { sig := method.Type().(*types.Signature) if sig.TypeParams() != nil { @@ -65,13 +62,13 @@ func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T type // // TODO(adonovan): document whether or not it is // safe to skip non-exported methods (as RTA does). - visit(sig.Params(), true) // skip the Tuple - visit(sig.Results(), true) // skip the Tuple + visit(sig.Params(), false) // the Tuple is inaccessible + visit(sig.Results(), false) // the Tuple is inaccessible } switch T := T.(type) { case *types.Alias: - visit(types.Unalias(T), skip) // emulates the pre-Alias behavior + visit(types.Unalias(T), access) // emulates the pre-Alias behavior case *types.Basic: // nop @@ -80,49 +77,49 @@ func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T type // nop---handled by recursion over method set. case *types.Pointer: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Slice: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Chan: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Map: - visit(T.Key(), false) - visit(T.Elem(), false) + visit(T.Key(), true) + visit(T.Elem(), true) case *types.Signature: if T.Recv() != nil { panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv())) } - visit(T.Params(), true) // skip the Tuple - visit(T.Results(), true) // skip the Tuple + visit(T.Params(), false) // the Tuple is inaccessible + visit(T.Results(), false) // the Tuple is inaccessible case *types.Named: // A pointer-to-named type can be derived from a named // type via reflection. It may have methods too. - visit(types.NewPointer(T), false) + visit(types.NewPointer(T), true) // Consider 'type T struct{S}' where S has methods. // Reflection provides no way to get from T to struct{S}, // only to S, so the method set of struct{S} is unwanted, - // so set 'skip' flag during recursion. - visit(T.Underlying(), true) // skip the unnamed type + // so mark it inaccessible during recursion. + visit(T.Underlying(), false) // skip the unnamed type case *types.Array: - visit(T.Elem(), false) + visit(T.Elem(), true) case *types.Struct: for i, n := 0, T.NumFields(); i < n; i++ { // TODO(adonovan): document whether or not // it is safe to skip non-exported fields. - visit(T.Field(i).Type(), false) + visit(T.Field(i).Type(), true) } case *types.Tuple: for i, n := 0, T.Len(); i < n; i++ { - visit(T.At(i).Type(), false) + visit(T.At(i).Type(), true) } case *types.TypeParam, *types.Union: @@ -133,5 +130,5 @@ func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T type panic(fmt.Sprintf("ForEachElement called on unexpected type %T", T)) } } - visit(T, false) + visit(T, true) } diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go index cc86487e..386c59c7 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go @@ -13,20 +13,30 @@ import ( // TooNewStdSymbols computes the set of package-level symbols // exported by pkg that are not available at the specified version. -// The result maps each symbol to its minimum version. // // The pkg is allowed to contain type errors. -func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string { - disallowed := make(map[types.Object]string) +func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]stdlib.Symbol { + disallowed := make(map[types.Object]stdlib.Symbol) + + // Some symbols are accessible before their release but + // only with specific build tags unknown to us here. + // Avoid false positives in such cases. + if pkg.Path() == "testing/synctest" && versions.AtLeast(version, "go1.24") { + // requires go1.24 && goexperiment.synctest || go1.25 + return disallowed + } + if (pkg.Path() == "encoding/json/v2" || pkg.Path() == "encoding/json/jsontext") && versions.AtLeast(version, "go1.25") { + // requires go1.25 && goexperiment.jsonv2 || go1.27 + return disallowed + } // Pass 1: package-level symbols. symbols := stdlib.PackageSymbols[pkg.Path()] for _, sym := range symbols { - symver := sym.Version.String() - if versions.Before(version, symver) { + if versions.Before(version, sym.Version.String()) { switch sym.Kind { case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type: - disallowed[pkg.Scope().Lookup(sym.Name)] = symver + disallowed[pkg.Scope().Lookup(sym.Name)] = sym } } } @@ -60,28 +70,36 @@ func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]strin // spuriously cause the analyzer to report a reference to a // too-new symbol even though this expression compiles just // fine (with the fake implementation) using go1.21. + var noSym stdlib.Symbol + depth := make(map[types.Object]int) for _, sym := range symbols { - symVersion := sym.Version.String() - if !versions.Before(version, symVersion) { + if !versions.Before(version, sym.Version.String()) { continue // allowed } var obj types.Object + var indices []int switch sym.Kind { case stdlib.Field: typename, name := sym.SplitField() - if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) + if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == noSym { + obj, indices, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) } case stdlib.Method: ptr, recvname, name := sym.SplitMethod() - if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) + if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == noSym { + obj, indices, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) } } if obj != nil { - disallowed[obj] = symVersion + // In the presence of embedding, two or more "pkg.T.name" + // strings may map to the same types.Object. + // Prefer the Object with the shorter index path. + if min, ok := depth[obj]; !ok || len(indices) < min { + depth[obj] = len(indices) + disallowed[obj] = sym + } } } diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go index d2c0b4c5..9fd48b08 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -270,3 +270,11 @@ func ImplicitFieldSelections(seln types.Selection) iter.Seq2[*types.Var, bool] { } } } + +func TupleOf(elems ...types.Type) *types.Tuple { + params := make([]*types.Var, len(elems)) + for i, elem := range elems { + params[i] = types.NewParam(token.NoPos, nil, "", elem) + } + return types.NewTuple(params...) +} diff --git a/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go b/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go index 12479f69..22dbc522 100644 --- a/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go +++ b/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go @@ -39,27 +39,14 @@ import ( var randIntN = rand.IntN -// ChildState is the balancer state of a child along with the endpoint which -// identifies the child balancer. +// ChildState is the state of a child balancer. type ChildState struct { - Endpoint resolver.Endpoint - State balancer.State - - // Balancer exposes only the ExitIdler interface of the child LB policy. - // Other methods of the child policy are called only by endpointsharding. - Balancer ExitIdler -} - -// ExitIdler provides access to only the ExitIdle method of the child balancer. -type ExitIdler interface { - // ExitIdle instructs the LB policy to reconnect to backends / exit the - // IDLE state, if appropriate and possible. Note that SubConns that enter - // the IDLE state will not reconnect until SubConn.Connect is called. - ExitIdle() + Endpoint resolver.Endpoint // Endpoint of the child balancer. + State balancer.State // State of the child balancer. + ExitIdle func() // Function to exit the child balancer from IDLE state. } -// Options are the options to configure the behaviour of the -// endpointsharding balancer. +// Options configure the behaviour of the endpointsharding balancer. type Options struct { // DisableAutoReconnect allows the balancer to keep child balancer in the // IDLE state until they are explicitly triggered to exit using the @@ -77,14 +64,13 @@ type ChildBuilderFunc func(cc balancer.ClientConn, opts balancer.BuildOptions) b // policies each owning a single endpoint. The endpointsharding balancer // forwards the LoadBalancingConfig in ClientConn state updates to its children. func NewBalancer(cc balancer.ClientConn, opts balancer.BuildOptions, childBuilder ChildBuilderFunc, esOpts Options) balancer.Balancer { - es := &endpointSharding{ + return &endpointSharding{ cc: cc, bOpts: opts, esOpts: esOpts, childBuilder: childBuilder, + endpoints: resolver.NewEndpointMap[*endpointState](), } - es.children.Store(resolver.NewEndpointMap[*balancerWrapper]()) - return es } // endpointSharding is a balancer that wraps child balancers. It creates a child @@ -96,124 +82,129 @@ type endpointSharding struct { esOpts Options childBuilder ChildBuilderFunc - // childMu synchronizes calls to any single child. It must be held for all - // calls into a child. To avoid deadlocks, do not acquire childMu while - // holding mu. - childMu sync.Mutex - children atomic.Pointer[resolver.EndpointMap[*balancerWrapper]] - - // inhibitChildUpdates is set during UpdateClientConnState/ResolverError - // calls (calls to children will each produce an update, only want one - // update). - inhibitChildUpdates atomic.Bool - - // mu synchronizes access to the state stored in balancerWrappers in the - // children field. mu must not be held during calls into a child since - // synchronous calls back from the child may require taking mu, causing a - // deadlock. To avoid deadlocks, do not acquire childMu while holding mu. - mu sync.Mutex + // mu guards access to the below fields and guarantees mutual exclusion + // between top-down methods (like UpdateClientConnState, ResolverError etc, + // which are already serialized) and bottom-up methods (like UpdateState) + // that can be called concurrently. + // + // Lock ordering & deadlock prevention: + // Child callbacks (like UpdateState) acquire this mutex to push state updates + // to the parent. This establishes a strict lock ordering: + // [endpointState.childMu] -> [endpointSharding.mu] + // + // To prevent deadlocks, we must never invert this order. Therefore, we must + // never call any methods on a child balancer while holding this mutex. If we + // did, and that child balancer invoked UpdateState synchronously, it would + // attempt to re-acquire this mutex, causing a deadlock. + // + // Concurrency: + // Top-down operations need to iterate over all children. To ensure a + // single, clean aggregated update at the end of such operations, we inhibit + // intermediate updates from children. We grab this mutex briefly to set + // `inhibitChildUpdates = true` and immediately release it. This allows us + // to perform the potentially slow, top-down child updates without holding + // any parent locks. Once finished, we grab the mutex again to unset the + // flag and push the final aggregated state. An update from a child during + // this time will *only* update the child state, and will not access the + // endpoints map or push an aggregated state to the parent. + mu sync.Mutex + endpoints *resolver.EndpointMap[*endpointState] + inhibitChildUpdates bool } // rotateEndpoints returns a slice of all the input endpoints rotated a random // amount. func rotateEndpoints(es []resolver.Endpoint) []resolver.Endpoint { - les := len(es) - if les == 0 { + n := len(es) + if n == 0 { return es } - r := randIntN(les) + r := randIntN(n) + // Make a copy to avoid mutating data beyond the end of es. - ret := make([]resolver.Endpoint, les) + ret := make([]resolver.Endpoint, n) copy(ret, es[r:]) - copy(ret[les-r:], es[:r]) + copy(ret[n-r:], es[:r]) return ret } // UpdateClientConnState creates a child for new endpoints and deletes children // for endpoints that are no longer present. It also updates all the children, // and sends a single synchronous update of the childrens' aggregated state at -// the end of the UpdateClientConnState operation. If any endpoint has no -// addresses it will ignore that endpoint. Otherwise, returns first error found -// from a child, but fully processes the new update. +// the end of the UpdateClientConnState operation. +// +// Returns the first error found from a child, but fully processes the update. func (es *endpointSharding) UpdateClientConnState(state balancer.ClientConnState) error { - es.childMu.Lock() - defer es.childMu.Unlock() - - es.inhibitChildUpdates.Store(true) - defer func() { - es.inhibitChildUpdates.Store(false) - es.updateState() - }() - var ret error - - children := es.children.Load() - newChildren := resolver.NewEndpointMap[*balancerWrapper]() + es.inhibitUpdatesFromChildren() - // Update/Create new children. + // Update/create child balancers for each endpoint in the update. Note that we + // don't hold the mutex here, but this is fine because inhibitChildUpdates is + // true, and therefore UpdateState will not access es.endpoints. + var retErr error + newEndpoints := resolver.NewEndpointMap[*endpointState]() for _, endpoint := range rotateEndpoints(state.ResolverState.Endpoints) { - if _, ok := newChildren.Get(endpoint); ok { - // Endpoint child was already created, continue to avoid duplicate - // update. + if _, ok := newEndpoints.Get(endpoint); ok { + // Skip duplicate endpoints. continue } - childBalancer, ok := children.Get(endpoint) + epState, ok := es.endpoints.Get(endpoint) if ok { - // Endpoint attributes may have changed, update the stored endpoint. - es.mu.Lock() - childBalancer.childState.Endpoint = endpoint - es.mu.Unlock() + // Endpoint child already exists, update the stored endpoint. + epState.endpoint = endpoint } else { - childBalancer = &balancerWrapper{ - childState: ChildState{Endpoint: endpoint}, - ClientConn: es.cc, - es: es, + // Endpoint child does not exist, create a new one. + epState = &endpointState{ + ClientConn: es.cc, + parent: es, + endpoint: endpoint, + disableAutoReconnect: es.esOpts.DisableAutoReconnect, } - childBalancer.childState.Balancer = childBalancer - childBalancer.child = es.childBuilder(childBalancer, es.bOpts) + epState.childLB = es.childBuilder(epState, es.bOpts) } - newChildren.Set(endpoint, childBalancer) - if err := childBalancer.updateClientConnStateLocked(balancer.ClientConnState{ + // Update the endpoint state for the endpoint. + newEndpoints.Set(endpoint, epState) + + if err := epState.updateClientConnState(balancer.ClientConnState{ BalancerConfig: state.BalancerConfig, ResolverState: resolver.State{ Endpoints: []resolver.Endpoint{endpoint}, Attributes: state.ResolverState.Attributes, }, - }); err != nil && ret == nil { - // Return first error found, and always commit full processing of - // updating children. If desired to process more specific errors - // across all endpoints, caller should make these specific - // validations, this is a current limitation for simplicity sake. - ret = err + }); err != nil && retErr == nil { + // Keep the first error found from any child. + retErr = err } } + // Delete old children that are no longer present. - for e, child := range children.All() { - if _, ok := newChildren.Get(e); !ok { - child.closeLocked() + for e, child := range es.endpoints.All() { + if _, ok := newEndpoints.Get(e); !ok { + child.close() } } - es.children.Store(newChildren) - if newChildren.Len() == 0 { - return balancer.ErrBadResolverState + + if newEndpoints.Len() == 0 { + retErr = balancer.ErrBadResolverState } - return ret + + es.mu.Lock() + es.endpoints = newEndpoints + es.inhibitChildUpdates = false + es.updateStateLocked() + es.mu.Unlock() + + return retErr } // ResolverError forwards the resolver error to all of the endpointSharding's // children and sends a single synchronous update of the childStates at the end // of the ResolverError operation. func (es *endpointSharding) ResolverError(err error) { - es.childMu.Lock() - defer es.childMu.Unlock() - es.inhibitChildUpdates.Store(true) - defer func() { - es.inhibitChildUpdates.Store(false) - es.updateState() - }() - children := es.children.Load() - for _, child := range children.All() { - child.resolverErrorLocked(err) + es.inhibitUpdatesFromChildren() + for _, child := range es.endpoints.All() { + child.resolverError(err) } + es.allowUpdatesFromChildren() } func (es *endpointSharding) UpdateSubConnState(balancer.SubConn, balancer.SubConnState) { @@ -221,41 +212,49 @@ func (es *endpointSharding) UpdateSubConnState(balancer.SubConn, balancer.SubCon } func (es *endpointSharding) Close() { - es.childMu.Lock() - defer es.childMu.Unlock() - children := es.children.Load() - for _, child := range children.All() { - child.closeLocked() + es.inhibitUpdatesFromChildren() + for _, child := range es.endpoints.All() { + child.close() } } func (es *endpointSharding) ExitIdle() { - es.childMu.Lock() - defer es.childMu.Unlock() - for _, bw := range es.children.Load().All() { - if !bw.isClosed { - bw.child.ExitIdle() - } + es.inhibitUpdatesFromChildren() + for _, child := range es.endpoints.All() { + child.exitIdle() } + es.allowUpdatesFromChildren() } -// updateState updates this component's state. It sends the aggregated state, -// and a picker with round robin behavior with all the child states present if -// needed. -func (es *endpointSharding) updateState() { - if es.inhibitChildUpdates.Load() { - return - } - var readyPickers, connectingPickers, idlePickers, transientFailurePickers []balancer.Picker +func (es *endpointSharding) inhibitUpdatesFromChildren() { + es.mu.Lock() + es.inhibitChildUpdates = true + es.mu.Unlock() +} +func (es *endpointSharding) allowUpdatesFromChildren() { es.mu.Lock() - defer es.mu.Unlock() + es.inhibitChildUpdates = false + es.updateStateLocked() + es.mu.Unlock() +} - children := es.children.Load() - childStates := make([]ChildState, 0, children.Len()) +// updateStateLocked updates this component's state. It sends the aggregated +// state, and a picker with round robin behavior with all the child states +// present if needed. This method must only be called when inhibitChildUpdates +// is false. +// +// Caller must hold es.mu. +func (es *endpointSharding) updateStateLocked() { + var readyPickers, connectingPickers, idlePickers, transientFailurePickers []balancer.Picker - for _, child := range children.All() { - childState := child.childState + childStates := make([]ChildState, 0, es.endpoints.Len()) + for _, epState := range es.endpoints.All() { + childState := ChildState{ + Endpoint: epState.endpoint, + State: epState.state, + ExitIdle: func() { go epState.exitIdle() }, + } childStates = append(childStates, childState) childPicker := childState.State.Picker switch childState.State.ConnectivityState { @@ -292,14 +291,14 @@ func (es *endpointSharding) updateState() { aggState = connectivity.TransientFailure pickers = []balancer.Picker{base.NewErrPicker(errors.New("no children to pick from"))} } // No children (resolver error before valid update). - p := &pickerWithChildStates{ - pickers: pickers, - childStates: childStates, - next: uint32(randIntN(len(pickers))), - } + es.cc.UpdateState(balancer.State{ ConnectivityState: aggState, - Picker: p, + Picker: &pickerWithChildStates{ + pickers: pickers, + childStates: childStates, + next: uint32(randIntN(len(pickers))), + }, }) } @@ -328,61 +327,59 @@ func ChildStatesFromPicker(picker balancer.Picker) []ChildState { return p.childStates } -// balancerWrapper is a wrapper of a balancer. It ID's a child balancer by -// endpoint, and persists recent child balancer state. -type balancerWrapper struct { - // The following fields are initialized at build time and read-only after - // that and therefore do not need to be guarded by a mutex. - - // child contains the wrapped balancer. Access its methods only through - // methods on balancerWrapper to ensure proper synchronization - child balancer.Balancer - balancer.ClientConn // embed to intercept UpdateState, doesn't deal with SubConns +// endpointState is the internal state maintained for each endpoint. +type endpointState struct { + balancer.ClientConn // Embedded to intercept UpdateState - es *endpointSharding + parent *endpointSharding // Parent endpointsharding balancer. + endpoint resolver.Endpoint // Endpoint of the child balancer. + state balancer.State // State of the child balancer. + disableAutoReconnect bool // Whether to disable auto reconnect for this child. - // Access to the following fields is guarded by es.mu. - - childState ChildState - isClosed bool + childMu sync.Mutex // Guarantees mutual exclusion for Balancer API calls to the child balancer. + childLB balancer.Balancer // Child balancer. + closed bool // Tracks closure of the child balancer to ensure ExitIdle is not called after Close(). } -func (bw *balancerWrapper) UpdateState(state balancer.State) { - bw.es.mu.Lock() - bw.childState.State = state - bw.es.mu.Unlock() - if state.ConnectivityState == connectivity.Idle && !bw.es.esOpts.DisableAutoReconnect { - bw.ExitIdle() +func (es *endpointState) UpdateState(state balancer.State) { + es.parent.mu.Lock() + es.state = state + if !es.parent.inhibitChildUpdates { + es.parent.updateStateLocked() + } + es.parent.mu.Unlock() + + if state.ConnectivityState == connectivity.Idle && !es.disableAutoReconnect { + go es.exitIdle() } - bw.es.updateState() } -// ExitIdle pings an IDLE child balancer to exit idle in a new goroutine to -// avoid deadlocks due to synchronous balancer state updates. -func (bw *balancerWrapper) ExitIdle() { - go func() { - bw.es.childMu.Lock() - if !bw.isClosed { - bw.child.ExitIdle() - } - bw.es.childMu.Unlock() - }() +func (es *endpointState) updateClientConnState(state balancer.ClientConnState) error { + es.childMu.Lock() + err := es.childLB.UpdateClientConnState(state) + es.childMu.Unlock() + return err } -// updateClientConnStateLocked delivers the ClientConnState to the child -// balancer. Callers must hold the child mutex of the parent endpointsharding -// balancer. -func (bw *balancerWrapper) updateClientConnStateLocked(ccs balancer.ClientConnState) error { - return bw.child.UpdateClientConnState(ccs) +func (es *endpointState) resolverError(err error) { + es.childMu.Lock() + es.childLB.ResolverError(err) + es.childMu.Unlock() } -// closeLocked closes the child balancer. Callers must hold the child mutext of -// the parent endpointsharding balancer. -func (bw *balancerWrapper) closeLocked() { - bw.child.Close() - bw.isClosed = true +func (es *endpointState) close() { + es.childMu.Lock() + if !es.closed { + es.closed = true + es.childLB.Close() + } + es.childMu.Unlock() } -func (bw *balancerWrapper) resolverErrorLocked(err error) { - bw.child.ResolverError(err) +func (es *endpointState) exitIdle() { + es.childMu.Lock() + if !es.closed { + es.childLB.ExitIdle() + } + es.childMu.Unlock() } diff --git a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go index d48bc304..ddd08f53 100644 --- a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go +++ b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go @@ -36,7 +36,6 @@ import ( "google.golang.org/grpc/balancer/pickfirst/internal" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/experimental/balancer/weight" - expstats "google.golang.org/grpc/experimental/stats" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal/envconfig" internalgrpclog "google.golang.org/grpc/internal/grpclog" @@ -56,30 +55,7 @@ const Name = "pick_first" // attributes to indicate whether the health listener usage is enabled. type enableHealthListenerKeyType struct{} -var ( - logger = grpclog.Component("pick-first-leaf-lb") - disconnectionsMetric = expstats.RegisterInt64Count(expstats.MetricDescriptor{ - Name: "grpc.lb.pick_first.disconnections", - Description: "EXPERIMENTAL. Number of times the selected subchannel becomes disconnected.", - Unit: "{disconnection}", - Labels: []string{"grpc.target"}, - Default: false, - }) - connectionAttemptsSucceededMetric = expstats.RegisterInt64Count(expstats.MetricDescriptor{ - Name: "grpc.lb.pick_first.connection_attempts_succeeded", - Description: "EXPERIMENTAL. Number of successful connection attempts.", - Unit: "{attempt}", - Labels: []string{"grpc.target"}, - Default: false, - }) - connectionAttemptsFailedMetric = expstats.RegisterInt64Count(expstats.MetricDescriptor{ - Name: "grpc.lb.pick_first.connection_attempts_failed", - Description: "EXPERIMENTAL. Number of failed connection attempts.", - Unit: "{attempt}", - Labels: []string{"grpc.target"}, - Default: false, - }) -) +var logger = grpclog.Component("pick-first-leaf-lb") const ( // TODO: change to pick-first when this becomes the default pick_first policy. @@ -101,11 +77,9 @@ const ( type pickfirstBuilder struct{} -func (pickfirstBuilder) Build(cc balancer.ClientConn, bo balancer.BuildOptions) balancer.Balancer { +func (pickfirstBuilder) Build(cc balancer.ClientConn, _ balancer.BuildOptions) balancer.Balancer { b := &pickfirstBalancer{ - cc: cc, - target: bo.Target.String(), - metricsRecorder: cc.MetricsRecorder(), + cc: cc, subConns: resolver.NewAddressMapV2[*scData](), state: connectivity.Connecting, @@ -185,10 +159,8 @@ func (b *pickfirstBalancer) newSCData(addr resolver.Address) (*scData, error) { type pickfirstBalancer struct { // The following fields are initialized at build time and read-only after // that and therefore do not need to be guarded by a mutex. - logger *internalgrpclog.PrefixLogger - cc balancer.ClientConn - target string - metricsRecorder expstats.MetricsRecorder // guaranteed to be non nil + logger *internalgrpclog.PrefixLogger + cc balancer.ClientConn // The mutex is used to ensure synchronization of updates triggered // from the idle picker and the already serialized resolver, @@ -633,14 +605,11 @@ func (b *pickfirstBalancer) updateSubConnState(sd *scData, newState balancer.Sub return } - // Record a connection attempt when exiting CONNECTING. if newState.ConnectivityState == connectivity.TransientFailure { sd.connectionFailedInFirstPass = true - connectionAttemptsFailedMetric.Record(b.metricsRecorder, 1, b.target) } if newState.ConnectivityState == connectivity.Ready { - connectionAttemptsSucceededMetric.Record(b.metricsRecorder, 1, b.target) b.shutdownRemainingLocked(sd) if !b.addressList.seekTo(sd.addr) { // This should not fail as we should have only one SubConn after @@ -689,15 +658,6 @@ func (b *pickfirstBalancer) updateSubConnState(sd *scData, newState balancer.Sub // the first address when the picker is used. b.shutdownRemainingLocked(sd) sd.effectiveState = newState.ConnectivityState - // READY SubConn interspliced in between CONNECTING and IDLE, need to - // account for that. - if oldState == connectivity.Connecting { - // A known issue (https://github.com/grpc/grpc-go/issues/7862) - // causes a race that prevents the READY state change notification. - // This works around it. - connectionAttemptsSucceededMetric.Record(b.metricsRecorder, 1, b.target) - } - disconnectionsMetric.Record(b.metricsRecorder, 1, b.target) b.addressList.reset() b.updateBalancerState(balancer.State{ ConnectivityState: connectivity.Idle, diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index 296123e2..6c249fda 100644 --- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -679,7 +679,7 @@ func (x *Message) GetData() []byte { // A list of metadata pairs, used in the payload of client header, // server header, and server trailer. // Implementations may omit some entries to honor the header limits -// of GRPC_BINARY_LOG_CONFIG. +// of GRPC_BINARY_LOG_FILTER. // // Header keys added by gRPC are omitted. To be more specific, // implementations will not log the following entries, and this is @@ -689,7 +689,9 @@ func (x *Message) GetData() []byte { // or keys like 'lb-token' // - transport specific entries, including but not limited to: // ':path', ':authority', 'content-encoding', 'user-agent', 'te', etc -// - entries added for call credentials +// - entries added for call credentials (on client side, excludes all +// such headers; on server side, excludes only the "authorization" +// header) // // Implementations must always log grpc-trace-bin if it is present. // Practically speaking it will only be visible on server side because diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go index 788c89c1..2079bf4e 100644 --- a/vendor/google.golang.org/grpc/call.go +++ b/vendor/google.golang.org/grpc/call.go @@ -20,6 +20,10 @@ package grpc import ( "context" + "io" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // Invoke sends the RPC request on the wire and returns after response is @@ -67,8 +71,27 @@ func invoke(ctx context.Context, method string, req, reply any, cc *ClientConn, if err != nil { return err } - if err := cs.SendMsg(req); err != nil { + // In case of nil or io.EOF error, call RecvMsg. + if err := cs.SendMsg(req); err != nil && err != io.EOF { + return err + } + // CloseSend is needed because in some scenarios (e.g., xDS), the same + // interceptors are used to process both unary and streaming RPCs. Calling + // CloseSend signals to those interceptors that no more messages are on the + // way. + if err := cs.CloseSend(); err != nil && err != io.EOF { return err } - return cs.RecvMsg(reply) + if err := cs.RecvMsg(reply); err != nil { + return err + } + // Call RecvMsg again to get the trailers. + err = cs.RecvMsg(reply) + if err == io.EOF { + return nil + } + if err == nil { + return status.Error(codes.Internal, "cardinality violation: expected for non server-streaming RPCs, but received another message") + } + return err } diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index b27c7e84..f5ce0719 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -553,6 +553,7 @@ func chainStreamClientInterceptors(cc *ClientConn) { if cc.dopts.streamInt != nil { interceptors = append([]StreamClientInterceptor{cc.dopts.streamInt}, interceptors...) } + interceptors = append(interceptors, defaultStreamInterceptor) var chainedInt StreamClientInterceptor if len(interceptors) == 0 { chainedInt = nil diff --git a/vendor/google.golang.org/grpc/internal/buffer/unbounded.go b/vendor/google.golang.org/grpc/internal/buffer/unbounded.go index 467392b8..d1f4b634 100644 --- a/vendor/google.golang.org/grpc/internal/buffer/unbounded.go +++ b/vendor/google.golang.org/grpc/internal/buffer/unbounded.go @@ -27,32 +27,29 @@ import ( // extra goroutines. This is typically used for passing updates from one entity // to another within gRPC. // +// To avoid extra memory allocations and type assertions, using any on +// performance-critical code paths is discouraged. Use concrete types wherever +// possible when instantiating Unbounded. +// // All methods on this type are thread-safe and don't block on anything except // the underlying mutex used for synchronization. -// -// Unbounded supports values of any type to be stored in it by using a channel -// of `any`. This means that a call to Put() incurs an extra memory allocation, -// and also that users need a type assertion while reading. For performance -// critical code paths, using Unbounded is strongly discouraged and defining a -// new type specific implementation of this buffer is preferred. See -// internal/transport/transport.go for an example of this. -type Unbounded struct { - c chan any +type Unbounded[T any] struct { + c chan T closed bool closing bool mu sync.Mutex - backlog []any + backlog []T } // NewUnbounded returns a new instance of Unbounded. -func NewUnbounded() *Unbounded { - return &Unbounded{c: make(chan any, 1)} +func NewUnbounded[T any]() *Unbounded[T] { + return &Unbounded[T]{c: make(chan T, 1)} } var errBufferClosed = errors.New("Put called on closed buffer.Unbounded") // Put adds t to the unbounded buffer. -func (b *Unbounded) Put(t any) error { +func (b *Unbounded[T]) Put(t T) error { b.mu.Lock() defer b.mu.Unlock() if b.closing { @@ -72,13 +69,14 @@ func (b *Unbounded) Put(t any) error { // Load sends the earliest buffered data, if any, onto the read channel returned // by Get(). Users are expected to call this every time they successfully read a // value from the read channel. -func (b *Unbounded) Load() { +func (b *Unbounded[T]) Load() { b.mu.Lock() defer b.mu.Unlock() if len(b.backlog) > 0 { select { case b.c <- b.backlog[0]: - b.backlog[0] = nil + var zero T + b.backlog[0] = zero b.backlog = b.backlog[1:] default: } @@ -96,14 +94,14 @@ func (b *Unbounded) Load() { // // If the unbounded buffer is closed, the read channel returned by this method // is closed after all data is drained. -func (b *Unbounded) Get() <-chan any { +func (b *Unbounded[T]) Get() <-chan T { return b.c } // Close closes the unbounded buffer. No subsequent data may be Put(), and the // channel returned from Get() will be closed after all the data is read and // Load() is called for the final time. -func (b *Unbounded) Close() { +func (b *Unbounded[T]) Close() { b.mu.Lock() defer b.mu.Unlock() if b.closing { diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 33344812..dc6fc0c4 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -153,6 +153,13 @@ var ( // TODO: Remove this env var once v1.83.0 is released. ControlBufferThrottleLimit = uint64FromEnv("GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT", 100, 1, 10000) + // ALTSMaxFrameSize is the maximum frame size for ALTS in bytes. + // This can be overridden by setting the environment variable + // "GRPC_GO_EXPERIMENTAL_ALTS_MAX_FRAME_SIZE" (min: 4096, max: 512*1024, capped at + // 512KiB to match altsWriteBufferMaxSize in + // credentials/alts/internal/conn/record.go). + ALTSMaxFrameSize = uint64FromEnv("GRPC_GO_EXPERIMENTAL_ALTS_MAX_FRAME_SIZE", 4096, 4096, 512*1024) + // EnableReceiveBufferCompaction enables the compaction of data buffers // to reduce the number of buffers in the receive buffer. // diff --git a/vendor/google.golang.org/grpc/internal/envconfig/xds.go b/vendor/google.golang.org/grpc/internal/envconfig/xds.go index e4b69191..5ec39bd7 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/xds.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/xds.go @@ -98,4 +98,9 @@ var ( // filter. For more details, see: // https://github.com/grpc/proposal/blob/master/A83-xds-gcp-authn-filter.md GCPAuthenticationFilterEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_GCP_AUTHENTICATION_FILTER", false) + + // XDSClientExtAuthzEnabled indicates whether the external authorization + // filter is enabled on the client side. For more details, see: + // https://github.com/grpc/proposal/blob/master/A92-xds-ext-authz.md + XDSClientExtAuthzEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_EXT_AUTHZ_ON_CLIENT", false) ) diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go index d4999fcc..caa9dd68 100644 --- a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go +++ b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go @@ -41,7 +41,7 @@ type CallbackSerializer struct { // its resources. done chan struct{} - callbacks *buffer.Unbounded + callbacks *buffer.Unbounded[func(context.Context)] } // NewCallbackSerializer returns a new CallbackSerializer instance. The provided @@ -52,7 +52,7 @@ type CallbackSerializer struct { func NewCallbackSerializer(ctx context.Context) *CallbackSerializer { cs := &CallbackSerializer{ done: make(chan struct{}), - callbacks: buffer.NewUnbounded(), + callbacks: buffer.NewUnbounded[func(context.Context)](), } go cs.run(ctx) return cs @@ -113,7 +113,7 @@ func (cs *CallbackSerializer) run(ctx context.Context) { // Run all callbacks. for cb := range cs.callbacks.Get() { cs.callbacks.Load() - cb.(func(context.Context))(ctx) + cb(ctx) } } diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/refcounted.go b/vendor/google.golang.org/grpc/internal/grpcsync/refcounted.go new file mode 100644 index 00000000..bca9b837 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcsync/refcounted.go @@ -0,0 +1,109 @@ +/* + * + * Copyright 2026 gRPC 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 grpcsync + +import ( + "sync/atomic" + + "google.golang.org/grpc/grpclog" +) + +var logger = grpclog.Component("grpcsync") + +// RefCounted is a reference counted wrapper of type T. It tracks the number of +// active references and runs a cleanup when the last reference is released. +type RefCounted[T any] struct { + val T + refCount atomic.Int32 + onZero func() +} + +// NewRefCounted creates a new RefCounted instance wrapping the given value with +// initial refcount of one. +// +// The value should typically be a pointer, interface, or handle rather than a +// plain value type (such as a struct or primitive value). +// +// The provided onZero callback must not be nil, and is executed exactly once +// when the reference count drops to zero. Panics if onZero is nil. +// +// WARNING: onZero runs synchronously inside Decrement; it must not acquire +// locks held by Decrement callers. +func NewRefCounted[T any](val T, onZero func()) *RefCounted[T] { + if onZero == nil { + panic("grpcsync: onZero callback cannot be nil") + } + rc := &RefCounted[T]{ + val: val, + onZero: onZero, + } + rc.refCount.Store(1) + return rc +} + +// Value returns the encapsulated resource. +func (rc *RefCounted[T]) Value() T { + return rc.val +} + +// TryIncrement attempts to increment the reference count, returning true if +// successful. It returns false if the count has already reached 0, indicating +// the resource has been cleaned up and cannot be resurrected. +// +// WARNING: Avoid calling TryIncrement on hot paths when an active reference is +// already guaranteed by the caller; use Increment instead to bypass the +// CompareAndSwap loop overhead. TryIncrement should be reserved for speculative +// lookups (such as fetching from a cache or map) where the resource might be +// dead. +func (rc *RefCounted[T]) TryIncrement() bool { + // Utilize a CompareAndSwap loop to prevent race conditions where a concurrent + // decrement could drop the count to zero between the read and the increment + // operation, which would otherwise inadvertently resurrect a closed resource. + for { + count := rc.refCount.Load() + if count <= 0 { + return false // Already dead or dying + } + if rc.refCount.CompareAndSwap(count, count+1) { + return true + } + } +} + +// Increment increments the reference count. +// +// WARNING: Call Increment only when there is a guarantee that an active +// reference is already present, ensuring the resource is not dead. If there is +// a possibility that the resource is dead or its reference count might have +// reached zero, call TryIncrement instead. +func (rc *RefCounted[T]) Increment() { + if rc.refCount.Add(1) <= 1 { + logger.Errorf("Resource already closed or dead") + } +} + +// Decrement decrements the reference count. If it drops to zero, the onZero +// callback is executed synchronously before this method returns. +func (rc *RefCounted[T]) Decrement() { + if v := rc.refCount.Add(-1); v < 0 { + logger.Errorf("Refcount cannot be negative") + } else if v == 0 { + rc.onZero() + } +} diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index 4b3d563f..2b7fa6b0 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -245,6 +245,10 @@ var ( AsyncReporterCleanupDelegate = func(cleanup func()) func() { return cleanup } + + // XDSFilterWrapperOption returns a ServerOption that sets the internal + // stream wrapper used for server-side xDS HTTP filters. + XDSFilterWrapperOption any // func(func(grpc.ServerStream) (grpc.ServerStream, error)) grpc.ServerOption ) // HealthChecker defines the signature of the client-side LB channel health diff --git a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go index 238950bb..ead6dda4 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go +++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go @@ -42,6 +42,10 @@ type RPCInfo struct { // efficiency reasons. SelectConfig should not be blocking. Context context.Context Method string // i.e. "/Service/Method" + // Authority is the target authority (host) name of the RPC. This is required + // for HTTP filters (such as external processing) to populate request + // attributes. + Authority string } // RPCConfig describes the configuration to use for each RPC. @@ -54,17 +58,6 @@ type RPCConfig struct { Interceptor any } -// ServerInterceptor is an interceptor for incoming RPC's on gRPC server side. -type ServerInterceptor interface { - // AllowRPC checks if an incoming RPC is allowed to proceed based on - // information about connection RPC was received on, and HTTP Headers. This - // information will be piped into context. - AllowRPC(ctx context.Context) error // TODO: Make this a real interceptor for filters such as rate limiting. - // Close closes the interceptor. Once called, no new calls to NewStream are - // accepted. Ongoing calls to NewStream are allowed to complete. - Close() -} - type csKeyType string const csKey = csKeyType("grpc.internal.resolver.configSelector") diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index b9bae024..89c938fd 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -219,6 +219,17 @@ type outFlowControlSizeRequest struct { resp chan uint32 } +// outStreamRequestForTesting is used by tests to retrieve a pointer to an outStream +// safely inside the loopyWriter goroutine without racing on loopyWriter.estdStreams. +// By holding the *outStream pointer while streams and transports close down, tests +// can inspect settled accounting values (such as bytesOutStanding) after loopyWriter +// has run to completion without any data races. +type outStreamRequestForTesting struct { + throttledItem + streamID uint32 + resp chan *outStream +} + // closeConnection is an instruction to tell the loopy writer to flush the // framer and exit, which will cause the transport's connection to be closed // (by the client or server). The transport itself will close after the reader @@ -799,6 +810,10 @@ func (l *loopyWriter) outFlowControlSizeRequestHandler(o *outFlowControlSizeRequ o.resp <- l.sendQuota } +func (l *loopyWriter) outStreamRequestHandler(o *outStreamRequestForTesting) { + o.resp <- l.estdStreams[o.streamID] +} + func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error { c.onWrite() if str, ok := l.estdStreams[c.streamID]; ok { @@ -896,6 +911,8 @@ func (l *loopyWriter) handle(i any) error { return l.goAwayHandler(i) case *outFlowControlSizeRequest: l.outFlowControlSizeRequestHandler(i) + case *outStreamRequestForTesting: + l.outStreamRequestHandler(i) case closeConnection: // Just return a non-I/O error and run() will flush and close the // connection. diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index 10d19774..720fc4e5 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -554,8 +554,6 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) if err != nil { return nil, err } - // TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields - // first and create a slice of that exact size. // Make the slice of certain predictable size to reduce allocations made by append. hfLen := 7 // :method, :scheme, :path, :authority, content-type, user-agent, te hfLen += len(authData) + len(callAuthData) @@ -575,6 +573,21 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) if _, ok := ctx.Deadline(); ok { hfLen++ } + // Count the metadata header fields as well so the slice is not reallocated + // while they are appended below. Reserved headers are dropped when writing, + // so this may slightly over-count, which is preferable to growing the slice. + md, added, mdOK := metadataFromOutgoingContextRaw(ctx) + if mdOK { + for _, vv := range md { + hfLen += len(vv) + } + for _, vv := range added { + hfLen += len(vv) / 2 + } + } + for _, vv := range t.md { + hfLen += len(vv) + } headerFields := make([]hpack.HeaderField, 0, hfLen) headerFields = append(headerFields, hpack.HeaderField{Name: ":method", Value: "POST"}) headerFields = append(headerFields, hpack.HeaderField{Name: ":scheme", Value: t.scheme}) @@ -619,7 +632,7 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) } - if md, added, ok := metadataFromOutgoingContextRaw(ctx); ok { + if mdOK { var k string for k, vv := range md { // HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set. @@ -648,6 +661,9 @@ func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) if isReservedHeader(k) { continue } + if err := imetadata.ValidatePair(k, vv...); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } for _, v := range vv { headerFields = append(headerFields, hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) } @@ -691,6 +707,9 @@ func (t *http2Client) getTrAuthData(ctx context.Context, audience string) (map[s for k, v := range data { // Capital header names are illegal in HTTP/2. k = strings.ToLower(k) + if err := imetadata.ValidatePair(k, v); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } authData[k] = v } } @@ -724,6 +743,9 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call for k, v := range data { // Capital header names are illegal in HTTP/2 k = strings.ToLower(k) + if err := imetadata.ValidatePair(k, v); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } callAuthData[k] = v } } @@ -1226,23 +1248,26 @@ func (t *http2Client) handleData(f *parsedDataFrame) { t.closeStream(s, io.EOF, true, http2.ErrCodeFlowControl, status.New(codes.Internal, err.Error()), nil, false) return } + } - if s.nonGRPCStatus != nil { - // The frame should be handled as a non-gRPC response body - st := s.handleNonGRPCData(f) - if st != nil { - t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, true) - return - } - if w := s.fc.onRead(size); w > 0 { - t.controlBuf.put(&outgoingWindowUpdate{ - streamID: s.id, - increment: w, - }) - } + if s.nonGRPCStatus != nil { + // The frame should be handled as a non-gRPC response body. A non-nil + // status also covers END_STREAM, so no separate handling is needed below. + st := s.handleNonGRPCData(f) + if st != nil { + t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, true) return } + if w := s.fc.onRead(size); w > 0 { + t.controlBuf.put(&outgoingWindowUpdate{ + streamID: s.id, + increment: w, + }) + } + return + } + if size > 0 { dataLen := f.data.Len() if f.Header().Flags.Has(http2.FlagDataPadded) { if w := s.fc.onRead(size - uint32(dataLen)); w > 0 { diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index 82e13e64..f11e88cc 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -531,6 +531,7 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade if frame.StreamEnded() { // s is just created by the caller. No lock needed. s.state = streamReadDone + s.write(recvMsg{err: io.EOF}) } if timeoutSet { s.ctx, s.cancel = context.WithTimeout(ctx, timeout) diff --git a/vendor/google.golang.org/grpc/internal/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go index c34975ff..faa42f8c 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -300,24 +300,29 @@ func decodeGrpcMessageUnchecked(msg string) string { type bufWriter struct { pool *imem.SimpleBufferPool - buf []byte + bufHandle *[]byte offset int batchSize int conn io.Writer err error } +// unsharedBufWriter keeps the unshared slice header in the writer allocation. +type unsharedBufWriter struct { + bufWriter + buf []byte +} + func newBufWriter(conn io.Writer, batchSize int, pool *imem.SimpleBufferPool) *bufWriter { - w := &bufWriter{ - batchSize: batchSize, - conn: conn, - pool: pool, - } - // this indicates that we should use non shared buf - if pool == nil { - w.buf = make([]byte, batchSize) + if pool == nil && batchSize > 0 { + w := &unsharedBufWriter{ + bufWriter: bufWriter{batchSize: batchSize, conn: conn}, + buf: make([]byte, batchSize), + } + w.bufHandle = &w.buf + return &w.bufWriter } - return w + return &bufWriter{batchSize: batchSize, conn: conn, pool: pool} } func (w *bufWriter) Write(b []byte) (int, error) { @@ -328,13 +333,13 @@ func (w *bufWriter) Write(b []byte) (int, error) { n, err := w.conn.Write(b) return n, toIOError(err) } - if w.buf == nil { - b := w.pool.Get(w.batchSize) - w.buf = *b + if w.bufHandle == nil { + w.bufHandle = w.pool.Get(w.batchSize) } + buf := *w.bufHandle written := 0 for len(b) > 0 { - copied := copy(w.buf[w.offset:], b) + copied := copy(buf[w.offset:], b) b = b[copied:] written += copied w.offset += copied @@ -350,15 +355,17 @@ func (w *bufWriter) Write(b []byte) (int, error) { func (w *bufWriter) Flush() error { err := w.flushKeepBuffer() - // Only release the buffer if we are in a "shared" mode - if w.buf != nil && w.pool != nil { - b := w.buf - w.pool.Put(&b) - w.buf = nil - } + w.releaseBuffer() return err } +func (w *bufWriter) releaseBuffer() { + if w.pool != nil && w.bufHandle != nil { + w.pool.Put(w.bufHandle) + w.bufHandle = nil + } +} + func (w *bufWriter) flushKeepBuffer() error { if w.err != nil { return w.err @@ -366,9 +373,13 @@ func (w *bufWriter) flushKeepBuffer() error { if w.offset == 0 { return nil } - _, w.err = w.conn.Write(w.buf[:w.offset]) + buf := *w.bufHandle + _, w.err = w.conn.Write(buf[:w.offset]) w.err = toIOError(w.err) w.offset = 0 + if w.err != nil { + w.releaseBuffer() + } return w.err } diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 5fc901e5..fc656b36 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -89,10 +89,10 @@ type recvMsg struct { // recvBuffer is an unbounded channel of recvMsg structs. // -// Note: recvBuffer differs from buffer.Unbounded only in the fact that it -// holds a channel of recvMsg structs instead of objects implementing "item" -// interface. recvBuffer is written to much more often and using strict recvMsg -// structs helps avoid allocation in "recvBuffer.put" +// Note: recvBuffer differs from buffer.Unbounded in that it provides in-place +// value initialization (via init) to avoid struct pointer allocations on +// streams, and automatically frees pooled mem.Buffer payloads when stream +// errors occur. type recvBuffer struct { c chan recvMsg mu sync.Mutex @@ -466,15 +466,18 @@ func (s *Stream) ReadMessageHeader(header []byte) (err error) { return er } s.readRequester.requestRead(len(header)) + bytesRead := 0 for len(header) != 0 { n, err := s.trReader.ReadMessageHeader(header) + bytesRead += n header = header[n:] if len(header) == 0 { err = nil } if err != nil { - if n > 0 && err == io.EOF { + if bytesRead > 0 && err == io.EOF { err = io.ErrUnexpectedEOF + s.trReader.er = err } return err } @@ -505,19 +508,22 @@ func (s *Stream) read(n int) (data mem.BufferSlice, err error) { allocCap := min(ceil(n, http2MaxFrameLen), 128) data = make(mem.BufferSlice, 0, allocCap) s.readRequester.requestRead(n) + bytesRead := 0 for n != 0 { buf, err := s.trReader.Read(n) var bufLen int if buf != nil { bufLen = buf.Len() } + bytesRead += bufLen n -= bufLen if n == 0 { err = nil } if err != nil { - if bufLen > 0 && err == io.EOF { + if bytesRead > 0 && err == io.EOF { err = io.ErrUnexpectedEOF + s.trReader.er = err } data.Free() return nil, err diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index d2e15253..2b79204b 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -24,6 +24,7 @@ package metadata // import "google.golang.org/grpc/metadata" import ( "context" "fmt" + "sort" "strings" "google.golang.org/grpc/internal" @@ -90,6 +91,76 @@ func Pairs(kv ...string) MD { return md } +// loggableMetadataKeys is the set of metadata keys whose values are known not +// to carry credentials or other sensitive data, and are therefore safe to print +// verbatim in String. Values for any key not in this set are redacted. Keys are +// in metadata's canonical lowercase form. +// +// The list is intentionally restricted to standardized gRPC and HTTP/2 protocol +// headers. Everything else, including all application-defined keys, is +// censored. +// Note that this list might change as we add/remove support for +// metadata types. +var loggableMetadataKeys = map[string]bool{ + "content-type": true, + "te": true, + "user-agent": true, + "grpc-encoding": true, + "grpc-accept-encoding": true, + "grpc-timeout": true, + "grpc-status": true, + "grpc-message-type": true, + "grpc-previous-rpc-attempts": true, + "grpc-retry-pushback-ms": true, +} + +// String implements fmt.Stringer to allow metadata to be printed when stored in +// a context. +// +// To avoid accidentally leaking credentials or other sensitive data (for +// example via log(md), or by logging a value that happens to contain metadata), +// String reports only keys on an allowlist of standardized, non-sensitive +// protocol headers (see loggableMetadataKeys). Every other key is omitted +// entirely, along with its values, because a key name may itself be sensitive; +// only the number of omitted keys is reported, as "". This is a +// best-effort guard against accidents, not a security boundary: a caller that +// genuinely wants the full contents can still print map[string][]string(md) +// directly. +// +// Note that this only affects verbs that use the Stringer, such as %v and %s. +// The %#v verb prints the underlying map with all values and is not redacted. +// Users should not rely on the output of this method to be stable +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a later +// release. +func (md MD) String() string { + keys := make([]string, 0, len(md)) + for k := range md { + if loggableMetadataKeys[strings.ToLower(k)] { + keys = append(keys, k) + } + } + sort.Strings(keys) + + var sb strings.Builder + sb.WriteString("map[") + for i, k := range keys { + if i > 0 { + sb.WriteByte(' ') + } + fmt.Fprintf(&sb, "%s:%v", k, md[k]) + } + if redacted := len(md) - len(keys); redacted > 0 { + if len(keys) > 0 { + sb.WriteByte(' ') + } + fmt.Fprintf(&sb, "<%d redacted>", redacted) + } + sb.WriteByte(']') + return sb.String() +} + // Len returns the number of items in md. func (md MD) Len() int { return len(md) diff --git a/vendor/google.golang.org/grpc/resolver_wrapper.go b/vendor/google.golang.org/grpc/resolver_wrapper.go index 6e613764..f8b0fd38 100644 --- a/vendor/google.golang.org/grpc/resolver_wrapper.go +++ b/vendor/google.golang.org/grpc/resolver_wrapper.go @@ -188,7 +188,7 @@ func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.P // addChannelzTraceEvent adds a channelz trace event containing the new // state received from resolver implementations. func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { - if !logger.V(0) && !channelz.IsOn() { + if !logger.V(2) && !channelz.IsOn() { return } var updates []string diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index cf0a2067..4ab54115 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -89,6 +89,7 @@ func init() { internal.MetricsRecorderForServer = func(srv *Server) estats.MetricsRecorder { return istats.NewMetricsRecorderList(srv.opts.statsHandlers) } + internal.XDSFilterWrapperOption = xdsFilterWrapperOption } var statusOK = status.New(codes.OK, "") @@ -117,10 +118,8 @@ type ServiceDesc struct { // serviceInfo wraps information about a service. It is very similar to // ServiceDesc and is constructed from it for internal purposes. type serviceInfo struct { - // Contains the implementation for the methods in this service. - serviceImpl any - methods map[string]*MethodDesc - streams map[string]*StreamDesc + serviceImpl any // Implementation for the methods in this service. + streams map[string]*StreamDesc // Streaming descriptors and wrapped unary descriptors for this service. mdata any } @@ -183,6 +182,7 @@ type serverOptions struct { bufferPool mem.BufferPool waitForHandlers bool staticWindowSize bool + streamWrapper func(ServerStream) (ServerStream, error) } var defaultServerOptions = serverOptions{ @@ -663,6 +663,14 @@ func bufferPool(bufferPool mem.BufferPool) ServerOption { }) } +// xdsFilterWrapperOption returns a ServerOption that sets the server-level +// stream wrapper (used internally by xDS server filters). +func xdsFilterWrapperOption(w func(ServerStream) (ServerStream, error)) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.streamWrapper = w + }) +} + // serverWorkerResetThreshold defines how often the stack must be reset. Every // N requests, by spawning a new goroutine in its place, a worker can reset its // stack so that large stacks don't live in memory forever. 2^16 should allow @@ -790,18 +798,22 @@ func (s *Server) register(sd *ServiceDesc, ss any) { } info := &serviceInfo{ serviceImpl: ss, - methods: make(map[string]*MethodDesc), streams: make(map[string]*StreamDesc), mdata: sd.Metadata, } - for i := range sd.Methods { - d := &sd.Methods[i] - info.methods[d.MethodName] = d - } for i := range sd.Streams { d := &sd.Streams[i] info.streams[d.StreamName] = d } + for i := range sd.Methods { + d := &sd.Methods[i] + info.streams[d.MethodName] = &StreamDesc{ + StreamName: d.MethodName, + Handler: s.wrapUnaryHandler(d), + ServerStreams: false, + ClientStreams: false, + } + } s.services[sd.ServiceName] = info } @@ -827,20 +839,26 @@ type ServiceInfo struct { func (s *Server) GetServiceInfo() map[string]ServiceInfo { ret := make(map[string]ServiceInfo) for n, srv := range s.services { - methods := make([]MethodInfo, 0, len(srv.methods)+len(srv.streams)) - for m := range srv.methods { - methods = append(methods, MethodInfo{ - Name: m, - IsClientStream: false, - IsServerStream: false, - }) + methods := make([]MethodInfo, 0, len(srv.streams)) + // Iterate over unary methods first to maintain backward compatibility of order. + for m, d := range srv.streams { + if !d.ClientStreams && !d.ServerStreams { + methods = append(methods, MethodInfo{ + Name: m, + IsClientStream: false, + IsServerStream: false, + }) + } } + // Iterate over streaming methods. for m, d := range srv.streams { - methods = append(methods, MethodInfo{ - Name: m, - IsClientStream: d.ClientStreams, - IsServerStream: d.ServerStreams, - }) + if d.ClientStreams || d.ServerStreams { + methods = append(methods, MethodInfo{ + Name: m, + IsClientStream: d.ClientStreams, + IsServerStream: d.ServerStreams, + }) + } } ret[n] = ServiceInfo{ @@ -1185,42 +1203,6 @@ func (s *Server) incrCallsFailed() { s.channelz.ServerMetrics.CallsFailed.Add(1) } -func (s *Server) sendResponse(ctx context.Context, stream *transport.ServerStream, msg any, cp Compressor, opts *transport.WriteOptions, comp encoding.Compressor) error { - data, err := encode(s.getCodec(stream.ContentSubtype()), msg) - if err != nil { - channelz.Error(logger, s.channelz, "grpc: server failed to encode response: ", err) - return err - } - - compData, pf, err := compress(data, cp, comp, s.opts.bufferPool) - if err != nil { - data.Free() - channelz.Error(logger, s.channelz, "grpc: server failed to compress response: ", err) - return err - } - - hdr, payload := msgHeader(data, compData, pf) - - defer func() { - compData.Free() - data.Free() - // payload does not need to be freed here, it is either data or compData, both of - // which are already freed. - }() - - dataLen := data.Len() - payloadLen := payload.Len() - // TODO(dfawley): should we be checking len(data) instead? - if payloadLen > s.opts.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", payloadLen, s.opts.maxSendMessageSize) - } - err = stream.Write(hdr, payload, opts) - if err == nil && s.statsHandler != nil { - s.statsHandler.HandleRPC(ctx, outPayload(false, msg, dataLen, payloadLen, time.Now())) - } - return err -} - // chainUnaryServerInterceptors chains all unary server interceptors into one. func chainUnaryServerInterceptors(s *Server) { // Prepend opts.unaryInt to the chaining interceptors if it exists, since unaryInt will @@ -1257,300 +1239,6 @@ func getChainUnaryHandler(interceptors []UnaryServerInterceptor, curr int, info } } -func (s *Server) processUnaryRPC(ctx context.Context, stream *transport.ServerStream, info *serviceInfo, md *MethodDesc, trInfo *traceInfo) (err error) { - sh := s.statsHandler - if sh != nil || trInfo != nil || channelz.IsOn() { - if channelz.IsOn() { - s.incrCallsStarted() - } - var statsBegin *stats.Begin - if sh != nil { - statsBegin = &stats.Begin{ - BeginTime: time.Now(), - IsClientStream: false, - IsServerStream: false, - } - sh.HandleRPC(ctx, statsBegin) - } - if trInfo != nil { - trInfo.tr.LazyLog(&trInfo.firstLine, false) - } - // The deferred error handling for tracing, stats handler and channelz are - // combined into one function to reduce stack usage -- a defer takes ~56-64 - // bytes on the stack, so overflowing the stack will require a stack - // re-allocation, which is expensive. - // - // To maintain behavior similar to separate deferred statements, statements - // should be executed in the reverse order. That is, tracing first, stats - // handler second, and channelz last. Note that panics *within* defers will - // lead to different behavior, but that's an acceptable compromise; that - // would be undefined behavior territory anyway. - defer func() { - if trInfo != nil { - if err != nil && err != io.EOF { - trInfo.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) - trInfo.tr.SetError() - } - trInfo.tr.Finish() - } - - if sh != nil { - end := &stats.End{ - BeginTime: statsBegin.BeginTime, - EndTime: time.Now(), - } - if err != nil && err != io.EOF { - end.Error = toRPCErr(err) - } - sh.HandleRPC(ctx, end) - } - - if channelz.IsOn() { - if err != nil && err != io.EOF { - s.incrCallsFailed() - } else { - s.incrCallsSucceeded() - } - } - }() - } - var binlogs []binarylog.MethodLogger - if ml := binarylog.GetMethodLogger(stream.Method()); ml != nil { - binlogs = append(binlogs, ml) - } - if s.opts.binaryLogger != nil { - if ml := s.opts.binaryLogger.GetMethodLogger(stream.Method()); ml != nil { - binlogs = append(binlogs, ml) - } - } - if len(binlogs) != 0 { - md, _ := metadata.FromIncomingContext(ctx) - logEntry := &binarylog.ClientHeader{ - Header: md, - MethodName: stream.Method(), - PeerAddr: nil, - } - if deadline, ok := ctx.Deadline(); ok { - logEntry.Timeout = time.Until(deadline) - if logEntry.Timeout < 0 { - logEntry.Timeout = 0 - } - } - if a := md[":authority"]; len(a) > 0 { - logEntry.Authority = a[0] - } - if peer, ok := peer.FromContext(ctx); ok { - logEntry.PeerAddr = peer.Addr - } - for _, binlog := range binlogs { - binlog.Log(ctx, logEntry) - } - } - - // comp and cp are used for compression. decomp and dc are used for - // decompression. If comp and decomp are both set, they are the same; - // however they are kept separate to ensure that at most one of the - // compressor/decompressor variable pairs are set for use later. - var comp, decomp encoding.Compressor - var cp Compressor - var dc Decompressor - var sendCompressorName string - - // If dc is set and matches the stream's compression, use it. Otherwise, try - // to find a matching registered compressor for decomp. - if rc := stream.RecvCompress(); s.opts.dc != nil && s.opts.dc.Type() == rc { - dc = s.opts.dc - } else if rc != "" && rc != encoding.Identity { - decomp = encoding.GetCompressor(rc) - if decomp == nil { - st := status.Newf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", rc) - stream.WriteStatus(st) - return st.Err() - } - } - - // If cp is set, use it. Otherwise, attempt to compress the response using - // the incoming message compression method. - // - // NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686. - if s.opts.cp != nil { - cp = s.opts.cp - sendCompressorName = cp.Type() - } else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity { - // Legacy compressor not specified; attempt to respond with same encoding. - comp = encoding.GetCompressor(rc) - if comp != nil { - sendCompressorName = comp.Name() - } - } - - if sendCompressorName != "" { - if err := stream.SetSendCompress(sendCompressorName); err != nil { - return status.Errorf(codes.Internal, "grpc: failed to set send compressor: %v", err) - } - } - - var payInfo *payloadInfo - if sh != nil || len(binlogs) != 0 { - payInfo = &payloadInfo{} - defer payInfo.free() - } - - d, err := recvAndDecompress(&parser{r: stream, bufferPool: s.opts.bufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp, true) - if err != nil { - if e := stream.WriteStatus(status.Convert(err)); e != nil { - channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) - } - return err - } - freed := false - dataFree := func() { - if !freed { - d.Free() - freed = true - } - } - defer dataFree() - df := func(v any) error { - defer dataFree() - if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil { - return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err) - } - - if sh != nil { - sh.HandleRPC(ctx, &stats.InPayload{ - RecvTime: time.Now(), - Payload: v, - Length: d.Len(), - WireLength: payInfo.compressedLength + headerLen, - CompressedLength: payInfo.compressedLength, - }) - } - if len(binlogs) != 0 { - cm := &binarylog.ClientMessage{ - Message: d.Materialize(), - } - for _, binlog := range binlogs { - binlog.Log(ctx, cm) - } - } - if trInfo != nil { - trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true) - } - return nil - } - ctx = NewContextWithServerTransportStream(ctx, stream) - reply, appErr := md.Handler(info.serviceImpl, ctx, df, s.opts.unaryInt) - if appErr != nil { - appStatus, ok := status.FromError(appErr) - if !ok { - // Convert non-status application error to a status error with code - // Unknown, but handle context errors specifically. - appStatus = status.FromContextError(appErr) - appErr = appStatus.Err() - } - if trInfo != nil { - trInfo.tr.LazyLog(stringer(appStatus.Message()), true) - trInfo.tr.SetError() - } - if e := stream.WriteStatus(appStatus); e != nil { - channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) - } - if len(binlogs) != 0 { - if h, _ := stream.Header(); h.Len() > 0 { - // Only log serverHeader if there was header. Otherwise it can - // be trailer only. - sh := &binarylog.ServerHeader{ - Header: h, - } - for _, binlog := range binlogs { - binlog.Log(ctx, sh) - } - } - st := &binarylog.ServerTrailer{ - Trailer: stream.Trailer(), - Err: appErr, - } - for _, binlog := range binlogs { - binlog.Log(ctx, st) - } - } - return appErr - } - if trInfo != nil { - trInfo.tr.LazyLog(stringer("OK"), false) - } - opts := &transport.WriteOptions{Last: true} - - // Server handler could have set new compressor by calling SetSendCompressor. - // In case it is set, we need to use it for compressing outbound message. - if stream.SendCompress() != sendCompressorName { - comp = encoding.GetCompressor(stream.SendCompress()) - } - if err := s.sendResponse(ctx, stream, reply, cp, opts, comp); err != nil { - if err == io.EOF { - // The entire stream is done (for unary RPC only). - return err - } - if sts, ok := status.FromError(err); ok { - if e := stream.WriteStatus(sts); e != nil { - channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) - } - } else { - switch st := err.(type) { - case transport.ConnectionError: - // Nothing to do here. - default: - panic(fmt.Sprintf("grpc: Unexpected error (%T) from sendResponse: %v", st, st)) - } - } - if len(binlogs) != 0 { - h, _ := stream.Header() - sh := &binarylog.ServerHeader{ - Header: h, - } - st := &binarylog.ServerTrailer{ - Trailer: stream.Trailer(), - Err: appErr, - } - for _, binlog := range binlogs { - binlog.Log(ctx, sh) - binlog.Log(ctx, st) - } - } - return err - } - if len(binlogs) != 0 { - h, _ := stream.Header() - sh := &binarylog.ServerHeader{ - Header: h, - } - sm := &binarylog.ServerMessage{ - Message: reply, - } - for _, binlog := range binlogs { - binlog.Log(ctx, sh) - binlog.Log(ctx, sm) - } - } - if trInfo != nil { - trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true) - } - // TODO: Should we be logging if writing status failed here, like above? - // Should the logging be in WriteStatus? Should we ignore the WriteStatus - // error or allow the stats handler to see it? - if len(binlogs) != 0 { - st := &binarylog.ServerTrailer{ - Trailer: stream.Trailer(), - Err: appErr, - } - for _, binlog := range binlogs { - binlog.Log(ctx, st) - } - } - return stream.WriteStatus(statusOK) -} - // chainStreamServerInterceptors chains all stream server interceptors into one. func chainStreamServerInterceptors(s *Server) { // Prepend opts.streamInt to the chaining interceptors if it exists, since streamInt will @@ -1587,7 +1275,21 @@ func getChainStreamHandler(interceptors []StreamServerInterceptor, curr int, inf } } -func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.ServerStream, info *serviceInfo, sd *StreamDesc, trInfo *traceInfo) (err error) { +// wrapUnaryHandler converts a standard Unary Method Descriptor into a +// StreamHandler, allowing Unary RPCs to be processed via the same unified +// pipeline as Streaming RPCs. +func (s *Server) wrapUnaryHandler(md *MethodDesc) StreamHandler { + return func(srv any, stream ServerStream) error { + df := func(v any) error { return stream.RecvMsg(v) } + reply, err := md.Handler(srv, stream.Context(), df, s.opts.unaryInt) + if err != nil { + return err + } + return stream.SendMsg(reply) + } +} + +func (s *Server) processRPC(ctx context.Context, stream *transport.ServerStream, info *serviceInfo, sd *StreamDesc, trInfo *traceInfo) (err error) { if channelz.IsOn() { s.incrCallsStarted() } @@ -1615,7 +1317,16 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv } if sh != nil || trInfo != nil || channelz.IsOn() { - // See comment in processUnaryRPC on defers. + // The deferred error handling for tracing, stats handler and channelz are + // combined into one function to reduce stack usage -- a defer takes ~56-64 + // bytes on the stack, so overflowing the stack will require a stack + // re-allocation, which is expensive. + // + // To maintain behavior similar to separate deferred statements, statements + // should be executed in the reverse order. That is, tracing first, stats + // handler second, and channelz last. Note that panics *within* defers will + // lead to different behavior, but that's an acceptable compromise; that + // would be undefined behavior territory anyway. defer func() { if trInfo != nil { ss.mu.Lock() @@ -1689,7 +1400,7 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv ss.decompressorV1 = encoding.GetCompressor(rc) if ss.decompressorV1 == nil { st := status.Newf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", rc) - ss.s.WriteStatus(st) + ss.writeStatus(st) return st.Err() } } @@ -1717,23 +1428,34 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv ss.ctx = newContextWithRPCInfo(ss.ctx, false, ss.codec, ss.compressorV0, ss.compressorV1) - if trInfo != nil { - trInfo.tr.LazyLog(&trInfo.firstLine, false) - } + // Execute the xDS HTTP filter interceptors. var appErr error - var server any - if info != nil { - server = info.serviceImpl + var wrappedStream ServerStream = ss + if s.opts.streamWrapper != nil { + wrappedStream, appErr = s.opts.streamWrapper(ss) } - if s.opts.streamInt == nil { - appErr = sd.Handler(server, ss) - } else { - info := &StreamServerInfo{ - FullMethod: stream.Method(), - IsClientStream: sd.ClientStreams, - IsServerStream: sd.ServerStreams, + + if appErr == nil { + if trInfo != nil { + trInfo.tr.LazyLog(&trInfo.firstLine, false) + } + var server any + if info != nil { + server = info.serviceImpl + } + if s.opts.streamInt == nil || (!sd.ClientStreams && !sd.ServerStreams) { + // If there is no stream interceptor, or if this is a unary RPC, call + // the handler directly. The wrapped unary handler will call the unary + // interceptor if it exists. + appErr = sd.Handler(server, wrappedStream) + } else { + info := &StreamServerInfo{ + FullMethod: stream.Method(), + IsClientStream: sd.ClientStreams, + IsServerStream: sd.ServerStreams, + } + appErr = s.opts.streamInt(server, wrappedStream, info, sd.Handler) } - appErr = s.opts.streamInt(server, ss, info, sd.Handler) } if appErr != nil { appStatus, ok := status.FromError(appErr) @@ -1750,6 +1472,17 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv ss.mu.Unlock() } if len(ss.binlogs) != 0 { + if !ss.serverHeaderBinlogged { + if h, _ := ss.s.Header(); h.Len() > 0 { + sh := &binarylog.ServerHeader{ + Header: h, + } + ss.serverHeaderBinlogged = true + for _, binlog := range ss.binlogs { + binlog.Log(ctx, sh) + } + } + } st := &binarylog.ServerTrailer{ Trailer: ss.s.Trailer(), Err: appErr, @@ -1758,8 +1491,9 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv binlog.Log(ctx, st) } } - ss.s.WriteStatus(appStatus) - // TODO: Should we log an error from WriteStatus here and below? + if err := ss.writeStatus(appStatus); err != nil { + channelz.Warningf(logger, s.channelz, "grpc: Server.processRPC failed to write status: %v", err) + } return appErr } if trInfo != nil { @@ -1776,7 +1510,10 @@ func (s *Server) processStreamingRPC(ctx context.Context, stream *transport.Serv binlog.Log(ctx, st) } } - return ss.s.WriteStatus(statusOK) + if err := ss.writeStatus(statusOK); err != nil { + channelz.Warningf(logger, s.channelz, "grpc: Server.processRPC failed to write status: %v", err) + } + return err } func (s *Server) handleMalformedMethodName(stream *transport.ServerStream, ti *traceInfo) { @@ -1854,18 +1591,14 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Ser srv, knownService := s.services[service] if knownService { - if md, ok := srv.methods[method]; ok { - s.processUnaryRPC(ctx, stream, srv, md, ti) - return - } if sd, ok := srv.streams[method]; ok { - s.processStreamingRPC(ctx, stream, srv, sd, ti) + s.processRPC(ctx, stream, srv, sd, ti) return } } // Unknown service, or known server unknown method. if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil { - s.processStreamingRPC(ctx, stream, nil, unknownDesc, ti) + s.processRPC(ctx, stream, nil, unknownDesc, ti) return } var errDesc string @@ -2069,9 +1802,6 @@ func (s *Server) isRegisteredMethod(serviceMethod string) bool { method := serviceMethod[pos+1:] srv, knownService := s.services[service] if knownService { - if _, ok := srv.methods[method]; ok { - return true - } if _, ok := srv.streams[method]; ok { return true } diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 51aff85d..52e59f2c 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -28,6 +28,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" "google.golang.org/grpc/balancer" @@ -148,6 +149,94 @@ type ClientStream interface { RecvMsg(m any) error } +// clientStreamWrapper wraps a ClientStream and handles SendMsg, CloseSend, and +// RecvMsg parities based on the nature of stream. +type clientStreamWrapper struct { + ClientStream + desc *StreamDesc + closeSendCalled atomic.Bool +} + +// CloseSend closes the send direction of the stream. The implementation ensures +// that CloseSend is only called once on the underlying ClientStream, even if +// CloseSend is called multiple times on the wrapper. +func (w *clientStreamWrapper) CloseSend() error { + if w.closeSendCalled.Swap(true) { + return nil + } + return w.ClientStream.CloseSend() +} + +// SendMsg sends message m across the stream. For RPCs where client can call +// SendMsg only once, i.e. only server-streaming RPCs, it converts io.EOF to nil +// and immediately calls CloseSend to trigger any interceptor hooks. +func (w *clientStreamWrapper) SendMsg(m any) error { + err := w.ClientStream.SendMsg(m) + // If the RPC is a client-streaming RPC, the client can send multiple + // messages. In this case, the client should handle any type of + // error,including io.EOF and call CloseSend once it is done sending messages. + if w.desc.ClientStreams { + return err + } + + if err == io.EOF { + // For non-client-streaming RPCs, we return nil instead of EOF on error + // because the generated code requires it. finish is not called; RecvMsg() + // will call it with the stream's status independently. + return nil + } + if err != nil { + return err + } + // In some scenarios (e.g., xDS), the same interceptors process both unary and + // streaming RPCs, relying on CloseSend to signal that no more messages are on + // the way. Although protobuf-generated stubs already invoke CloseSend for + // server-streaming RPCs, it is explicitly called here to ensure downstream + // interceptors are also notified when callers interact with the ClientStream + // API directly. + if err := w.CloseSend(); err != nil && err != io.EOF { + return err + } + return nil + +} + +// RecvMsg receives message m from the stream. For RPCs that call RecvMsg only +// once i.e. only client streaming RPCs, it calls the underlying RecvMsg a +// second time after receiving the first message to get the trailers. +func (w *clientStreamWrapper) RecvMsg(m any) error { + err := w.ClientStream.RecvMsg(m) + if err != nil { + return err + } + if w.desc.ServerStreams { + return nil + } + // Call RecvMsg again for non-server streaming RPCs to get the trailers and + // ensure RPC has completed successfully. + err = w.ClientStream.RecvMsg(m) + if err == io.EOF { + return nil + } + if err == nil { + return status.Error(codes.Internal, "cardinality violation: expected for non server-streaming RPCs, but received another message") + } + return err +} + +// defaultStreamInterceptor is a StreamClientInterceptor which wraps the +// ClientStream and is always invoked as the first interceptor. It consolidates +// behavior for different RPC types at the level closest to the application, +// which simplifies the underlying stream implementation and other interceptors +// by avoiding duplicate or scattered handling. +func defaultStreamInterceptor(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error) { + cs, err := streamer(ctx, desc, cc, method, opts...) + if err != nil { + return nil, err + } + return &clientStreamWrapper{ClientStream: cs, desc: desc}, nil +} + // NewStream creates a new Stream for the client side. This is typically // called by generated code. ctx is used for the lifetime of the stream. // @@ -253,14 +342,11 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth mc := &emptyMethodConfig var onCommit func() - newStream := func(ctx context.Context, filterOpts ...CallOption) (ClientStream, error) { - if filterOpts != nil { - opts = combine(opts, filterOpts) - } + newStream := func(ctx context.Context, opts ...CallOption) (ClientStream, error) { return newClientStreamWithParams(ctx, desc, cc, method, mc, onCommit, nameResolutionDelayed, opts...) } - rpcInfo := iresolver.RPCInfo{Context: ctx, Method: method} + rpcInfo := iresolver.RPCInfo{Context: ctx, Method: method, Authority: cc.authority} rpcConfig, err := cc.safeConfigSelector.SelectConfig(rpcInfo) if err != nil { if st, ok := status.FromError(err); ok { @@ -278,13 +364,23 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth ctx = rpcConfig.Context } mc = &rpcConfig.MethodConfig - onCommit = rpcConfig.OnCommitted + + if rpcConfig.OnCommitted != nil { + onCommit = rpcConfig.OnCommitted + // Register an OnFinish CallOption with the OnCommitted callback to + // ensure it is invoked on stream termination, even if the stream + // fails early before committing. Implementations of OnCommitted are + // expected to be idempotent (e.g., guarded by sync.Once), since both + // onCommit and OnFinish may run for a single RPC. + opts = append(opts, OnFinish(func(error) { rpcConfig.OnCommitted() })) + } + if rpcConfig.Interceptor != nil { rpcInfo.Context = nil ns := newStream if interceptor, ok := rpcConfig.Interceptor.(clientInterceptor); ok { - newStream = func(ctx context.Context, filterOpts ...CallOption) (ClientStream, error) { - cs, err := interceptor.NewStream(ctx, rpcInfo, ns, filterOpts...) + newStream = func(ctx context.Context, opts ...CallOption) (ClientStream, error) { + cs, err := interceptor.NewStream(ctx, rpcInfo, ns, opts...) if err != nil { return nil, toRPCErr(err) } @@ -296,7 +392,7 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth } } - return newStream(ctx) + return newStream(ctx, opts...) } func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, mc *serviceconfig.MethodConfig, onCommit func(), nameResolutionDelayed bool, opts ...CallOption) (_ ClientStream, err error) { @@ -543,6 +639,9 @@ func (a *csAttempt) newStream() error { // maintained in it are local to the attempt. When the attempt has to be // retried, a new instance of csAttempt will be created. if a.pickResult.Metadata != nil { + if err := imetadata.Validate(a.pickResult.Metadata); err != nil { + return status.Error(codes.Internal, err.Error()) + } // We currently do not have a function it the metadata package which // merges given metadata with existing metadata in a context. Existing // function `AppendToOutgoingContext()` takes a variadic argument of key @@ -1044,8 +1143,8 @@ func (cs *clientStream) RecvMsg(m any) error { binlog.Log(cs.ctx, sm) } } - if err != nil || !cs.desc.ServerStreams { - // err != nil or non-server-streaming indicates end of stream. + if err != nil { + // err != nil indicates end of stream. cs.finish(err) } return err @@ -1093,7 +1192,8 @@ func (cs *clientStream) finish(err error) { } cs.finished = true cs.commitAttemptLocked() - if cs.attempt != nil { + attemptCreated := cs.attempt != nil + if attemptCreated { cs.attempt.finish(err) // after functions all rely upon having a stream. if cs.attempt.transportStream != nil { @@ -1131,7 +1231,13 @@ func (cs *clientStream) finish(err error) { if err == nil { cs.retryThrottler.successfulRPC() } - endOfClientStream(cs.cc, err, cs.opts...) + // If no attempt was ever created, stream creation has failed, and the + // cleanup is left to newClientStream, whose deferred cleanup invokes + // endOfClientStream if the call fails. Invoking it here as well would + // run the cleanup twice for the same call. + if attemptCreated { + endOfClientStream(cs.cc, err, cs.opts...) + } cs.cancel() } @@ -1145,12 +1251,6 @@ func (a *csAttempt) sendMsg(m any, hdr []byte, payld mem.BufferSlice, dataLength a.mu.Unlock() } if err := a.transportStream.Write(hdr, payld, &transport.WriteOptions{Last: !cs.desc.ClientStreams}); err != nil { - if !cs.desc.ClientStreams { - // For non-client-streaming RPCs, we return nil instead of EOF on error - // because the generated code requires it. finish is not called; RecvMsg() - // will call it with the stream's status independently. - return nil - } return io.EOF } if a.statsHandler != nil { @@ -1218,18 +1318,7 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { Length: payInfo.uncompressedBytes.Len(), }) } - if cs.desc.ServerStreams { - // Subsequent messages should be received by subsequent RecvMsg calls. - return nil - } - // Special handling for non-server-stream rpcs. - // This recv expects EOF or errors, so we don't collect inPayload. - if err := recv(&a.parser, cs.codec, a.transportStream, a.decompressorV0, m, *cs.callInfo.maxReceiveMessageSize, nil, a.decompressorV1, false); err == io.EOF { - return a.transportStream.Status().Err() // non-server streaming Recv returns nil on success - } else if err != nil { - return toRPCErr(err) - } - return status.Error(codes.Internal, "cardinality violation: expected for non server-streaming RPCs, but received another message") + return nil } func (a *csAttempt) finish(err error) { @@ -1399,7 +1488,7 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin } }() } - return as, nil + return &clientStreamWrapper{ClientStream: as, desc: desc}, nil } type addrConnStream struct { @@ -1497,12 +1586,6 @@ func (as *addrConnStream) SendMsg(m any) (err error) { } if err := as.transportStream.Write(hdr, payload, &transport.WriteOptions{Last: !as.desc.ClientStreams}); err != nil { - if !as.desc.ClientStreams { - // For non-client-streaming RPCs, we return nil instead of EOF on error - // because the generated code requires it. finish is not called; RecvMsg() - // will call it with the stream's status independently. - return nil - } return io.EOF } @@ -1511,8 +1594,8 @@ func (as *addrConnStream) SendMsg(m any) (err error) { func (as *addrConnStream) RecvMsg(m any) (err error) { defer func() { - if err != nil || !as.desc.ServerStreams { - // err != nil or non-server-streaming indicates end of stream. + if err != nil { + // err != nil indicates end of stream. as.finish(err) } }() @@ -1551,20 +1634,7 @@ func (as *addrConnStream) RecvMsg(m any) (err error) { return toRPCErr(err) } as.receivedFirstMsg = true - - if as.desc.ServerStreams { - // Subsequent messages should be received by subsequent RecvMsg calls. - return nil - } - - // Special handling for non-server-stream rpcs. - // This recv expects EOF or errors, so we don't collect inPayload. - if err := recv(&as.parser, as.codec, as.transportStream, as.decompressorV0, m, *as.callInfo.maxReceiveMessageSize, nil, as.decompressorV1, false); err == io.EOF { - return as.transportStream.Status().Err() // non-server streaming Recv returns nil on success - } else if err != nil { - return toRPCErr(err) - } - return status.Error(codes.Internal, "cardinality violation: expected for non server-streaming RPCs, but received another message") + return nil } func (as *addrConnStream) finish(err error) { @@ -1675,6 +1745,8 @@ type serverStream struct { // synchronized. serverHeaderBinlogged bool + statusWritten atomic.Bool // True if status has been written to the transport. + mu sync.Mutex // protects trInfo.tr after the service handler runs. } @@ -1723,6 +1795,16 @@ func (ss *serverStream) SetTrailer(md metadata.MD) { ss.s.SetTrailer(md) } +// writeStatus sends the status of a stream to the client. It uses an atomic +// CAS to guarantee that the status is written to the transport exactly once, +// even if called concurrently. +func (ss *serverStream) writeStatus(st *status.Status) error { + if !ss.statusWritten.CompareAndSwap(false, true) { + return nil + } + return ss.s.WriteStatus(st) +} + func (ss *serverStream) SendMsg(m any) (err error) { defer func() { if ss.trInfo != nil { @@ -1739,7 +1821,7 @@ func (ss *serverStream) SendMsg(m any) (err error) { } if err != nil && err != io.EOF { st, _ := status.FromError(toRPCErr(err)) - ss.s.WriteStatus(st) + ss.writeStatus(st) // Non-user specified status was sent out. This should be an error // case (as a server side Cancel maybe). // @@ -1822,7 +1904,7 @@ func (ss *serverStream) RecvMsg(m any) (err error) { } if err != nil && err != io.EOF { st, _ := status.FromError(toRPCErr(err)) - ss.s.WriteStatus(st) + ss.writeStatus(st) // Non-user specified status was sent out. This should be an error // case (as a server side Cancel maybe). // diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 835dc07f..75f8ef50 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.83.2" +const Version = "1.84.0" diff --git a/vendor/gopkg.in/yaml.v3/LICENSE b/vendor/gopkg.in/yaml.v3/LICENSE deleted file mode 100644 index 2683e4bb..00000000 --- a/vendor/gopkg.in/yaml.v3/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ - -This project is covered by two different licenses: MIT and Apache. - -#### MIT License #### - -The following files were ported to Go from C files of libyaml, and thus -are still covered by their original MIT license, with the additional -copyright staring in 2011 when the project was ported over: - - apic.go emitterc.go parserc.go readerc.go scannerc.go - writerc.go yamlh.go yamlprivateh.go - -Copyright (c) 2006-2010 Kirill Simonov -Copyright (c) 2006-2011 Kirill Simonov - -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. - -### Apache License ### - -All the remaining project files are covered by the Apache license: - -Copyright (c) 2011-2019 Canonical Ltd - -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/gopkg.in/yaml.v3/README.md b/vendor/gopkg.in/yaml.v3/README.md deleted file mode 100644 index 08eb1bab..00000000 --- a/vendor/gopkg.in/yaml.v3/README.md +++ /dev/null @@ -1,150 +0,0 @@ -# YAML support for the Go language - -Introduction ------------- - -The yaml package enables Go programs to comfortably encode and decode YAML -values. It was developed within [Canonical](https://www.canonical.com) as -part of the [juju](https://juju.ubuntu.com) project, and is based on a -pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) -C library to parse and generate YAML data quickly and reliably. - -Compatibility -------------- - -The yaml package supports most of YAML 1.2, but preserves some behavior -from 1.1 for backwards compatibility. - -Specifically, as of v3 of the yaml package: - - - YAML 1.1 bools (_yes/no, on/off_) are supported as long as they are being - decoded into a typed bool value. Otherwise they behave as a string. Booleans - in YAML 1.2 are _true/false_ only. - - Octals encode and decode as _0777_ per YAML 1.1, rather than _0o777_ - as specified in YAML 1.2, because most parsers still use the old format. - Octals in the _0o777_ format are supported though, so new files work. - - Does not support base-60 floats. These are gone from YAML 1.2, and were - actually never supported by this package as it's clearly a poor choice. - -and offers backwards -compatibility with YAML 1.1 in some cases. -1.2, including support for -anchors, tags, map merging, etc. Multi-document unmarshalling is not yet -implemented, and base-60 floats from YAML 1.1 are purposefully not -supported since they're a poor design and are gone in YAML 1.2. - -Installation and usage ----------------------- - -The import path for the package is *gopkg.in/yaml.v3*. - -To install it, run: - - go get gopkg.in/yaml.v3 - -API documentation ------------------ - -If opened in a browser, the import path itself leads to the API documentation: - - - [https://gopkg.in/yaml.v3](https://gopkg.in/yaml.v3) - -API stability -------------- - -The package API for yaml v3 will remain stable as described in [gopkg.in](https://gopkg.in). - - -License -------- - -The yaml package is licensed under the MIT and Apache License 2.0 licenses. -Please see the LICENSE file for details. - - -Example -------- - -```Go -package main - -import ( - "fmt" - "log" - - "gopkg.in/yaml.v3" -) - -var data = ` -a: Easy! -b: - c: 2 - d: [3, 4] -` - -// Note: struct fields must be public in order for unmarshal to -// correctly populate the data. -type T struct { - A string - B struct { - RenamedC int `yaml:"c"` - D []int `yaml:",flow"` - } -} - -func main() { - t := T{} - - err := yaml.Unmarshal([]byte(data), &t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t:\n%v\n\n", t) - - d, err := yaml.Marshal(&t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t dump:\n%s\n\n", string(d)) - - m := make(map[interface{}]interface{}) - - err = yaml.Unmarshal([]byte(data), &m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m:\n%v\n\n", m) - - d, err = yaml.Marshal(&m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m dump:\n%s\n\n", string(d)) -} -``` - -This example will generate the following output: - -``` ---- t: -{Easy! {2 [3 4]}} - ---- t dump: -a: Easy! -b: - c: 2 - d: [3, 4] - - ---- m: -map[a:Easy! b:map[c:2 d:[3 4]]] - ---- m dump: -a: Easy! -b: - c: 2 - d: - - 3 - - 4 -``` - diff --git a/vendor/gopkg.in/yaml.v3/apic.go b/vendor/gopkg.in/yaml.v3/apic.go deleted file mode 100644 index ae7d049f..00000000 --- a/vendor/gopkg.in/yaml.v3/apic.go +++ /dev/null @@ -1,747 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -import ( - "io" -) - -func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) { - //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens)) - - // Check if we can move the queue at the beginning of the buffer. - if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) { - if parser.tokens_head != len(parser.tokens) { - copy(parser.tokens, parser.tokens[parser.tokens_head:]) - } - parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head] - parser.tokens_head = 0 - } - parser.tokens = append(parser.tokens, *token) - if pos < 0 { - return - } - copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:]) - parser.tokens[parser.tokens_head+pos] = *token -} - -// Create a new parser object. -func yaml_parser_initialize(parser *yaml_parser_t) bool { - *parser = yaml_parser_t{ - raw_buffer: make([]byte, 0, input_raw_buffer_size), - buffer: make([]byte, 0, input_buffer_size), - } - return true -} - -// Destroy a parser object. -func yaml_parser_delete(parser *yaml_parser_t) { - *parser = yaml_parser_t{} -} - -// String read handler. -func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { - if parser.input_pos == len(parser.input) { - return 0, io.EOF - } - n = copy(buffer, parser.input[parser.input_pos:]) - parser.input_pos += n - return n, nil -} - -// Reader read handler. -func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { - return parser.input_reader.Read(buffer) -} - -// Set a string input. -func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) { - if parser.read_handler != nil { - panic("must set the input source only once") - } - parser.read_handler = yaml_string_read_handler - parser.input = input - parser.input_pos = 0 -} - -// Set a file input. -func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) { - if parser.read_handler != nil { - panic("must set the input source only once") - } - parser.read_handler = yaml_reader_read_handler - parser.input_reader = r -} - -// Set the source encoding. -func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) { - if parser.encoding != yaml_ANY_ENCODING { - panic("must set the encoding only once") - } - parser.encoding = encoding -} - -// Create a new emitter object. -func yaml_emitter_initialize(emitter *yaml_emitter_t) { - *emitter = yaml_emitter_t{ - buffer: make([]byte, output_buffer_size), - raw_buffer: make([]byte, 0, output_raw_buffer_size), - states: make([]yaml_emitter_state_t, 0, initial_stack_size), - events: make([]yaml_event_t, 0, initial_queue_size), - best_width: -1, - } -} - -// Destroy an emitter object. -func yaml_emitter_delete(emitter *yaml_emitter_t) { - *emitter = yaml_emitter_t{} -} - -// String write handler. -func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error { - *emitter.output_buffer = append(*emitter.output_buffer, buffer...) - return nil -} - -// yaml_writer_write_handler uses emitter.output_writer to write the -// emitted text. -func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error { - _, err := emitter.output_writer.Write(buffer) - return err -} - -// Set a string output. -func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) { - if emitter.write_handler != nil { - panic("must set the output target only once") - } - emitter.write_handler = yaml_string_write_handler - emitter.output_buffer = output_buffer -} - -// Set a file output. -func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) { - if emitter.write_handler != nil { - panic("must set the output target only once") - } - emitter.write_handler = yaml_writer_write_handler - emitter.output_writer = w -} - -// Set the output encoding. -func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) { - if emitter.encoding != yaml_ANY_ENCODING { - panic("must set the output encoding only once") - } - emitter.encoding = encoding -} - -// Set the canonical output style. -func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) { - emitter.canonical = canonical -} - -// Set the indentation increment. -func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) { - if indent < 2 || indent > 9 { - indent = 2 - } - emitter.best_indent = indent -} - -// Set the preferred line width. -func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) { - if width < 0 { - width = -1 - } - emitter.best_width = width -} - -// Set if unescaped non-ASCII characters are allowed. -func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) { - emitter.unicode = unicode -} - -// Set the preferred line break character. -func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) { - emitter.line_break = line_break -} - -///* -// * Destroy a token object. -// */ -// -//YAML_DECLARE(void) -//yaml_token_delete(yaml_token_t *token) -//{ -// assert(token); // Non-NULL token object expected. -// -// switch (token.type) -// { -// case YAML_TAG_DIRECTIVE_TOKEN: -// yaml_free(token.data.tag_directive.handle); -// yaml_free(token.data.tag_directive.prefix); -// break; -// -// case YAML_ALIAS_TOKEN: -// yaml_free(token.data.alias.value); -// break; -// -// case YAML_ANCHOR_TOKEN: -// yaml_free(token.data.anchor.value); -// break; -// -// case YAML_TAG_TOKEN: -// yaml_free(token.data.tag.handle); -// yaml_free(token.data.tag.suffix); -// break; -// -// case YAML_SCALAR_TOKEN: -// yaml_free(token.data.scalar.value); -// break; -// -// default: -// break; -// } -// -// memset(token, 0, sizeof(yaml_token_t)); -//} -// -///* -// * Check if a string is a valid UTF-8 sequence. -// * -// * Check 'reader.c' for more details on UTF-8 encoding. -// */ -// -//static int -//yaml_check_utf8(yaml_char_t *start, size_t length) -//{ -// yaml_char_t *end = start+length; -// yaml_char_t *pointer = start; -// -// while (pointer < end) { -// unsigned char octet; -// unsigned int width; -// unsigned int value; -// size_t k; -// -// octet = pointer[0]; -// width = (octet & 0x80) == 0x00 ? 1 : -// (octet & 0xE0) == 0xC0 ? 2 : -// (octet & 0xF0) == 0xE0 ? 3 : -// (octet & 0xF8) == 0xF0 ? 4 : 0; -// value = (octet & 0x80) == 0x00 ? octet & 0x7F : -// (octet & 0xE0) == 0xC0 ? octet & 0x1F : -// (octet & 0xF0) == 0xE0 ? octet & 0x0F : -// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; -// if (!width) return 0; -// if (pointer+width > end) return 0; -// for (k = 1; k < width; k ++) { -// octet = pointer[k]; -// if ((octet & 0xC0) != 0x80) return 0; -// value = (value << 6) + (octet & 0x3F); -// } -// if (!((width == 1) || -// (width == 2 && value >= 0x80) || -// (width == 3 && value >= 0x800) || -// (width == 4 && value >= 0x10000))) return 0; -// -// pointer += width; -// } -// -// return 1; -//} -// - -// Create STREAM-START. -func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) { - *event = yaml_event_t{ - typ: yaml_STREAM_START_EVENT, - encoding: encoding, - } -} - -// Create STREAM-END. -func yaml_stream_end_event_initialize(event *yaml_event_t) { - *event = yaml_event_t{ - typ: yaml_STREAM_END_EVENT, - } -} - -// Create DOCUMENT-START. -func yaml_document_start_event_initialize( - event *yaml_event_t, - version_directive *yaml_version_directive_t, - tag_directives []yaml_tag_directive_t, - implicit bool, -) { - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - version_directive: version_directive, - tag_directives: tag_directives, - implicit: implicit, - } -} - -// Create DOCUMENT-END. -func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) { - *event = yaml_event_t{ - typ: yaml_DOCUMENT_END_EVENT, - implicit: implicit, - } -} - -// Create ALIAS. -func yaml_alias_event_initialize(event *yaml_event_t, anchor []byte) bool { - *event = yaml_event_t{ - typ: yaml_ALIAS_EVENT, - anchor: anchor, - } - return true -} - -// Create SCALAR. -func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool { - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - anchor: anchor, - tag: tag, - value: value, - implicit: plain_implicit, - quoted_implicit: quoted_implicit, - style: yaml_style_t(style), - } - return true -} - -// Create SEQUENCE-START. -func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool { - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(style), - } - return true -} - -// Create SEQUENCE-END. -func yaml_sequence_end_event_initialize(event *yaml_event_t) bool { - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - } - return true -} - -// Create MAPPING-START. -func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) { - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(style), - } -} - -// Create MAPPING-END. -func yaml_mapping_end_event_initialize(event *yaml_event_t) { - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - } -} - -// Destroy an event object. -func yaml_event_delete(event *yaml_event_t) { - *event = yaml_event_t{} -} - -///* -// * Create a document object. -// */ -// -//YAML_DECLARE(int) -//yaml_document_initialize(document *yaml_document_t, -// version_directive *yaml_version_directive_t, -// tag_directives_start *yaml_tag_directive_t, -// tag_directives_end *yaml_tag_directive_t, -// start_implicit int, end_implicit int) -//{ -// struct { -// error yaml_error_type_t -// } context -// struct { -// start *yaml_node_t -// end *yaml_node_t -// top *yaml_node_t -// } nodes = { NULL, NULL, NULL } -// version_directive_copy *yaml_version_directive_t = NULL -// struct { -// start *yaml_tag_directive_t -// end *yaml_tag_directive_t -// top *yaml_tag_directive_t -// } tag_directives_copy = { NULL, NULL, NULL } -// value yaml_tag_directive_t = { NULL, NULL } -// mark yaml_mark_t = { 0, 0, 0 } -// -// assert(document) // Non-NULL document object is expected. -// assert((tag_directives_start && tag_directives_end) || -// (tag_directives_start == tag_directives_end)) -// // Valid tag directives are expected. -// -// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error -// -// if (version_directive) { -// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)) -// if (!version_directive_copy) goto error -// version_directive_copy.major = version_directive.major -// version_directive_copy.minor = version_directive.minor -// } -// -// if (tag_directives_start != tag_directives_end) { -// tag_directive *yaml_tag_directive_t -// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) -// goto error -// for (tag_directive = tag_directives_start -// tag_directive != tag_directives_end; tag_directive ++) { -// assert(tag_directive.handle) -// assert(tag_directive.prefix) -// if (!yaml_check_utf8(tag_directive.handle, -// strlen((char *)tag_directive.handle))) -// goto error -// if (!yaml_check_utf8(tag_directive.prefix, -// strlen((char *)tag_directive.prefix))) -// goto error -// value.handle = yaml_strdup(tag_directive.handle) -// value.prefix = yaml_strdup(tag_directive.prefix) -// if (!value.handle || !value.prefix) goto error -// if (!PUSH(&context, tag_directives_copy, value)) -// goto error -// value.handle = NULL -// value.prefix = NULL -// } -// } -// -// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, -// tag_directives_copy.start, tag_directives_copy.top, -// start_implicit, end_implicit, mark, mark) -// -// return 1 -// -//error: -// STACK_DEL(&context, nodes) -// yaml_free(version_directive_copy) -// while (!STACK_EMPTY(&context, tag_directives_copy)) { -// value yaml_tag_directive_t = POP(&context, tag_directives_copy) -// yaml_free(value.handle) -// yaml_free(value.prefix) -// } -// STACK_DEL(&context, tag_directives_copy) -// yaml_free(value.handle) -// yaml_free(value.prefix) -// -// return 0 -//} -// -///* -// * Destroy a document object. -// */ -// -//YAML_DECLARE(void) -//yaml_document_delete(document *yaml_document_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// tag_directive *yaml_tag_directive_t -// -// context.error = YAML_NO_ERROR // Eliminate a compiler warning. -// -// assert(document) // Non-NULL document object is expected. -// -// while (!STACK_EMPTY(&context, document.nodes)) { -// node yaml_node_t = POP(&context, document.nodes) -// yaml_free(node.tag) -// switch (node.type) { -// case YAML_SCALAR_NODE: -// yaml_free(node.data.scalar.value) -// break -// case YAML_SEQUENCE_NODE: -// STACK_DEL(&context, node.data.sequence.items) -// break -// case YAML_MAPPING_NODE: -// STACK_DEL(&context, node.data.mapping.pairs) -// break -// default: -// assert(0) // Should not happen. -// } -// } -// STACK_DEL(&context, document.nodes) -// -// yaml_free(document.version_directive) -// for (tag_directive = document.tag_directives.start -// tag_directive != document.tag_directives.end -// tag_directive++) { -// yaml_free(tag_directive.handle) -// yaml_free(tag_directive.prefix) -// } -// yaml_free(document.tag_directives.start) -// -// memset(document, 0, sizeof(yaml_document_t)) -//} -// -///** -// * Get a document node. -// */ -// -//YAML_DECLARE(yaml_node_t *) -//yaml_document_get_node(document *yaml_document_t, index int) -//{ -// assert(document) // Non-NULL document object is expected. -// -// if (index > 0 && document.nodes.start + index <= document.nodes.top) { -// return document.nodes.start + index - 1 -// } -// return NULL -//} -// -///** -// * Get the root object. -// */ -// -//YAML_DECLARE(yaml_node_t *) -//yaml_document_get_root_node(document *yaml_document_t) -//{ -// assert(document) // Non-NULL document object is expected. -// -// if (document.nodes.top != document.nodes.start) { -// return document.nodes.start -// } -// return NULL -//} -// -///* -// * Add a scalar node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_scalar(document *yaml_document_t, -// tag *yaml_char_t, value *yaml_char_t, length int, -// style yaml_scalar_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// value_copy *yaml_char_t = NULL -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// assert(value) // Non-NULL value is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (length < 0) { -// length = strlen((char *)value) -// } -// -// if (!yaml_check_utf8(value, length)) goto error -// value_copy = yaml_malloc(length+1) -// if (!value_copy) goto error -// memcpy(value_copy, value, length) -// value_copy[length] = '\0' -// -// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// yaml_free(tag_copy) -// yaml_free(value_copy) -// -// return 0 -//} -// -///* -// * Add a sequence node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_sequence(document *yaml_document_t, -// tag *yaml_char_t, style yaml_sequence_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// struct { -// start *yaml_node_item_t -// end *yaml_node_item_t -// top *yaml_node_item_t -// } items = { NULL, NULL, NULL } -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error -// -// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, -// style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// STACK_DEL(&context, items) -// yaml_free(tag_copy) -// -// return 0 -//} -// -///* -// * Add a mapping node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_mapping(document *yaml_document_t, -// tag *yaml_char_t, style yaml_mapping_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// struct { -// start *yaml_node_pair_t -// end *yaml_node_pair_t -// top *yaml_node_pair_t -// } pairs = { NULL, NULL, NULL } -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error -// -// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, -// style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// STACK_DEL(&context, pairs) -// yaml_free(tag_copy) -// -// return 0 -//} -// -///* -// * Append an item to a sequence node. -// */ -// -//YAML_DECLARE(int) -//yaml_document_append_sequence_item(document *yaml_document_t, -// sequence int, item int) -//{ -// struct { -// error yaml_error_type_t -// } context -// -// assert(document) // Non-NULL document is required. -// assert(sequence > 0 -// && document.nodes.start + sequence <= document.nodes.top) -// // Valid sequence id is required. -// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE) -// // A sequence node is required. -// assert(item > 0 && document.nodes.start + item <= document.nodes.top) -// // Valid item id is required. -// -// if (!PUSH(&context, -// document.nodes.start[sequence-1].data.sequence.items, item)) -// return 0 -// -// return 1 -//} -// -///* -// * Append a pair of a key and a value to a mapping node. -// */ -// -//YAML_DECLARE(int) -//yaml_document_append_mapping_pair(document *yaml_document_t, -// mapping int, key int, value int) -//{ -// struct { -// error yaml_error_type_t -// } context -// -// pair yaml_node_pair_t -// -// assert(document) // Non-NULL document is required. -// assert(mapping > 0 -// && document.nodes.start + mapping <= document.nodes.top) -// // Valid mapping id is required. -// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE) -// // A mapping node is required. -// assert(key > 0 && document.nodes.start + key <= document.nodes.top) -// // Valid key id is required. -// assert(value > 0 && document.nodes.start + value <= document.nodes.top) -// // Valid value id is required. -// -// pair.key = key -// pair.value = value -// -// if (!PUSH(&context, -// document.nodes.start[mapping-1].data.mapping.pairs, pair)) -// return 0 -// -// return 1 -//} -// -// diff --git a/vendor/gopkg.in/yaml.v3/decode.go b/vendor/gopkg.in/yaml.v3/decode.go deleted file mode 100644 index 0173b698..00000000 --- a/vendor/gopkg.in/yaml.v3/decode.go +++ /dev/null @@ -1,1000 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// 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 yaml - -import ( - "encoding" - "encoding/base64" - "fmt" - "io" - "math" - "reflect" - "strconv" - "time" -) - -// ---------------------------------------------------------------------------- -// Parser, produces a node tree out of a libyaml event stream. - -type parser struct { - parser yaml_parser_t - event yaml_event_t - doc *Node - anchors map[string]*Node - doneInit bool - textless bool -} - -func newParser(b []byte) *parser { - p := parser{} - if !yaml_parser_initialize(&p.parser) { - panic("failed to initialize YAML emitter") - } - if len(b) == 0 { - b = []byte{'\n'} - } - yaml_parser_set_input_string(&p.parser, b) - return &p -} - -func newParserFromReader(r io.Reader) *parser { - p := parser{} - if !yaml_parser_initialize(&p.parser) { - panic("failed to initialize YAML emitter") - } - yaml_parser_set_input_reader(&p.parser, r) - return &p -} - -func (p *parser) init() { - if p.doneInit { - return - } - p.anchors = make(map[string]*Node) - p.expect(yaml_STREAM_START_EVENT) - p.doneInit = true -} - -func (p *parser) destroy() { - if p.event.typ != yaml_NO_EVENT { - yaml_event_delete(&p.event) - } - yaml_parser_delete(&p.parser) -} - -// expect consumes an event from the event stream and -// checks that it's of the expected type. -func (p *parser) expect(e yaml_event_type_t) { - if p.event.typ == yaml_NO_EVENT { - if !yaml_parser_parse(&p.parser, &p.event) { - p.fail() - } - } - if p.event.typ == yaml_STREAM_END_EVENT { - failf("attempted to go past the end of stream; corrupted value?") - } - if p.event.typ != e { - p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ) - p.fail() - } - yaml_event_delete(&p.event) - p.event.typ = yaml_NO_EVENT -} - -// peek peeks at the next event in the event stream, -// puts the results into p.event and returns the event type. -func (p *parser) peek() yaml_event_type_t { - if p.event.typ != yaml_NO_EVENT { - return p.event.typ - } - // It's curious choice from the underlying API to generally return a - // positive result on success, but on this case return true in an error - // scenario. This was the source of bugs in the past (issue #666). - if !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR { - p.fail() - } - return p.event.typ -} - -func (p *parser) fail() { - var where string - var line int - if p.parser.context_mark.line != 0 { - line = p.parser.context_mark.line - // Scanner errors don't iterate line before returning error - if p.parser.error == yaml_SCANNER_ERROR { - line++ - } - } else if p.parser.problem_mark.line != 0 { - line = p.parser.problem_mark.line - // Scanner errors don't iterate line before returning error - if p.parser.error == yaml_SCANNER_ERROR { - line++ - } - } - if line != 0 { - where = "line " + strconv.Itoa(line) + ": " - } - var msg string - if len(p.parser.problem) > 0 { - msg = p.parser.problem - } else { - msg = "unknown problem parsing YAML content" - } - failf("%s%s", where, msg) -} - -func (p *parser) anchor(n *Node, anchor []byte) { - if anchor != nil { - n.Anchor = string(anchor) - p.anchors[n.Anchor] = n - } -} - -func (p *parser) parse() *Node { - p.init() - switch p.peek() { - case yaml_SCALAR_EVENT: - return p.scalar() - case yaml_ALIAS_EVENT: - return p.alias() - case yaml_MAPPING_START_EVENT: - return p.mapping() - case yaml_SEQUENCE_START_EVENT: - return p.sequence() - case yaml_DOCUMENT_START_EVENT: - return p.document() - case yaml_STREAM_END_EVENT: - // Happens when attempting to decode an empty buffer. - return nil - case yaml_TAIL_COMMENT_EVENT: - panic("internal error: unexpected tail comment event (please report)") - default: - panic("internal error: attempted to parse unknown event (please report): " + p.event.typ.String()) - } -} - -func (p *parser) node(kind Kind, defaultTag, tag, value string) *Node { - var style Style - if tag != "" && tag != "!" { - tag = shortTag(tag) - style = TaggedStyle - } else if defaultTag != "" { - tag = defaultTag - } else if kind == ScalarNode { - tag, _ = resolve("", value) - } - n := &Node{ - Kind: kind, - Tag: tag, - Value: value, - Style: style, - } - if !p.textless { - n.Line = p.event.start_mark.line + 1 - n.Column = p.event.start_mark.column + 1 - n.HeadComment = string(p.event.head_comment) - n.LineComment = string(p.event.line_comment) - n.FootComment = string(p.event.foot_comment) - } - return n -} - -func (p *parser) parseChild(parent *Node) *Node { - child := p.parse() - parent.Content = append(parent.Content, child) - return child -} - -func (p *parser) document() *Node { - n := p.node(DocumentNode, "", "", "") - p.doc = n - p.expect(yaml_DOCUMENT_START_EVENT) - p.parseChild(n) - if p.peek() == yaml_DOCUMENT_END_EVENT { - n.FootComment = string(p.event.foot_comment) - } - p.expect(yaml_DOCUMENT_END_EVENT) - return n -} - -func (p *parser) alias() *Node { - n := p.node(AliasNode, "", "", string(p.event.anchor)) - n.Alias = p.anchors[n.Value] - if n.Alias == nil { - failf("unknown anchor '%s' referenced", n.Value) - } - p.expect(yaml_ALIAS_EVENT) - return n -} - -func (p *parser) scalar() *Node { - var parsedStyle = p.event.scalar_style() - var nodeStyle Style - switch { - case parsedStyle&yaml_DOUBLE_QUOTED_SCALAR_STYLE != 0: - nodeStyle = DoubleQuotedStyle - case parsedStyle&yaml_SINGLE_QUOTED_SCALAR_STYLE != 0: - nodeStyle = SingleQuotedStyle - case parsedStyle&yaml_LITERAL_SCALAR_STYLE != 0: - nodeStyle = LiteralStyle - case parsedStyle&yaml_FOLDED_SCALAR_STYLE != 0: - nodeStyle = FoldedStyle - } - var nodeValue = string(p.event.value) - var nodeTag = string(p.event.tag) - var defaultTag string - if nodeStyle == 0 { - if nodeValue == "<<" { - defaultTag = mergeTag - } - } else { - defaultTag = strTag - } - n := p.node(ScalarNode, defaultTag, nodeTag, nodeValue) - n.Style |= nodeStyle - p.anchor(n, p.event.anchor) - p.expect(yaml_SCALAR_EVENT) - return n -} - -func (p *parser) sequence() *Node { - n := p.node(SequenceNode, seqTag, string(p.event.tag), "") - if p.event.sequence_style()&yaml_FLOW_SEQUENCE_STYLE != 0 { - n.Style |= FlowStyle - } - p.anchor(n, p.event.anchor) - p.expect(yaml_SEQUENCE_START_EVENT) - for p.peek() != yaml_SEQUENCE_END_EVENT { - p.parseChild(n) - } - n.LineComment = string(p.event.line_comment) - n.FootComment = string(p.event.foot_comment) - p.expect(yaml_SEQUENCE_END_EVENT) - return n -} - -func (p *parser) mapping() *Node { - n := p.node(MappingNode, mapTag, string(p.event.tag), "") - block := true - if p.event.mapping_style()&yaml_FLOW_MAPPING_STYLE != 0 { - block = false - n.Style |= FlowStyle - } - p.anchor(n, p.event.anchor) - p.expect(yaml_MAPPING_START_EVENT) - for p.peek() != yaml_MAPPING_END_EVENT { - k := p.parseChild(n) - if block && k.FootComment != "" { - // Must be a foot comment for the prior value when being dedented. - if len(n.Content) > 2 { - n.Content[len(n.Content)-3].FootComment = k.FootComment - k.FootComment = "" - } - } - v := p.parseChild(n) - if k.FootComment == "" && v.FootComment != "" { - k.FootComment = v.FootComment - v.FootComment = "" - } - if p.peek() == yaml_TAIL_COMMENT_EVENT { - if k.FootComment == "" { - k.FootComment = string(p.event.foot_comment) - } - p.expect(yaml_TAIL_COMMENT_EVENT) - } - } - n.LineComment = string(p.event.line_comment) - n.FootComment = string(p.event.foot_comment) - if n.Style&FlowStyle == 0 && n.FootComment != "" && len(n.Content) > 1 { - n.Content[len(n.Content)-2].FootComment = n.FootComment - n.FootComment = "" - } - p.expect(yaml_MAPPING_END_EVENT) - return n -} - -// ---------------------------------------------------------------------------- -// Decoder, unmarshals a node into a provided value. - -type decoder struct { - doc *Node - aliases map[*Node]bool - terrors []string - - stringMapType reflect.Type - generalMapType reflect.Type - - knownFields bool - uniqueKeys bool - decodeCount int - aliasCount int - aliasDepth int - - mergedFields map[interface{}]bool -} - -var ( - nodeType = reflect.TypeOf(Node{}) - durationType = reflect.TypeOf(time.Duration(0)) - stringMapType = reflect.TypeOf(map[string]interface{}{}) - generalMapType = reflect.TypeOf(map[interface{}]interface{}{}) - ifaceType = generalMapType.Elem() - timeType = reflect.TypeOf(time.Time{}) - ptrTimeType = reflect.TypeOf(&time.Time{}) -) - -func newDecoder() *decoder { - d := &decoder{ - stringMapType: stringMapType, - generalMapType: generalMapType, - uniqueKeys: true, - } - d.aliases = make(map[*Node]bool) - return d -} - -func (d *decoder) terror(n *Node, tag string, out reflect.Value) { - if n.Tag != "" { - tag = n.Tag - } - value := n.Value - if tag != seqTag && tag != mapTag { - if len(value) > 10 { - value = " `" + value[:7] + "...`" - } else { - value = " `" + value + "`" - } - } - d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.Line, shortTag(tag), value, out.Type())) -} - -func (d *decoder) callUnmarshaler(n *Node, u Unmarshaler) (good bool) { - err := u.UnmarshalYAML(n) - if e, ok := err.(*TypeError); ok { - d.terrors = append(d.terrors, e.Errors...) - return false - } - if err != nil { - fail(err) - } - return true -} - -func (d *decoder) callObsoleteUnmarshaler(n *Node, u obsoleteUnmarshaler) (good bool) { - terrlen := len(d.terrors) - err := u.UnmarshalYAML(func(v interface{}) (err error) { - defer handleErr(&err) - d.unmarshal(n, reflect.ValueOf(v)) - if len(d.terrors) > terrlen { - issues := d.terrors[terrlen:] - d.terrors = d.terrors[:terrlen] - return &TypeError{issues} - } - return nil - }) - if e, ok := err.(*TypeError); ok { - d.terrors = append(d.terrors, e.Errors...) - return false - } - if err != nil { - fail(err) - } - return true -} - -// d.prepare initializes and dereferences pointers and calls UnmarshalYAML -// if a value is found to implement it. -// It returns the initialized and dereferenced out value, whether -// unmarshalling was already done by UnmarshalYAML, and if so whether -// its types unmarshalled appropriately. -// -// If n holds a null value, prepare returns before doing anything. -func (d *decoder) prepare(n *Node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { - if n.ShortTag() == nullTag { - return out, false, false - } - again := true - for again { - again = false - if out.Kind() == reflect.Ptr { - if out.IsNil() { - out.Set(reflect.New(out.Type().Elem())) - } - out = out.Elem() - again = true - } - if out.CanAddr() { - outi := out.Addr().Interface() - if u, ok := outi.(Unmarshaler); ok { - good = d.callUnmarshaler(n, u) - return out, true, good - } - if u, ok := outi.(obsoleteUnmarshaler); ok { - good = d.callObsoleteUnmarshaler(n, u) - return out, true, good - } - } - } - return out, false, false -} - -func (d *decoder) fieldByIndex(n *Node, v reflect.Value, index []int) (field reflect.Value) { - if n.ShortTag() == nullTag { - return reflect.Value{} - } - for _, num := range index { - for { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() - continue - } - break - } - v = v.Field(num) - } - return v -} - -const ( - // 400,000 decode operations is ~500kb of dense object declarations, or - // ~5kb of dense object declarations with 10000% alias expansion - alias_ratio_range_low = 400000 - - // 4,000,000 decode operations is ~5MB of dense object declarations, or - // ~4.5MB of dense object declarations with 10% alias expansion - alias_ratio_range_high = 4000000 - - // alias_ratio_range is the range over which we scale allowed alias ratios - alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low) -) - -func allowedAliasRatio(decodeCount int) float64 { - switch { - case decodeCount <= alias_ratio_range_low: - // allow 99% to come from alias expansion for small-to-medium documents - return 0.99 - case decodeCount >= alias_ratio_range_high: - // allow 10% to come from alias expansion for very large documents - return 0.10 - default: - // scale smoothly from 99% down to 10% over the range. - // this maps to 396,000 - 400,000 allowed alias-driven decodes over the range. - // 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps). - return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range) - } -} - -func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) { - d.decodeCount++ - if d.aliasDepth > 0 { - d.aliasCount++ - } - if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) { - failf("document contains excessive aliasing") - } - if out.Type() == nodeType { - out.Set(reflect.ValueOf(n).Elem()) - return true - } - switch n.Kind { - case DocumentNode: - return d.document(n, out) - case AliasNode: - return d.alias(n, out) - } - out, unmarshaled, good := d.prepare(n, out) - if unmarshaled { - return good - } - switch n.Kind { - case ScalarNode: - good = d.scalar(n, out) - case MappingNode: - good = d.mapping(n, out) - case SequenceNode: - good = d.sequence(n, out) - case 0: - if n.IsZero() { - return d.null(out) - } - fallthrough - default: - failf("cannot decode node with unknown kind %d", n.Kind) - } - return good -} - -func (d *decoder) document(n *Node, out reflect.Value) (good bool) { - if len(n.Content) == 1 { - d.doc = n - d.unmarshal(n.Content[0], out) - return true - } - return false -} - -func (d *decoder) alias(n *Node, out reflect.Value) (good bool) { - if d.aliases[n] { - // TODO this could actually be allowed in some circumstances. - failf("anchor '%s' value contains itself", n.Value) - } - d.aliases[n] = true - d.aliasDepth++ - good = d.unmarshal(n.Alias, out) - d.aliasDepth-- - delete(d.aliases, n) - return good -} - -var zeroValue reflect.Value - -func resetMap(out reflect.Value) { - for _, k := range out.MapKeys() { - out.SetMapIndex(k, zeroValue) - } -} - -func (d *decoder) null(out reflect.Value) bool { - if out.CanAddr() { - switch out.Kind() { - case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - out.Set(reflect.Zero(out.Type())) - return true - } - } - return false -} - -func (d *decoder) scalar(n *Node, out reflect.Value) bool { - var tag string - var resolved interface{} - if n.indicatedString() { - tag = strTag - resolved = n.Value - } else { - tag, resolved = resolve(n.Tag, n.Value) - if tag == binaryTag { - data, err := base64.StdEncoding.DecodeString(resolved.(string)) - if err != nil { - failf("!!binary value contains invalid base64 data") - } - resolved = string(data) - } - } - if resolved == nil { - return d.null(out) - } - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { - // We've resolved to exactly the type we want, so use that. - out.Set(resolvedv) - return true - } - // Perhaps we can use the value as a TextUnmarshaler to - // set its value. - if out.CanAddr() { - u, ok := out.Addr().Interface().(encoding.TextUnmarshaler) - if ok { - var text []byte - if tag == binaryTag { - text = []byte(resolved.(string)) - } else { - // We let any value be unmarshaled into TextUnmarshaler. - // That might be more lax than we'd like, but the - // TextUnmarshaler itself should bowl out any dubious values. - text = []byte(n.Value) - } - err := u.UnmarshalText(text) - if err != nil { - fail(err) - } - return true - } - } - switch out.Kind() { - case reflect.String: - if tag == binaryTag { - out.SetString(resolved.(string)) - return true - } - out.SetString(n.Value) - return true - case reflect.Interface: - out.Set(reflect.ValueOf(resolved)) - return true - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - // This used to work in v2, but it's very unfriendly. - isDuration := out.Type() == durationType - - switch resolved := resolved.(type) { - case int: - if !isDuration && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case int64: - if !isDuration && !out.OverflowInt(resolved) { - out.SetInt(resolved) - return true - } - case uint64: - if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case float64: - if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case string: - if out.Type() == durationType { - d, err := time.ParseDuration(resolved) - if err == nil { - out.SetInt(int64(d)) - return true - } - } - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - switch resolved := resolved.(type) { - case int: - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case int64: - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case uint64: - if !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case float64: - if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - } - case reflect.Bool: - switch resolved := resolved.(type) { - case bool: - out.SetBool(resolved) - return true - case string: - // This offers some compatibility with the 1.1 spec (https://yaml.org/type/bool.html). - // It only works if explicitly attempting to unmarshal into a typed bool value. - switch resolved { - case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON": - out.SetBool(true) - return true - case "n", "N", "no", "No", "NO", "off", "Off", "OFF": - out.SetBool(false) - return true - } - } - case reflect.Float32, reflect.Float64: - switch resolved := resolved.(type) { - case int: - out.SetFloat(float64(resolved)) - return true - case int64: - out.SetFloat(float64(resolved)) - return true - case uint64: - out.SetFloat(float64(resolved)) - return true - case float64: - out.SetFloat(resolved) - return true - } - case reflect.Struct: - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { - out.Set(resolvedv) - return true - } - case reflect.Ptr: - panic("yaml internal error: please report the issue") - } - d.terror(n, tag, out) - return false -} - -func settableValueOf(i interface{}) reflect.Value { - v := reflect.ValueOf(i) - sv := reflect.New(v.Type()).Elem() - sv.Set(v) - return sv -} - -func (d *decoder) sequence(n *Node, out reflect.Value) (good bool) { - l := len(n.Content) - - var iface reflect.Value - switch out.Kind() { - case reflect.Slice: - out.Set(reflect.MakeSlice(out.Type(), l, l)) - case reflect.Array: - if l != out.Len() { - failf("invalid array: want %d elements but got %d", out.Len(), l) - } - case reflect.Interface: - // No type hints. Will have to use a generic sequence. - iface = out - out = settableValueOf(make([]interface{}, l)) - default: - d.terror(n, seqTag, out) - return false - } - et := out.Type().Elem() - - j := 0 - for i := 0; i < l; i++ { - e := reflect.New(et).Elem() - if ok := d.unmarshal(n.Content[i], e); ok { - out.Index(j).Set(e) - j++ - } - } - if out.Kind() != reflect.Array { - out.Set(out.Slice(0, j)) - } - if iface.IsValid() { - iface.Set(out) - } - return true -} - -func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) { - l := len(n.Content) - if d.uniqueKeys { - nerrs := len(d.terrors) - for i := 0; i < l; i += 2 { - ni := n.Content[i] - for j := i + 2; j < l; j += 2 { - nj := n.Content[j] - if ni.Kind == nj.Kind && ni.Value == nj.Value { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: mapping key %#v already defined at line %d", nj.Line, nj.Value, ni.Line)) - } - } - } - if len(d.terrors) > nerrs { - return false - } - } - switch out.Kind() { - case reflect.Struct: - return d.mappingStruct(n, out) - case reflect.Map: - // okay - case reflect.Interface: - iface := out - if isStringMap(n) { - out = reflect.MakeMap(d.stringMapType) - } else { - out = reflect.MakeMap(d.generalMapType) - } - iface.Set(out) - default: - d.terror(n, mapTag, out) - return false - } - - outt := out.Type() - kt := outt.Key() - et := outt.Elem() - - stringMapType := d.stringMapType - generalMapType := d.generalMapType - if outt.Elem() == ifaceType { - if outt.Key().Kind() == reflect.String { - d.stringMapType = outt - } else if outt.Key() == ifaceType { - d.generalMapType = outt - } - } - - mergedFields := d.mergedFields - d.mergedFields = nil - - var mergeNode *Node - - mapIsNew := false - if out.IsNil() { - out.Set(reflect.MakeMap(outt)) - mapIsNew = true - } - for i := 0; i < l; i += 2 { - if isMerge(n.Content[i]) { - mergeNode = n.Content[i+1] - continue - } - k := reflect.New(kt).Elem() - if d.unmarshal(n.Content[i], k) { - if mergedFields != nil { - ki := k.Interface() - if mergedFields[ki] { - continue - } - mergedFields[ki] = true - } - kkind := k.Kind() - if kkind == reflect.Interface { - kkind = k.Elem().Kind() - } - if kkind == reflect.Map || kkind == reflect.Slice { - failf("invalid map key: %#v", k.Interface()) - } - e := reflect.New(et).Elem() - if d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) { - out.SetMapIndex(k, e) - } - } - } - - d.mergedFields = mergedFields - if mergeNode != nil { - d.merge(n, mergeNode, out) - } - - d.stringMapType = stringMapType - d.generalMapType = generalMapType - return true -} - -func isStringMap(n *Node) bool { - if n.Kind != MappingNode { - return false - } - l := len(n.Content) - for i := 0; i < l; i += 2 { - shortTag := n.Content[i].ShortTag() - if shortTag != strTag && shortTag != mergeTag { - return false - } - } - return true -} - -func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) { - sinfo, err := getStructInfo(out.Type()) - if err != nil { - panic(err) - } - - var inlineMap reflect.Value - var elemType reflect.Type - if sinfo.InlineMap != -1 { - inlineMap = out.Field(sinfo.InlineMap) - elemType = inlineMap.Type().Elem() - } - - for _, index := range sinfo.InlineUnmarshalers { - field := d.fieldByIndex(n, out, index) - d.prepare(n, field) - } - - mergedFields := d.mergedFields - d.mergedFields = nil - var mergeNode *Node - var doneFields []bool - if d.uniqueKeys { - doneFields = make([]bool, len(sinfo.FieldsList)) - } - name := settableValueOf("") - l := len(n.Content) - for i := 0; i < l; i += 2 { - ni := n.Content[i] - if isMerge(ni) { - mergeNode = n.Content[i+1] - continue - } - if !d.unmarshal(ni, name) { - continue - } - sname := name.String() - if mergedFields != nil { - if mergedFields[sname] { - continue - } - mergedFields[sname] = true - } - if info, ok := sinfo.FieldsMap[sname]; ok { - if d.uniqueKeys { - if doneFields[info.Id] { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type())) - continue - } - doneFields[info.Id] = true - } - var field reflect.Value - if info.Inline == nil { - field = out.Field(info.Num) - } else { - field = d.fieldByIndex(n, out, info.Inline) - } - d.unmarshal(n.Content[i+1], field) - } else if sinfo.InlineMap != -1 { - if inlineMap.IsNil() { - inlineMap.Set(reflect.MakeMap(inlineMap.Type())) - } - value := reflect.New(elemType).Elem() - d.unmarshal(n.Content[i+1], value) - inlineMap.SetMapIndex(name, value) - } else if d.knownFields { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type())) - } - } - - d.mergedFields = mergedFields - if mergeNode != nil { - d.merge(n, mergeNode, out) - } - return true -} - -func failWantMap() { - failf("map merge requires map or sequence of maps as the value") -} - -func (d *decoder) merge(parent *Node, merge *Node, out reflect.Value) { - mergedFields := d.mergedFields - if mergedFields == nil { - d.mergedFields = make(map[interface{}]bool) - for i := 0; i < len(parent.Content); i += 2 { - k := reflect.New(ifaceType).Elem() - if d.unmarshal(parent.Content[i], k) { - d.mergedFields[k.Interface()] = true - } - } - } - - switch merge.Kind { - case MappingNode: - d.unmarshal(merge, out) - case AliasNode: - if merge.Alias != nil && merge.Alias.Kind != MappingNode { - failWantMap() - } - d.unmarshal(merge, out) - case SequenceNode: - for i := 0; i < len(merge.Content); i++ { - ni := merge.Content[i] - if ni.Kind == AliasNode { - if ni.Alias != nil && ni.Alias.Kind != MappingNode { - failWantMap() - } - } else if ni.Kind != MappingNode { - failWantMap() - } - d.unmarshal(ni, out) - } - default: - failWantMap() - } - - d.mergedFields = mergedFields -} - -func isMerge(n *Node) bool { - return n.Kind == ScalarNode && n.Value == "<<" && (n.Tag == "" || n.Tag == "!" || shortTag(n.Tag) == mergeTag) -} diff --git a/vendor/gopkg.in/yaml.v3/emitterc.go b/vendor/gopkg.in/yaml.v3/emitterc.go deleted file mode 100644 index 0f47c9ca..00000000 --- a/vendor/gopkg.in/yaml.v3/emitterc.go +++ /dev/null @@ -1,2020 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -import ( - "bytes" - "fmt" -) - -// Flush the buffer if needed. -func flush(emitter *yaml_emitter_t) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) { - return yaml_emitter_flush(emitter) - } - return true -} - -// Put a character to the output buffer. -func put(emitter *yaml_emitter_t, value byte) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - emitter.buffer[emitter.buffer_pos] = value - emitter.buffer_pos++ - emitter.column++ - return true -} - -// Put a line break to the output buffer. -func put_break(emitter *yaml_emitter_t) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - switch emitter.line_break { - case yaml_CR_BREAK: - emitter.buffer[emitter.buffer_pos] = '\r' - emitter.buffer_pos += 1 - case yaml_LN_BREAK: - emitter.buffer[emitter.buffer_pos] = '\n' - emitter.buffer_pos += 1 - case yaml_CRLN_BREAK: - emitter.buffer[emitter.buffer_pos+0] = '\r' - emitter.buffer[emitter.buffer_pos+1] = '\n' - emitter.buffer_pos += 2 - default: - panic("unknown line break setting") - } - if emitter.column == 0 { - emitter.space_above = true - } - emitter.column = 0 - emitter.line++ - // [Go] Do this here and below and drop from everywhere else (see commented lines). - emitter.indention = true - return true -} - -// Copy a character from a string into buffer. -func write(emitter *yaml_emitter_t, s []byte, i *int) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - p := emitter.buffer_pos - w := width(s[*i]) - switch w { - case 4: - emitter.buffer[p+3] = s[*i+3] - fallthrough - case 3: - emitter.buffer[p+2] = s[*i+2] - fallthrough - case 2: - emitter.buffer[p+1] = s[*i+1] - fallthrough - case 1: - emitter.buffer[p+0] = s[*i+0] - default: - panic("unknown character width") - } - emitter.column++ - emitter.buffer_pos += w - *i += w - return true -} - -// Write a whole string into buffer. -func write_all(emitter *yaml_emitter_t, s []byte) bool { - for i := 0; i < len(s); { - if !write(emitter, s, &i) { - return false - } - } - return true -} - -// Copy a line break character from a string into buffer. -func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { - if s[*i] == '\n' { - if !put_break(emitter) { - return false - } - *i++ - } else { - if !write(emitter, s, i) { - return false - } - if emitter.column == 0 { - emitter.space_above = true - } - emitter.column = 0 - emitter.line++ - // [Go] Do this here and above and drop from everywhere else (see commented lines). - emitter.indention = true - } - return true -} - -// Set an emitter error and return false. -func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { - emitter.error = yaml_EMITTER_ERROR - emitter.problem = problem - return false -} - -// Emit an event. -func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { - emitter.events = append(emitter.events, *event) - for !yaml_emitter_need_more_events(emitter) { - event := &emitter.events[emitter.events_head] - if !yaml_emitter_analyze_event(emitter, event) { - return false - } - if !yaml_emitter_state_machine(emitter, event) { - return false - } - yaml_event_delete(event) - emitter.events_head++ - } - return true -} - -// Check if we need to accumulate more events before emitting. -// -// We accumulate extra -// - 1 event for DOCUMENT-START -// - 2 events for SEQUENCE-START -// - 3 events for MAPPING-START -// -func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { - if emitter.events_head == len(emitter.events) { - return true - } - var accumulate int - switch emitter.events[emitter.events_head].typ { - case yaml_DOCUMENT_START_EVENT: - accumulate = 1 - break - case yaml_SEQUENCE_START_EVENT: - accumulate = 2 - break - case yaml_MAPPING_START_EVENT: - accumulate = 3 - break - default: - return false - } - if len(emitter.events)-emitter.events_head > accumulate { - return false - } - var level int - for i := emitter.events_head; i < len(emitter.events); i++ { - switch emitter.events[i].typ { - case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: - level++ - case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: - level-- - } - if level == 0 { - return false - } - } - return true -} - -// Append a directive to the directives stack. -func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { - for i := 0; i < len(emitter.tag_directives); i++ { - if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { - if allow_duplicates { - return true - } - return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") - } - } - - // [Go] Do we actually need to copy this given garbage collection - // and the lack of deallocating destructors? - tag_copy := yaml_tag_directive_t{ - handle: make([]byte, len(value.handle)), - prefix: make([]byte, len(value.prefix)), - } - copy(tag_copy.handle, value.handle) - copy(tag_copy.prefix, value.prefix) - emitter.tag_directives = append(emitter.tag_directives, tag_copy) - return true -} - -// Increase the indentation level. -func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { - emitter.indents = append(emitter.indents, emitter.indent) - if emitter.indent < 0 { - if flow { - emitter.indent = emitter.best_indent - } else { - emitter.indent = 0 - } - } else if !indentless { - // [Go] This was changed so that indentations are more regular. - if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE { - // The first indent inside a sequence will just skip the "- " indicator. - emitter.indent += 2 - } else { - // Everything else aligns to the chosen indentation. - emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent) - } - } - return true -} - -// State dispatcher. -func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { - switch emitter.state { - default: - case yaml_EMIT_STREAM_START_STATE: - return yaml_emitter_emit_stream_start(emitter, event) - - case yaml_EMIT_FIRST_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, true) - - case yaml_EMIT_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, false) - - case yaml_EMIT_DOCUMENT_CONTENT_STATE: - return yaml_emitter_emit_document_content(emitter, event) - - case yaml_EMIT_DOCUMENT_END_STATE: - return yaml_emitter_emit_document_end(emitter, event) - - case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, true, false) - - case yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, false, true) - - case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, false, false) - - case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, true, false) - - case yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, false, true) - - case yaml_EMIT_FLOW_MAPPING_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, false, false) - - case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, true) - - case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, false) - - case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, true) - - case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, false) - - case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, true) - - case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, false) - - case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, true) - - case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, false) - - case yaml_EMIT_END_STATE: - return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") - } - panic("invalid emitter state") -} - -// Expect STREAM-START. -func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if event.typ != yaml_STREAM_START_EVENT { - return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") - } - if emitter.encoding == yaml_ANY_ENCODING { - emitter.encoding = event.encoding - if emitter.encoding == yaml_ANY_ENCODING { - emitter.encoding = yaml_UTF8_ENCODING - } - } - if emitter.best_indent < 2 || emitter.best_indent > 9 { - emitter.best_indent = 2 - } - if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { - emitter.best_width = 80 - } - if emitter.best_width < 0 { - emitter.best_width = 1<<31 - 1 - } - if emitter.line_break == yaml_ANY_BREAK { - emitter.line_break = yaml_LN_BREAK - } - - emitter.indent = -1 - emitter.line = 0 - emitter.column = 0 - emitter.whitespace = true - emitter.indention = true - emitter.space_above = true - emitter.foot_indent = -1 - - if emitter.encoding != yaml_UTF8_ENCODING { - if !yaml_emitter_write_bom(emitter) { - return false - } - } - emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE - return true -} - -// Expect DOCUMENT-START or STREAM-END. -func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - - if event.typ == yaml_DOCUMENT_START_EVENT { - - if event.version_directive != nil { - if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { - return false - } - } - - for i := 0; i < len(event.tag_directives); i++ { - tag_directive := &event.tag_directives[i] - if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { - return false - } - if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { - return false - } - } - - for i := 0; i < len(default_tag_directives); i++ { - tag_directive := &default_tag_directives[i] - if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { - return false - } - } - - implicit := event.implicit - if !first || emitter.canonical { - implicit = false - } - - if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if event.version_directive != nil { - implicit = false - if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if len(event.tag_directives) > 0 { - implicit = false - for i := 0; i < len(event.tag_directives); i++ { - tag_directive := &event.tag_directives[i] - if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { - return false - } - if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { - return false - } - if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - } - - if yaml_emitter_check_empty_document(emitter) { - implicit = false - } - if !implicit { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { - return false - } - if emitter.canonical || true { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - } - - if len(emitter.head_comment) > 0 { - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if !put_break(emitter) { - return false - } - } - - emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE - return true - } - - if event.typ == yaml_STREAM_END_EVENT { - if emitter.open_ended { - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_flush(emitter) { - return false - } - emitter.state = yaml_EMIT_END_STATE - return true - } - - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") -} - -// Expect the root node. -func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { - emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) - - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if !yaml_emitter_emit_node(emitter, event, true, false, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect DOCUMENT-END. -func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if event.typ != yaml_DOCUMENT_END_EVENT { - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") - } - // [Go] Force document foot separation. - emitter.foot_indent = 0 - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - emitter.foot_indent = -1 - if !yaml_emitter_write_indent(emitter) { - return false - } - if !event.implicit { - // [Go] Allocate the slice elsewhere. - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_flush(emitter) { - return false - } - emitter.state = yaml_EMIT_DOCUMENT_START_STATE - emitter.tag_directives = emitter.tag_directives[:0] - return true -} - -// Expect a flow item node. -func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool { - if first { - if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - emitter.flow_level++ - } - - if event.typ == yaml_SEQUENCE_END_EVENT { - if emitter.canonical && !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - emitter.flow_level-- - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - if emitter.column == 0 || emitter.canonical && !first { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - - return true - } - - if !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if emitter.column == 0 { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE) - } else { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) - } - if !yaml_emitter_emit_node(emitter, event, false, true, false, false) { - return false - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect a flow key node. -func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool { - if first { - if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - emitter.flow_level++ - } - - if event.typ == yaml_MAPPING_END_EVENT { - if (emitter.canonical || len(emitter.head_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0) && !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - if !yaml_emitter_process_head_comment(emitter) { - return false - } - emitter.flow_level-- - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - if emitter.canonical && !first { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - - if !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - - if !yaml_emitter_process_head_comment(emitter) { - return false - } - - if emitter.column == 0 { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, true) - } - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a flow value node. -func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { - if simple { - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { - return false - } - } else { - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { - return false - } - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE) - } else { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) - } - if !yaml_emitter_emit_node(emitter, event, false, false, true, false) { - return false - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect a block item node. -func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_increase_indent(emitter, false, false) { - return false - } - } - if event.typ == yaml_SEQUENCE_END_EVENT { - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) - if !yaml_emitter_emit_node(emitter, event, false, true, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect a block key node. -func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_increase_indent(emitter, false, false) { - return false - } - } - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if event.typ == yaml_MAPPING_END_EVENT { - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if len(emitter.line_comment) > 0 { - // [Go] A line comment was provided for the key. That's unusual as the - // scanner associates line comments with the value. Either way, - // save the line comment and render it appropriately later. - emitter.key_line_comment = emitter.line_comment - emitter.line_comment = nil - } - if yaml_emitter_check_simple_key(emitter) { - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, true) - } - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a block value node. -func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { - if simple { - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { - return false - } - } else { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { - return false - } - } - if len(emitter.key_line_comment) > 0 { - // [Go] Line comments are generally associated with the value, but when there's - // no value on the same line as a mapping key they end up attached to the - // key itself. - if event.typ == yaml_SCALAR_EVENT { - if len(emitter.line_comment) == 0 { - // A scalar is coming and it has no line comments by itself yet, - // so just let it handle the line comment as usual. If it has a - // line comment, we can't have both so the one from the key is lost. - emitter.line_comment = emitter.key_line_comment - emitter.key_line_comment = nil - } - } else if event.sequence_style() != yaml_FLOW_SEQUENCE_STYLE && (event.typ == yaml_MAPPING_START_EVENT || event.typ == yaml_SEQUENCE_START_EVENT) { - // An indented block follows, so write the comment right now. - emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment - if !yaml_emitter_process_line_comment(emitter) { - return false - } - emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment - } - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) - if !yaml_emitter_emit_node(emitter, event, false, false, true, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -func yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { - return event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0 -} - -// Expect a node. -func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, - root bool, sequence bool, mapping bool, simple_key bool) bool { - - emitter.root_context = root - emitter.sequence_context = sequence - emitter.mapping_context = mapping - emitter.simple_key_context = simple_key - - switch event.typ { - case yaml_ALIAS_EVENT: - return yaml_emitter_emit_alias(emitter, event) - case yaml_SCALAR_EVENT: - return yaml_emitter_emit_scalar(emitter, event) - case yaml_SEQUENCE_START_EVENT: - return yaml_emitter_emit_sequence_start(emitter, event) - case yaml_MAPPING_START_EVENT: - return yaml_emitter_emit_mapping_start(emitter, event) - default: - return yaml_emitter_set_emitter_error(emitter, - fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ)) - } -} - -// Expect ALIAS. -func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true -} - -// Expect SCALAR. -func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_select_scalar_style(emitter, event) { - return false - } - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - if !yaml_emitter_process_scalar(emitter) { - return false - } - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true -} - -// Expect SEQUENCE-START. -func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || - yaml_emitter_check_empty_sequence(emitter) { - emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE - } else { - emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE - } - return true -} - -// Expect MAPPING-START. -func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || - yaml_emitter_check_empty_mapping(emitter) { - emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE - } else { - emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE - } - return true -} - -// Check if the document content is an empty scalar. -func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { - return false // [Go] Huh? -} - -// Check if the next events represent an empty sequence. -func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { - if len(emitter.events)-emitter.events_head < 2 { - return false - } - return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && - emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT -} - -// Check if the next events represent an empty mapping. -func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { - if len(emitter.events)-emitter.events_head < 2 { - return false - } - return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && - emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT -} - -// Check if the next node can be expressed as a simple key. -func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { - length := 0 - switch emitter.events[emitter.events_head].typ { - case yaml_ALIAS_EVENT: - length += len(emitter.anchor_data.anchor) - case yaml_SCALAR_EVENT: - if emitter.scalar_data.multiline { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) + - len(emitter.scalar_data.value) - case yaml_SEQUENCE_START_EVENT: - if !yaml_emitter_check_empty_sequence(emitter) { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) - case yaml_MAPPING_START_EVENT: - if !yaml_emitter_check_empty_mapping(emitter) { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) - default: - return false - } - return length <= 128 -} - -// Determine an acceptable scalar style. -func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { - - no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 - if no_tag && !event.implicit && !event.quoted_implicit { - return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") - } - - style := event.scalar_style() - if style == yaml_ANY_SCALAR_STYLE { - style = yaml_PLAIN_SCALAR_STYLE - } - if emitter.canonical { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - if emitter.simple_key_context && emitter.scalar_data.multiline { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - - if style == yaml_PLAIN_SCALAR_STYLE { - if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || - emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - if no_tag && !event.implicit { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - } - if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { - if !emitter.scalar_data.single_quoted_allowed { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - } - if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { - if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - } - - if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { - emitter.tag_data.handle = []byte{'!'} - } - emitter.scalar_data.style = style - return true -} - -// Write an anchor. -func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { - if emitter.anchor_data.anchor == nil { - return true - } - c := []byte{'&'} - if emitter.anchor_data.alias { - c[0] = '*' - } - if !yaml_emitter_write_indicator(emitter, c, true, false, false) { - return false - } - return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) -} - -// Write a tag. -func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { - if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { - return true - } - if len(emitter.tag_data.handle) > 0 { - if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { - return false - } - if len(emitter.tag_data.suffix) > 0 { - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { - return false - } - } - } else { - // [Go] Allocate these slices elsewhere. - if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { - return false - } - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { - return false - } - } - return true -} - -// Write a scalar. -func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { - switch emitter.scalar_data.style { - case yaml_PLAIN_SCALAR_STYLE: - return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_SINGLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_DOUBLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_LITERAL_SCALAR_STYLE: - return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) - - case yaml_FOLDED_SCALAR_STYLE: - return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) - } - panic("unknown scalar style") -} - -// Write a head comment. -func yaml_emitter_process_head_comment(emitter *yaml_emitter_t) bool { - if len(emitter.tail_comment) > 0 { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_comment(emitter, emitter.tail_comment) { - return false - } - emitter.tail_comment = emitter.tail_comment[:0] - emitter.foot_indent = emitter.indent - if emitter.foot_indent < 0 { - emitter.foot_indent = 0 - } - } - - if len(emitter.head_comment) == 0 { - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_comment(emitter, emitter.head_comment) { - return false - } - emitter.head_comment = emitter.head_comment[:0] - return true -} - -// Write an line comment. -func yaml_emitter_process_line_comment(emitter *yaml_emitter_t) bool { - if len(emitter.line_comment) == 0 { - return true - } - if !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !yaml_emitter_write_comment(emitter, emitter.line_comment) { - return false - } - emitter.line_comment = emitter.line_comment[:0] - return true -} - -// Write a foot comment. -func yaml_emitter_process_foot_comment(emitter *yaml_emitter_t) bool { - if len(emitter.foot_comment) == 0 { - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_comment(emitter, emitter.foot_comment) { - return false - } - emitter.foot_comment = emitter.foot_comment[:0] - emitter.foot_indent = emitter.indent - if emitter.foot_indent < 0 { - emitter.foot_indent = 0 - } - return true -} - -// Check if a %YAML directive is valid. -func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { - if version_directive.major != 1 || version_directive.minor != 1 { - return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") - } - return true -} - -// Check if a %TAG directive is valid. -func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { - handle := tag_directive.handle - prefix := tag_directive.prefix - if len(handle) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") - } - if handle[0] != '!' { - return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") - } - if handle[len(handle)-1] != '!' { - return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") - } - for i := 1; i < len(handle)-1; i += width(handle[i]) { - if !is_alpha(handle, i) { - return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") - } - } - if len(prefix) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") - } - return true -} - -// Check if an anchor is valid. -func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { - if len(anchor) == 0 { - problem := "anchor value must not be empty" - if alias { - problem = "alias value must not be empty" - } - return yaml_emitter_set_emitter_error(emitter, problem) - } - for i := 0; i < len(anchor); i += width(anchor[i]) { - if !is_alpha(anchor, i) { - problem := "anchor value must contain alphanumerical characters only" - if alias { - problem = "alias value must contain alphanumerical characters only" - } - return yaml_emitter_set_emitter_error(emitter, problem) - } - } - emitter.anchor_data.anchor = anchor - emitter.anchor_data.alias = alias - return true -} - -// Check if a tag is valid. -func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { - if len(tag) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") - } - for i := 0; i < len(emitter.tag_directives); i++ { - tag_directive := &emitter.tag_directives[i] - if bytes.HasPrefix(tag, tag_directive.prefix) { - emitter.tag_data.handle = tag_directive.handle - emitter.tag_data.suffix = tag[len(tag_directive.prefix):] - return true - } - } - emitter.tag_data.suffix = tag - return true -} - -// Check if a scalar is valid. -func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { - var ( - block_indicators = false - flow_indicators = false - line_breaks = false - special_characters = false - tab_characters = false - - leading_space = false - leading_break = false - trailing_space = false - trailing_break = false - break_space = false - space_break = false - - preceded_by_whitespace = false - followed_by_whitespace = false - previous_space = false - previous_break = false - ) - - emitter.scalar_data.value = value - - if len(value) == 0 { - emitter.scalar_data.multiline = false - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = true - emitter.scalar_data.single_quoted_allowed = true - emitter.scalar_data.block_allowed = false - return true - } - - if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { - block_indicators = true - flow_indicators = true - } - - preceded_by_whitespace = true - for i, w := 0, 0; i < len(value); i += w { - w = width(value[i]) - followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) - - if i == 0 { - switch value[i] { - case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': - flow_indicators = true - block_indicators = true - case '?', ':': - flow_indicators = true - if followed_by_whitespace { - block_indicators = true - } - case '-': - if followed_by_whitespace { - flow_indicators = true - block_indicators = true - } - } - } else { - switch value[i] { - case ',', '?', '[', ']', '{', '}': - flow_indicators = true - case ':': - flow_indicators = true - if followed_by_whitespace { - block_indicators = true - } - case '#': - if preceded_by_whitespace { - flow_indicators = true - block_indicators = true - } - } - } - - if value[i] == '\t' { - tab_characters = true - } else if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { - special_characters = true - } - if is_space(value, i) { - if i == 0 { - leading_space = true - } - if i+width(value[i]) == len(value) { - trailing_space = true - } - if previous_break { - break_space = true - } - previous_space = true - previous_break = false - } else if is_break(value, i) { - line_breaks = true - if i == 0 { - leading_break = true - } - if i+width(value[i]) == len(value) { - trailing_break = true - } - if previous_space { - space_break = true - } - previous_space = false - previous_break = true - } else { - previous_space = false - previous_break = false - } - - // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. - preceded_by_whitespace = is_blankz(value, i) - } - - emitter.scalar_data.multiline = line_breaks - emitter.scalar_data.flow_plain_allowed = true - emitter.scalar_data.block_plain_allowed = true - emitter.scalar_data.single_quoted_allowed = true - emitter.scalar_data.block_allowed = true - - if leading_space || leading_break || trailing_space || trailing_break { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - } - if trailing_space { - emitter.scalar_data.block_allowed = false - } - if break_space { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - emitter.scalar_data.single_quoted_allowed = false - } - if space_break || tab_characters || special_characters { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - emitter.scalar_data.single_quoted_allowed = false - } - if space_break || special_characters { - emitter.scalar_data.block_allowed = false - } - if line_breaks { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - } - if flow_indicators { - emitter.scalar_data.flow_plain_allowed = false - } - if block_indicators { - emitter.scalar_data.block_plain_allowed = false - } - return true -} - -// Check if the event data is valid. -func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { - - emitter.anchor_data.anchor = nil - emitter.tag_data.handle = nil - emitter.tag_data.suffix = nil - emitter.scalar_data.value = nil - - if len(event.head_comment) > 0 { - emitter.head_comment = event.head_comment - } - if len(event.line_comment) > 0 { - emitter.line_comment = event.line_comment - } - if len(event.foot_comment) > 0 { - emitter.foot_comment = event.foot_comment - } - if len(event.tail_comment) > 0 { - emitter.tail_comment = event.tail_comment - } - - switch event.typ { - case yaml_ALIAS_EVENT: - if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { - return false - } - - case yaml_SCALAR_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - if !yaml_emitter_analyze_scalar(emitter, event.value) { - return false - } - - case yaml_SEQUENCE_START_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - - case yaml_MAPPING_START_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - } - return true -} - -// Write the BOM character. -func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { - if !flush(emitter) { - return false - } - pos := emitter.buffer_pos - emitter.buffer[pos+0] = '\xEF' - emitter.buffer[pos+1] = '\xBB' - emitter.buffer[pos+2] = '\xBF' - emitter.buffer_pos += 3 - return true -} - -func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { - indent := emitter.indent - if indent < 0 { - indent = 0 - } - if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { - if !put_break(emitter) { - return false - } - } - if emitter.foot_indent == indent { - if !put_break(emitter) { - return false - } - } - for emitter.column < indent { - if !put(emitter, ' ') { - return false - } - } - emitter.whitespace = true - //emitter.indention = true - emitter.space_above = false - emitter.foot_indent = -1 - return true -} - -func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { - if need_whitespace && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !write_all(emitter, indicator) { - return false - } - emitter.whitespace = is_whitespace - emitter.indention = (emitter.indention && is_indention) - emitter.open_ended = false - return true -} - -func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { - if !write_all(emitter, value) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { - if !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !write_all(emitter, value) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { - if need_whitespace && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - for i := 0; i < len(value); { - var must_write bool - switch value[i] { - case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': - must_write = true - default: - must_write = is_alpha(value, i) - } - if must_write { - if !write(emitter, value, &i) { - return false - } - } else { - w := width(value[i]) - for k := 0; k < w; k++ { - octet := value[i] - i++ - if !put(emitter, '%') { - return false - } - - c := octet >> 4 - if c < 10 { - c += '0' - } else { - c += 'A' - 10 - } - if !put(emitter, c) { - return false - } - - c = octet & 0x0f - if c < 10 { - c += '0' - } else { - c += 'A' - 10 - } - if !put(emitter, c) { - return false - } - } - } - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - if len(value) > 0 && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - - spaces := false - breaks := false - for i := 0; i < len(value); { - if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - spaces = true - } else if is_break(value, i) { - if !breaks && value[i] == '\n' { - if !put_break(emitter) { - return false - } - } - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - spaces = false - breaks = false - } - } - - if len(value) > 0 { - emitter.whitespace = false - } - emitter.indention = false - if emitter.root_context { - emitter.open_ended = true - } - - return true -} - -func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { - return false - } - - spaces := false - breaks := false - for i := 0; i < len(value); { - if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - spaces = true - } else if is_break(value, i) { - if !breaks && value[i] == '\n' { - if !put_break(emitter) { - return false - } - } - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if value[i] == '\'' { - if !put(emitter, '\'') { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - spaces = false - breaks = false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - spaces := false - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { - return false - } - - for i := 0; i < len(value); { - if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || - is_bom(value, i) || is_break(value, i) || - value[i] == '"' || value[i] == '\\' { - - octet := value[i] - - var w int - var v rune - switch { - case octet&0x80 == 0x00: - w, v = 1, rune(octet&0x7F) - case octet&0xE0 == 0xC0: - w, v = 2, rune(octet&0x1F) - case octet&0xF0 == 0xE0: - w, v = 3, rune(octet&0x0F) - case octet&0xF8 == 0xF0: - w, v = 4, rune(octet&0x07) - } - for k := 1; k < w; k++ { - octet = value[i+k] - v = (v << 6) + (rune(octet) & 0x3F) - } - i += w - - if !put(emitter, '\\') { - return false - } - - var ok bool - switch v { - case 0x00: - ok = put(emitter, '0') - case 0x07: - ok = put(emitter, 'a') - case 0x08: - ok = put(emitter, 'b') - case 0x09: - ok = put(emitter, 't') - case 0x0A: - ok = put(emitter, 'n') - case 0x0b: - ok = put(emitter, 'v') - case 0x0c: - ok = put(emitter, 'f') - case 0x0d: - ok = put(emitter, 'r') - case 0x1b: - ok = put(emitter, 'e') - case 0x22: - ok = put(emitter, '"') - case 0x5c: - ok = put(emitter, '\\') - case 0x85: - ok = put(emitter, 'N') - case 0xA0: - ok = put(emitter, '_') - case 0x2028: - ok = put(emitter, 'L') - case 0x2029: - ok = put(emitter, 'P') - default: - if v <= 0xFF { - ok = put(emitter, 'x') - w = 2 - } else if v <= 0xFFFF { - ok = put(emitter, 'u') - w = 4 - } else { - ok = put(emitter, 'U') - w = 8 - } - for k := (w - 1) * 4; ok && k >= 0; k -= 4 { - digit := byte((v >> uint(k)) & 0x0F) - if digit < 10 { - ok = put(emitter, digit+'0') - } else { - ok = put(emitter, digit+'A'-10) - } - } - } - if !ok { - return false - } - spaces = false - } else if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { - if !yaml_emitter_write_indent(emitter) { - return false - } - if is_space(value, i+1) { - if !put(emitter, '\\') { - return false - } - } - i += width(value[i]) - } else if !write(emitter, value, &i) { - return false - } - spaces = true - } else { - if !write(emitter, value, &i) { - return false - } - spaces = false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { - if is_space(value, 0) || is_break(value, 0) { - indent_hint := []byte{'0' + byte(emitter.best_indent)} - if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { - return false - } - } - - emitter.open_ended = false - - var chomp_hint [1]byte - if len(value) == 0 { - chomp_hint[0] = '-' - } else { - i := len(value) - 1 - for value[i]&0xC0 == 0x80 { - i-- - } - if !is_break(value, i) { - chomp_hint[0] = '-' - } else if i == 0 { - chomp_hint[0] = '+' - emitter.open_ended = true - } else { - i-- - for value[i]&0xC0 == 0x80 { - i-- - } - if is_break(value, i) { - chomp_hint[0] = '+' - emitter.open_ended = true - } - } - } - if chomp_hint[0] != 0 { - if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { - return false - } - } - return true -} - -func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { - if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { - return false - } - if !yaml_emitter_write_block_scalar_hints(emitter, value) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - //emitter.indention = true - emitter.whitespace = true - breaks := true - for i := 0; i < len(value); { - if is_break(value, i) { - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - breaks = false - } - } - - return true -} - -func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { - return false - } - if !yaml_emitter_write_block_scalar_hints(emitter, value) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - - //emitter.indention = true - emitter.whitespace = true - - breaks := true - leading_spaces := true - for i := 0; i < len(value); { - if is_break(value, i) { - if !breaks && !leading_spaces && value[i] == '\n' { - k := 0 - for is_break(value, k) { - k += width(value[k]) - } - if !is_blankz(value, k) { - if !put_break(emitter) { - return false - } - } - } - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - leading_spaces = is_blank(value, i) - } - if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - emitter.indention = false - breaks = false - } - } - return true -} - -func yaml_emitter_write_comment(emitter *yaml_emitter_t, comment []byte) bool { - breaks := false - pound := false - for i := 0; i < len(comment); { - if is_break(comment, i) { - if !write_break(emitter, comment, &i) { - return false - } - //emitter.indention = true - breaks = true - pound = false - } else { - if breaks && !yaml_emitter_write_indent(emitter) { - return false - } - if !pound { - if comment[i] != '#' && (!put(emitter, '#') || !put(emitter, ' ')) { - return false - } - pound = true - } - if !write(emitter, comment, &i) { - return false - } - emitter.indention = false - breaks = false - } - } - if !breaks && !put_break(emitter) { - return false - } - - emitter.whitespace = true - //emitter.indention = true - return true -} diff --git a/vendor/gopkg.in/yaml.v3/encode.go b/vendor/gopkg.in/yaml.v3/encode.go deleted file mode 100644 index de9e72a3..00000000 --- a/vendor/gopkg.in/yaml.v3/encode.go +++ /dev/null @@ -1,577 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// 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 yaml - -import ( - "encoding" - "fmt" - "io" - "reflect" - "regexp" - "sort" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -type encoder struct { - emitter yaml_emitter_t - event yaml_event_t - out []byte - flow bool - indent int - doneInit bool -} - -func newEncoder() *encoder { - e := &encoder{} - yaml_emitter_initialize(&e.emitter) - yaml_emitter_set_output_string(&e.emitter, &e.out) - yaml_emitter_set_unicode(&e.emitter, true) - return e -} - -func newEncoderWithWriter(w io.Writer) *encoder { - e := &encoder{} - yaml_emitter_initialize(&e.emitter) - yaml_emitter_set_output_writer(&e.emitter, w) - yaml_emitter_set_unicode(&e.emitter, true) - return e -} - -func (e *encoder) init() { - if e.doneInit { - return - } - if e.indent == 0 { - e.indent = 4 - } - e.emitter.best_indent = e.indent - yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING) - e.emit() - e.doneInit = true -} - -func (e *encoder) finish() { - e.emitter.open_ended = false - yaml_stream_end_event_initialize(&e.event) - e.emit() -} - -func (e *encoder) destroy() { - yaml_emitter_delete(&e.emitter) -} - -func (e *encoder) emit() { - // This will internally delete the e.event value. - e.must(yaml_emitter_emit(&e.emitter, &e.event)) -} - -func (e *encoder) must(ok bool) { - if !ok { - msg := e.emitter.problem - if msg == "" { - msg = "unknown problem generating YAML content" - } - failf("%s", msg) - } -} - -func (e *encoder) marshalDoc(tag string, in reflect.Value) { - e.init() - var node *Node - if in.IsValid() { - node, _ = in.Interface().(*Node) - } - if node != nil && node.Kind == DocumentNode { - e.nodev(in) - } else { - yaml_document_start_event_initialize(&e.event, nil, nil, true) - e.emit() - e.marshal(tag, in) - yaml_document_end_event_initialize(&e.event, true) - e.emit() - } -} - -func (e *encoder) marshal(tag string, in reflect.Value) { - tag = shortTag(tag) - if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() { - e.nilv() - return - } - iface := in.Interface() - switch value := iface.(type) { - case *Node: - e.nodev(in) - return - case Node: - if !in.CanAddr() { - var n = reflect.New(in.Type()).Elem() - n.Set(in) - in = n - } - e.nodev(in.Addr()) - return - case time.Time: - e.timev(tag, in) - return - case *time.Time: - e.timev(tag, in.Elem()) - return - case time.Duration: - e.stringv(tag, reflect.ValueOf(value.String())) - return - case Marshaler: - v, err := value.MarshalYAML() - if err != nil { - fail(err) - } - if v == nil { - e.nilv() - return - } - e.marshal(tag, reflect.ValueOf(v)) - return - case encoding.TextMarshaler: - text, err := value.MarshalText() - if err != nil { - fail(err) - } - in = reflect.ValueOf(string(text)) - case nil: - e.nilv() - return - } - switch in.Kind() { - case reflect.Interface: - e.marshal(tag, in.Elem()) - case reflect.Map: - e.mapv(tag, in) - case reflect.Ptr: - e.marshal(tag, in.Elem()) - case reflect.Struct: - e.structv(tag, in) - case reflect.Slice, reflect.Array: - e.slicev(tag, in) - case reflect.String: - e.stringv(tag, in) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - e.intv(tag, in) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - e.uintv(tag, in) - case reflect.Float32, reflect.Float64: - e.floatv(tag, in) - case reflect.Bool: - e.boolv(tag, in) - default: - panic("cannot marshal type: " + in.Type().String()) - } -} - -func (e *encoder) mapv(tag string, in reflect.Value) { - e.mappingv(tag, func() { - keys := keyList(in.MapKeys()) - sort.Sort(keys) - for _, k := range keys { - e.marshal("", k) - e.marshal("", in.MapIndex(k)) - } - }) -} - -func (e *encoder) fieldByIndex(v reflect.Value, index []int) (field reflect.Value) { - for _, num := range index { - for { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - return reflect.Value{} - } - v = v.Elem() - continue - } - break - } - v = v.Field(num) - } - return v -} - -func (e *encoder) structv(tag string, in reflect.Value) { - sinfo, err := getStructInfo(in.Type()) - if err != nil { - panic(err) - } - e.mappingv(tag, func() { - for _, info := range sinfo.FieldsList { - var value reflect.Value - if info.Inline == nil { - value = in.Field(info.Num) - } else { - value = e.fieldByIndex(in, info.Inline) - if !value.IsValid() { - continue - } - } - if info.OmitEmpty && isZero(value) { - continue - } - e.marshal("", reflect.ValueOf(info.Key)) - e.flow = info.Flow - e.marshal("", value) - } - if sinfo.InlineMap >= 0 { - m := in.Field(sinfo.InlineMap) - if m.Len() > 0 { - e.flow = false - keys := keyList(m.MapKeys()) - sort.Sort(keys) - for _, k := range keys { - if _, found := sinfo.FieldsMap[k.String()]; found { - panic(fmt.Sprintf("cannot have key %q in inlined map: conflicts with struct field", k.String())) - } - e.marshal("", k) - e.flow = false - e.marshal("", m.MapIndex(k)) - } - } - } - }) -} - -func (e *encoder) mappingv(tag string, f func()) { - implicit := tag == "" - style := yaml_BLOCK_MAPPING_STYLE - if e.flow { - e.flow = false - style = yaml_FLOW_MAPPING_STYLE - } - yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style) - e.emit() - f() - yaml_mapping_end_event_initialize(&e.event) - e.emit() -} - -func (e *encoder) slicev(tag string, in reflect.Value) { - implicit := tag == "" - style := yaml_BLOCK_SEQUENCE_STYLE - if e.flow { - e.flow = false - style = yaml_FLOW_SEQUENCE_STYLE - } - e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) - e.emit() - n := in.Len() - for i := 0; i < n; i++ { - e.marshal("", in.Index(i)) - } - e.must(yaml_sequence_end_event_initialize(&e.event)) - e.emit() -} - -// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1. -// -// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported -// in YAML 1.2 and by this package, but these should be marshalled quoted for -// the time being for compatibility with other parsers. -func isBase60Float(s string) (result bool) { - // Fast path. - if s == "" { - return false - } - c := s[0] - if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 { - return false - } - // Do the full match. - return base60float.MatchString(s) -} - -// From http://yaml.org/type/float.html, except the regular expression there -// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix. -var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`) - -// isOldBool returns whether s is bool notation as defined in YAML 1.1. -// -// We continue to force strings that YAML 1.1 would interpret as booleans to be -// rendered as quotes strings so that the marshalled output valid for YAML 1.1 -// parsing. -func isOldBool(s string) (result bool) { - switch s { - case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON", - "n", "N", "no", "No", "NO", "off", "Off", "OFF": - return true - default: - return false - } -} - -func (e *encoder) stringv(tag string, in reflect.Value) { - var style yaml_scalar_style_t - s := in.String() - canUsePlain := true - switch { - case !utf8.ValidString(s): - if tag == binaryTag { - failf("explicitly tagged !!binary data must be base64-encoded") - } - if tag != "" { - failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag)) - } - // It can't be encoded directly as YAML so use a binary tag - // and encode it as base64. - tag = binaryTag - s = encodeBase64(s) - case tag == "": - // Check to see if it would resolve to a specific - // tag when encoded unquoted. If it doesn't, - // there's no need to quote it. - rtag, _ := resolve("", s) - canUsePlain = rtag == strTag && !(isBase60Float(s) || isOldBool(s)) - } - // Note: it's possible for user code to emit invalid YAML - // if they explicitly specify a tag and a string containing - // text that's incompatible with that tag. - switch { - case strings.Contains(s, "\n"): - if e.flow { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } else { - style = yaml_LITERAL_SCALAR_STYLE - } - case canUsePlain: - style = yaml_PLAIN_SCALAR_STYLE - default: - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - e.emitScalar(s, "", tag, style, nil, nil, nil, nil) -} - -func (e *encoder) boolv(tag string, in reflect.Value) { - var s string - if in.Bool() { - s = "true" - } else { - s = "false" - } - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) intv(tag string, in reflect.Value) { - s := strconv.FormatInt(in.Int(), 10) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) uintv(tag string, in reflect.Value) { - s := strconv.FormatUint(in.Uint(), 10) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) timev(tag string, in reflect.Value) { - t := in.Interface().(time.Time) - s := t.Format(time.RFC3339Nano) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) floatv(tag string, in reflect.Value) { - // Issue #352: When formatting, use the precision of the underlying value - precision := 64 - if in.Kind() == reflect.Float32 { - precision = 32 - } - - s := strconv.FormatFloat(in.Float(), 'g', -1, precision) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) nilv() { - e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t, head, line, foot, tail []byte) { - // TODO Kill this function. Replace all initialize calls by their underlining Go literals. - implicit := tag == "" - if !implicit { - tag = longTag(tag) - } - e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style)) - e.event.head_comment = head - e.event.line_comment = line - e.event.foot_comment = foot - e.event.tail_comment = tail - e.emit() -} - -func (e *encoder) nodev(in reflect.Value) { - e.node(in.Interface().(*Node), "") -} - -func (e *encoder) node(node *Node, tail string) { - // Zero nodes behave as nil. - if node.Kind == 0 && node.IsZero() { - e.nilv() - return - } - - // If the tag was not explicitly requested, and dropping it won't change the - // implicit tag of the value, don't include it in the presentation. - var tag = node.Tag - var stag = shortTag(tag) - var forceQuoting bool - if tag != "" && node.Style&TaggedStyle == 0 { - if node.Kind == ScalarNode { - if stag == strTag && node.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0 { - tag = "" - } else { - rtag, _ := resolve("", node.Value) - if rtag == stag { - tag = "" - } else if stag == strTag { - tag = "" - forceQuoting = true - } - } - } else { - var rtag string - switch node.Kind { - case MappingNode: - rtag = mapTag - case SequenceNode: - rtag = seqTag - } - if rtag == stag { - tag = "" - } - } - } - - switch node.Kind { - case DocumentNode: - yaml_document_start_event_initialize(&e.event, nil, nil, true) - e.event.head_comment = []byte(node.HeadComment) - e.emit() - for _, node := range node.Content { - e.node(node, "") - } - yaml_document_end_event_initialize(&e.event, true) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case SequenceNode: - style := yaml_BLOCK_SEQUENCE_STYLE - if node.Style&FlowStyle != 0 { - style = yaml_FLOW_SEQUENCE_STYLE - } - e.must(yaml_sequence_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style)) - e.event.head_comment = []byte(node.HeadComment) - e.emit() - for _, node := range node.Content { - e.node(node, "") - } - e.must(yaml_sequence_end_event_initialize(&e.event)) - e.event.line_comment = []byte(node.LineComment) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case MappingNode: - style := yaml_BLOCK_MAPPING_STYLE - if node.Style&FlowStyle != 0 { - style = yaml_FLOW_MAPPING_STYLE - } - yaml_mapping_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style) - e.event.tail_comment = []byte(tail) - e.event.head_comment = []byte(node.HeadComment) - e.emit() - - // The tail logic below moves the foot comment of prior keys to the following key, - // since the value for each key may be a nested structure and the foot needs to be - // processed only the entirety of the value is streamed. The last tail is processed - // with the mapping end event. - var tail string - for i := 0; i+1 < len(node.Content); i += 2 { - k := node.Content[i] - foot := k.FootComment - if foot != "" { - kopy := *k - kopy.FootComment = "" - k = &kopy - } - e.node(k, tail) - tail = foot - - v := node.Content[i+1] - e.node(v, "") - } - - yaml_mapping_end_event_initialize(&e.event) - e.event.tail_comment = []byte(tail) - e.event.line_comment = []byte(node.LineComment) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case AliasNode: - yaml_alias_event_initialize(&e.event, []byte(node.Value)) - e.event.head_comment = []byte(node.HeadComment) - e.event.line_comment = []byte(node.LineComment) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case ScalarNode: - value := node.Value - if !utf8.ValidString(value) { - if stag == binaryTag { - failf("explicitly tagged !!binary data must be base64-encoded") - } - if stag != "" { - failf("cannot marshal invalid UTF-8 data as %s", stag) - } - // It can't be encoded directly as YAML so use a binary tag - // and encode it as base64. - tag = binaryTag - value = encodeBase64(value) - } - - style := yaml_PLAIN_SCALAR_STYLE - switch { - case node.Style&DoubleQuotedStyle != 0: - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - case node.Style&SingleQuotedStyle != 0: - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - case node.Style&LiteralStyle != 0: - style = yaml_LITERAL_SCALAR_STYLE - case node.Style&FoldedStyle != 0: - style = yaml_FOLDED_SCALAR_STYLE - case strings.Contains(value, "\n"): - style = yaml_LITERAL_SCALAR_STYLE - case forceQuoting: - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - - e.emitScalar(value, node.Anchor, tag, style, []byte(node.HeadComment), []byte(node.LineComment), []byte(node.FootComment), []byte(tail)) - default: - failf("cannot encode node with unknown kind %d", node.Kind) - } -} diff --git a/vendor/gopkg.in/yaml.v3/parserc.go b/vendor/gopkg.in/yaml.v3/parserc.go deleted file mode 100644 index 268558a0..00000000 --- a/vendor/gopkg.in/yaml.v3/parserc.go +++ /dev/null @@ -1,1258 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -import ( - "bytes" -) - -// The parser implements the following grammar: -// -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END -// implicit_document ::= block_node DOCUMENT-END* -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// block_node_or_indentless_sequence ::= -// ALIAS -// | properties (block_content | indentless_block_sequence)? -// | block_content -// | indentless_block_sequence -// block_node ::= ALIAS -// | properties block_content? -// | block_content -// flow_node ::= ALIAS -// | properties flow_content? -// | flow_content -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// block_content ::= block_collection | flow_collection | SCALAR -// flow_content ::= flow_collection | SCALAR -// block_collection ::= block_sequence | block_mapping -// flow_collection ::= flow_sequence | flow_mapping -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ -// block_mapping ::= BLOCK-MAPPING_START -// ((KEY block_node_or_indentless_sequence?)? -// (VALUE block_node_or_indentless_sequence?)?)* -// BLOCK-END -// flow_sequence ::= FLOW-SEQUENCE-START -// (flow_sequence_entry FLOW-ENTRY)* -// flow_sequence_entry? -// FLOW-SEQUENCE-END -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// flow_mapping ::= FLOW-MAPPING-START -// (flow_mapping_entry FLOW-ENTRY)* -// flow_mapping_entry? -// FLOW-MAPPING-END -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - -// Peek the next token in the token queue. -func peek_token(parser *yaml_parser_t) *yaml_token_t { - if parser.token_available || yaml_parser_fetch_more_tokens(parser) { - token := &parser.tokens[parser.tokens_head] - yaml_parser_unfold_comments(parser, token) - return token - } - return nil -} - -// yaml_parser_unfold_comments walks through the comments queue and joins all -// comments behind the position of the provided token into the respective -// top-level comment slices in the parser. -func yaml_parser_unfold_comments(parser *yaml_parser_t, token *yaml_token_t) { - for parser.comments_head < len(parser.comments) && token.start_mark.index >= parser.comments[parser.comments_head].token_mark.index { - comment := &parser.comments[parser.comments_head] - if len(comment.head) > 0 { - if token.typ == yaml_BLOCK_END_TOKEN { - // No heads on ends, so keep comment.head for a follow up token. - break - } - if len(parser.head_comment) > 0 { - parser.head_comment = append(parser.head_comment, '\n') - } - parser.head_comment = append(parser.head_comment, comment.head...) - } - if len(comment.foot) > 0 { - if len(parser.foot_comment) > 0 { - parser.foot_comment = append(parser.foot_comment, '\n') - } - parser.foot_comment = append(parser.foot_comment, comment.foot...) - } - if len(comment.line) > 0 { - if len(parser.line_comment) > 0 { - parser.line_comment = append(parser.line_comment, '\n') - } - parser.line_comment = append(parser.line_comment, comment.line...) - } - *comment = yaml_comment_t{} - parser.comments_head++ - } -} - -// Remove the next token from the queue (must be called after peek_token). -func skip_token(parser *yaml_parser_t) { - parser.token_available = false - parser.tokens_parsed++ - parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN - parser.tokens_head++ -} - -// Get the next event. -func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { - // Erase the event object. - *event = yaml_event_t{} - - // No events after the end of the stream or error. - if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { - return true - } - - // Generate the next event. - return yaml_parser_state_machine(parser, event) -} - -// Set parser error. -func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { - parser.error = yaml_PARSER_ERROR - parser.problem = problem - parser.problem_mark = problem_mark - return false -} - -func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { - parser.error = yaml_PARSER_ERROR - parser.context = context - parser.context_mark = context_mark - parser.problem = problem - parser.problem_mark = problem_mark - return false -} - -// State dispatcher. -func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { - //trace("yaml_parser_state_machine", "state:", parser.state.String()) - - switch parser.state { - case yaml_PARSE_STREAM_START_STATE: - return yaml_parser_parse_stream_start(parser, event) - - case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, true) - - case yaml_PARSE_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, false) - - case yaml_PARSE_DOCUMENT_CONTENT_STATE: - return yaml_parser_parse_document_content(parser, event) - - case yaml_PARSE_DOCUMENT_END_STATE: - return yaml_parser_parse_document_end(parser, event) - - case yaml_PARSE_BLOCK_NODE_STATE: - return yaml_parser_parse_node(parser, event, true, false) - - case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return yaml_parser_parse_node(parser, event, true, true) - - case yaml_PARSE_FLOW_NODE_STATE: - return yaml_parser_parse_node(parser, event, false, false) - - case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, true) - - case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, false) - - case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_indentless_sequence_entry(parser, event) - - case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, true) - - case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, false) - - case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: - return yaml_parser_parse_block_mapping_value(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, true) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, false) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) - - case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, true) - - case yaml_PARSE_FLOW_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, false) - - case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, false) - - case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, true) - - default: - panic("invalid parser state") - } -} - -// Parse the production: -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END -// ************ -func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_STREAM_START_TOKEN { - return yaml_parser_set_parser_error(parser, "did not find expected ", token.start_mark) - } - parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE - *event = yaml_event_t{ - typ: yaml_STREAM_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - encoding: token.encoding, - } - skip_token(parser) - return true -} - -// Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// * -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// ************************* -func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { - - token := peek_token(parser) - if token == nil { - return false - } - - // Parse extra document end indicators. - if !implicit { - for token.typ == yaml_DOCUMENT_END_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } - - if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && - token.typ != yaml_TAG_DIRECTIVE_TOKEN && - token.typ != yaml_DOCUMENT_START_TOKEN && - token.typ != yaml_STREAM_END_TOKEN { - // Parse an implicit document. - if !yaml_parser_process_directives(parser, nil, nil) { - return false - } - parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) - parser.state = yaml_PARSE_BLOCK_NODE_STATE - - var head_comment []byte - if len(parser.head_comment) > 0 { - // [Go] Scan the header comment backwards, and if an empty line is found, break - // the header so the part before the last empty line goes into the - // document header, while the bottom of it goes into a follow up event. - for i := len(parser.head_comment) - 1; i > 0; i-- { - if parser.head_comment[i] == '\n' { - if i == len(parser.head_comment)-1 { - head_comment = parser.head_comment[:i] - parser.head_comment = parser.head_comment[i+1:] - break - } else if parser.head_comment[i-1] == '\n' { - head_comment = parser.head_comment[:i-1] - parser.head_comment = parser.head_comment[i+1:] - break - } - } - } - } - - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - - head_comment: head_comment, - } - - } else if token.typ != yaml_STREAM_END_TOKEN { - // Parse an explicit document. - var version_directive *yaml_version_directive_t - var tag_directives []yaml_tag_directive_t - start_mark := token.start_mark - if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { - return false - } - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_DOCUMENT_START_TOKEN { - yaml_parser_set_parser_error(parser, - "did not find expected ", token.start_mark) - return false - } - parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) - parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE - end_mark := token.end_mark - - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - version_directive: version_directive, - tag_directives: tag_directives, - implicit: false, - } - skip_token(parser) - - } else { - // Parse the stream end. - parser.state = yaml_PARSE_END_STATE - *event = yaml_event_t{ - typ: yaml_STREAM_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - skip_token(parser) - } - - return true -} - -// Parse the productions: -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// *********** -// -func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || - token.typ == yaml_TAG_DIRECTIVE_TOKEN || - token.typ == yaml_DOCUMENT_START_TOKEN || - token.typ == yaml_DOCUMENT_END_TOKEN || - token.typ == yaml_STREAM_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - return yaml_parser_process_empty_scalar(parser, event, - token.start_mark) - } - return yaml_parser_parse_node(parser, event, true, false) -} - -// Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// ************* -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// -func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - start_mark := token.start_mark - end_mark := token.start_mark - - implicit := true - if token.typ == yaml_DOCUMENT_END_TOKEN { - end_mark = token.end_mark - skip_token(parser) - implicit = false - } - - parser.tag_directives = parser.tag_directives[:0] - - parser.state = yaml_PARSE_DOCUMENT_START_STATE - *event = yaml_event_t{ - typ: yaml_DOCUMENT_END_EVENT, - start_mark: start_mark, - end_mark: end_mark, - implicit: implicit, - } - yaml_parser_set_event_comments(parser, event) - if len(event.head_comment) > 0 && len(event.foot_comment) == 0 { - event.foot_comment = event.head_comment - event.head_comment = nil - } - return true -} - -func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) { - event.head_comment = parser.head_comment - event.line_comment = parser.line_comment - event.foot_comment = parser.foot_comment - parser.head_comment = nil - parser.line_comment = nil - parser.foot_comment = nil - parser.tail_comment = nil - parser.stem_comment = nil -} - -// Parse the productions: -// block_node_or_indentless_sequence ::= -// ALIAS -// ***** -// | properties (block_content | indentless_block_sequence)? -// ********** * -// | block_content | indentless_block_sequence -// * -// block_node ::= ALIAS -// ***** -// | properties block_content? -// ********** * -// | block_content -// * -// flow_node ::= ALIAS -// ***** -// | properties flow_content? -// ********** * -// | flow_content -// * -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// ************************* -// block_content ::= block_collection | flow_collection | SCALAR -// ****** -// flow_content ::= flow_collection | SCALAR -// ****** -func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { - //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_ALIAS_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - *event = yaml_event_t{ - typ: yaml_ALIAS_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - anchor: token.value, - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true - } - - start_mark := token.start_mark - end_mark := token.start_mark - - var tag_token bool - var tag_handle, tag_suffix, anchor []byte - var tag_mark yaml_mark_t - if token.typ == yaml_ANCHOR_TOKEN { - anchor = token.value - start_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_TAG_TOKEN { - tag_token = true - tag_handle = token.value - tag_suffix = token.suffix - tag_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } else if token.typ == yaml_TAG_TOKEN { - tag_token = true - tag_handle = token.value - tag_suffix = token.suffix - start_mark = token.start_mark - tag_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_ANCHOR_TOKEN { - anchor = token.value - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } - - var tag []byte - if tag_token { - if len(tag_handle) == 0 { - tag = tag_suffix - tag_suffix = nil - } else { - for i := range parser.tag_directives { - if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { - tag = append([]byte(nil), parser.tag_directives[i].prefix...) - tag = append(tag, tag_suffix...) - break - } - } - if len(tag) == 0 { - yaml_parser_set_parser_error_context(parser, - "while parsing a node", start_mark, - "found undefined tag handle", tag_mark) - return false - } - } - } - - implicit := len(tag) == 0 - if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), - } - return true - } - if token.typ == yaml_SCALAR_TOKEN { - var plain_implicit, quoted_implicit bool - end_mark = token.end_mark - if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { - plain_implicit = true - } else if len(tag) == 0 { - quoted_implicit = true - } - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - value: token.value, - implicit: plain_implicit, - quoted_implicit: quoted_implicit, - style: yaml_style_t(token.style), - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true - } - if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { - // [Go] Some of the events below can be merged as they differ only on style. - end_mark = token.end_mark - parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), - } - yaml_parser_set_event_comments(parser, event) - return true - } - if token.typ == yaml_FLOW_MAPPING_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), - } - yaml_parser_set_event_comments(parser, event) - return true - } - if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), - } - if parser.stem_comment != nil { - event.head_comment = parser.stem_comment - parser.stem_comment = nil - } - return true - } - if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), - } - if parser.stem_comment != nil { - event.head_comment = parser.stem_comment - parser.stem_comment = nil - } - return true - } - if len(anchor) > 0 || len(tag) > 0 { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - quoted_implicit: false, - style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), - } - return true - } - - context := "while parsing a flow node" - if block { - context = "while parsing a block node" - } - yaml_parser_set_parser_error_context(parser, context, start_mark, - "did not find expected node content", token.start_mark) - return false -} - -// Parse the productions: -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END -// ******************** *********** * ********* -// -func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - if token == nil { - return false - } - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_BLOCK_ENTRY_TOKEN { - mark := token.end_mark - prior_head_len := len(parser.head_comment) - skip_token(parser) - yaml_parser_split_stem_comment(parser, prior_head_len) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, true, false) - } else { - parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - } - if token.typ == yaml_BLOCK_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - - skip_token(parser) - return true - } - - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a block collection", context_mark, - "did not find expected '-' indicator", token.start_mark) -} - -// Parse the productions: -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ -// *********** * -func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_BLOCK_ENTRY_TOKEN { - mark := token.end_mark - prior_head_len := len(parser.head_comment) - skip_token(parser) - yaml_parser_split_stem_comment(parser, prior_head_len) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_BLOCK_ENTRY_TOKEN && - token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, true, false) - } - parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? - } - return true -} - -// Split stem comment from head comment. -// -// When a sequence or map is found under a sequence entry, the former head comment -// is assigned to the underlying sequence or map as a whole, not the individual -// sequence or map entry as would be expected otherwise. To handle this case the -// previous head comment is moved aside as the stem comment. -func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) { - if stem_len == 0 { - return - } - - token := peek_token(parser) - if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN { - return - } - - parser.stem_comment = parser.head_comment[:stem_len] - if len(parser.head_comment) == stem_len { - parser.head_comment = nil - } else { - // Copy suffix to prevent very strange bugs if someone ever appends - // further bytes to the prefix in the stem_comment slice above. - parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...) - } -} - -// Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START -// ******************* -// ((KEY block_node_or_indentless_sequence?)? -// *** * -// (VALUE block_node_or_indentless_sequence?)?)* -// -// BLOCK-END -// ********* -// -func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - if token == nil { - return false - } - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - // [Go] A tail comment was left from the prior mapping value processed. Emit an event - // as it needs to be processed with that value and not the following key. - if len(parser.tail_comment) > 0 { - *event = yaml_event_t{ - typ: yaml_TAIL_COMMENT_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - foot_comment: parser.tail_comment, - } - parser.tail_comment = nil - return true - } - - if token.typ == yaml_KEY_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, true, true) - } else { - parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - } else if token.typ == yaml_BLOCK_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true - } - - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a block mapping", context_mark, - "did not find expected key", token.start_mark) -} - -// Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START -// -// ((KEY block_node_or_indentless_sequence?)? -// -// (VALUE block_node_or_indentless_sequence?)?)* -// ***** * -// BLOCK-END -// -// -func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_VALUE_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) - return yaml_parser_parse_node(parser, event, true, true) - } - parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Parse the productions: -// flow_sequence ::= FLOW-SEQUENCE-START -// ******************* -// (flow_sequence_entry FLOW-ENTRY)* -// * ********** -// flow_sequence_entry? -// * -// FLOW-SEQUENCE-END -// ***************** -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * -// -func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - if token == nil { - return false - } - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - if !first { - if token.typ == yaml_FLOW_ENTRY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } else { - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow sequence", context_mark, - "did not find expected ',' or ']'", token.start_mark) - } - } - - if token.typ == yaml_KEY_TOKEN { - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - implicit: true, - style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), - } - skip_token(parser) - return true - } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - yaml_parser_set_event_comments(parser, event) - - skip_token(parser) - return true -} - -// -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// *** * -// -func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_FLOW_ENTRY_TOKEN && - token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - mark := token.end_mark - skip_token(parser) - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) -} - -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// ***** * -// -func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_VALUE_TOKEN { - skip_token(parser) - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * -// -func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? - } - return true -} - -// Parse the productions: -// flow_mapping ::= FLOW-MAPPING-START -// ****************** -// (flow_mapping_entry FLOW-ENTRY)* -// * ********** -// flow_mapping_entry? -// ****************** -// FLOW-MAPPING-END -// **************** -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * *** * -// -func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ != yaml_FLOW_MAPPING_END_TOKEN { - if !first { - if token.typ == yaml_FLOW_ENTRY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } else { - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow mapping", context_mark, - "did not find expected ',' or '}'", token.start_mark) - } - } - - if token.typ == yaml_KEY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_FLOW_ENTRY_TOKEN && - token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } else { - parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) - } - } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true -} - -// Parse the productions: -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * ***** * -// -func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { - token := peek_token(parser) - if token == nil { - return false - } - if empty { - parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) - } - if token.typ == yaml_VALUE_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Generate an empty scalar event. -func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: mark, - end_mark: mark, - value: nil, // Empty - implicit: true, - style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), - } - return true -} - -var default_tag_directives = []yaml_tag_directive_t{ - {[]byte("!"), []byte("!")}, - {[]byte("!!"), []byte("tag:yaml.org,2002:")}, -} - -// Parse directives. -func yaml_parser_process_directives(parser *yaml_parser_t, - version_directive_ref **yaml_version_directive_t, - tag_directives_ref *[]yaml_tag_directive_t) bool { - - var version_directive *yaml_version_directive_t - var tag_directives []yaml_tag_directive_t - - token := peek_token(parser) - if token == nil { - return false - } - - for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { - if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { - if version_directive != nil { - yaml_parser_set_parser_error(parser, - "found duplicate %YAML directive", token.start_mark) - return false - } - if token.major != 1 || token.minor != 1 { - yaml_parser_set_parser_error(parser, - "found incompatible YAML document", token.start_mark) - return false - } - version_directive = &yaml_version_directive_t{ - major: token.major, - minor: token.minor, - } - } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { - value := yaml_tag_directive_t{ - handle: token.value, - prefix: token.prefix, - } - if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { - return false - } - tag_directives = append(tag_directives, value) - } - - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - - for i := range default_tag_directives { - if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { - return false - } - } - - if version_directive_ref != nil { - *version_directive_ref = version_directive - } - if tag_directives_ref != nil { - *tag_directives_ref = tag_directives - } - return true -} - -// Append a tag directive to the directives stack. -func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { - for i := range parser.tag_directives { - if bytes.Equal(value.handle, parser.tag_directives[i].handle) { - if allow_duplicates { - return true - } - return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) - } - } - - // [Go] I suspect the copy is unnecessary. This was likely done - // because there was no way to track ownership of the data. - value_copy := yaml_tag_directive_t{ - handle: make([]byte, len(value.handle)), - prefix: make([]byte, len(value.prefix)), - } - copy(value_copy.handle, value.handle) - copy(value_copy.prefix, value.prefix) - parser.tag_directives = append(parser.tag_directives, value_copy) - return true -} diff --git a/vendor/gopkg.in/yaml.v3/readerc.go b/vendor/gopkg.in/yaml.v3/readerc.go deleted file mode 100644 index b7de0a89..00000000 --- a/vendor/gopkg.in/yaml.v3/readerc.go +++ /dev/null @@ -1,434 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -import ( - "io" -) - -// Set the reader error and return 0. -func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool { - parser.error = yaml_READER_ERROR - parser.problem = problem - parser.problem_offset = offset - parser.problem_value = value - return false -} - -// Byte order marks. -const ( - bom_UTF8 = "\xef\xbb\xbf" - bom_UTF16LE = "\xff\xfe" - bom_UTF16BE = "\xfe\xff" -) - -// Determine the input stream encoding by checking the BOM symbol. If no BOM is -// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. -func yaml_parser_determine_encoding(parser *yaml_parser_t) bool { - // Ensure that we had enough bytes in the raw buffer. - for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 { - if !yaml_parser_update_raw_buffer(parser) { - return false - } - } - - // Determine the encoding. - buf := parser.raw_buffer - pos := parser.raw_buffer_pos - avail := len(buf) - pos - if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] { - parser.encoding = yaml_UTF16LE_ENCODING - parser.raw_buffer_pos += 2 - parser.offset += 2 - } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] { - parser.encoding = yaml_UTF16BE_ENCODING - parser.raw_buffer_pos += 2 - parser.offset += 2 - } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] { - parser.encoding = yaml_UTF8_ENCODING - parser.raw_buffer_pos += 3 - parser.offset += 3 - } else { - parser.encoding = yaml_UTF8_ENCODING - } - return true -} - -// Update the raw buffer. -func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool { - size_read := 0 - - // Return if the raw buffer is full. - if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) { - return true - } - - // Return on EOF. - if parser.eof { - return true - } - - // Move the remaining bytes in the raw buffer to the beginning. - if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) { - copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:]) - } - parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos] - parser.raw_buffer_pos = 0 - - // Call the read handler to fill the buffer. - size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)]) - parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read] - if err == io.EOF { - parser.eof = true - } else if err != nil { - return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1) - } - return true -} - -// Ensure that the buffer contains at least `length` characters. -// Return true on success, false on failure. -// -// The length is supposed to be significantly less that the buffer size. -func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { - if parser.read_handler == nil { - panic("read handler must be set") - } - - // [Go] This function was changed to guarantee the requested length size at EOF. - // The fact we need to do this is pretty awful, but the description above implies - // for that to be the case, and there are tests - - // If the EOF flag is set and the raw buffer is empty, do nothing. - if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) { - // [Go] ACTUALLY! Read the documentation of this function above. - // This is just broken. To return true, we need to have the - // given length in the buffer. Not doing that means every single - // check that calls this function to make sure the buffer has a - // given length is Go) panicking; or C) accessing invalid memory. - //return true - } - - // Return if the buffer contains enough characters. - if parser.unread >= length { - return true - } - - // Determine the input encoding if it is not known yet. - if parser.encoding == yaml_ANY_ENCODING { - if !yaml_parser_determine_encoding(parser) { - return false - } - } - - // Move the unread characters to the beginning of the buffer. - buffer_len := len(parser.buffer) - if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len { - copy(parser.buffer, parser.buffer[parser.buffer_pos:]) - buffer_len -= parser.buffer_pos - parser.buffer_pos = 0 - } else if parser.buffer_pos == buffer_len { - buffer_len = 0 - parser.buffer_pos = 0 - } - - // Open the whole buffer for writing, and cut it before returning. - parser.buffer = parser.buffer[:cap(parser.buffer)] - - // Fill the buffer until it has enough characters. - first := true - for parser.unread < length { - - // Fill the raw buffer if necessary. - if !first || parser.raw_buffer_pos == len(parser.raw_buffer) { - if !yaml_parser_update_raw_buffer(parser) { - parser.buffer = parser.buffer[:buffer_len] - return false - } - } - first = false - - // Decode the raw buffer. - inner: - for parser.raw_buffer_pos != len(parser.raw_buffer) { - var value rune - var width int - - raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos - - // Decode the next character. - switch parser.encoding { - case yaml_UTF8_ENCODING: - // Decode a UTF-8 character. Check RFC 3629 - // (http://www.ietf.org/rfc/rfc3629.txt) for more details. - // - // The following table (taken from the RFC) is used for - // decoding. - // - // Char. number range | UTF-8 octet sequence - // (hexadecimal) | (binary) - // --------------------+------------------------------------ - // 0000 0000-0000 007F | 0xxxxxxx - // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx - // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx - // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - // - // Additionally, the characters in the range 0xD800-0xDFFF - // are prohibited as they are reserved for use with UTF-16 - // surrogate pairs. - - // Determine the length of the UTF-8 sequence. - octet := parser.raw_buffer[parser.raw_buffer_pos] - switch { - case octet&0x80 == 0x00: - width = 1 - case octet&0xE0 == 0xC0: - width = 2 - case octet&0xF0 == 0xE0: - width = 3 - case octet&0xF8 == 0xF0: - width = 4 - default: - // The leading octet is invalid. - return yaml_parser_set_reader_error(parser, - "invalid leading UTF-8 octet", - parser.offset, int(octet)) - } - - // Check if the raw buffer contains an incomplete character. - if width > raw_unread { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-8 octet sequence", - parser.offset, -1) - } - break inner - } - - // Decode the leading octet. - switch { - case octet&0x80 == 0x00: - value = rune(octet & 0x7F) - case octet&0xE0 == 0xC0: - value = rune(octet & 0x1F) - case octet&0xF0 == 0xE0: - value = rune(octet & 0x0F) - case octet&0xF8 == 0xF0: - value = rune(octet & 0x07) - default: - value = 0 - } - - // Check and decode the trailing octets. - for k := 1; k < width; k++ { - octet = parser.raw_buffer[parser.raw_buffer_pos+k] - - // Check if the octet is valid. - if (octet & 0xC0) != 0x80 { - return yaml_parser_set_reader_error(parser, - "invalid trailing UTF-8 octet", - parser.offset+k, int(octet)) - } - - // Decode the octet. - value = (value << 6) + rune(octet&0x3F) - } - - // Check the length of the sequence against the value. - switch { - case width == 1: - case width == 2 && value >= 0x80: - case width == 3 && value >= 0x800: - case width == 4 && value >= 0x10000: - default: - return yaml_parser_set_reader_error(parser, - "invalid length of a UTF-8 sequence", - parser.offset, -1) - } - - // Check the range of the value. - if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF { - return yaml_parser_set_reader_error(parser, - "invalid Unicode character", - parser.offset, int(value)) - } - - case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING: - var low, high int - if parser.encoding == yaml_UTF16LE_ENCODING { - low, high = 0, 1 - } else { - low, high = 1, 0 - } - - // The UTF-16 encoding is not as simple as one might - // naively think. Check RFC 2781 - // (http://www.ietf.org/rfc/rfc2781.txt). - // - // Normally, two subsequent bytes describe a Unicode - // character. However a special technique (called a - // surrogate pair) is used for specifying character - // values larger than 0xFFFF. - // - // A surrogate pair consists of two pseudo-characters: - // high surrogate area (0xD800-0xDBFF) - // low surrogate area (0xDC00-0xDFFF) - // - // The following formulas are used for decoding - // and encoding characters using surrogate pairs: - // - // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) - // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) - // W1 = 110110yyyyyyyyyy - // W2 = 110111xxxxxxxxxx - // - // where U is the character value, W1 is the high surrogate - // area, W2 is the low surrogate area. - - // Check for incomplete UTF-16 character. - if raw_unread < 2 { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 character", - parser.offset, -1) - } - break inner - } - - // Get the character. - value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) + - (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8) - - // Check for unexpected low surrogate area. - if value&0xFC00 == 0xDC00 { - return yaml_parser_set_reader_error(parser, - "unexpected low surrogate area", - parser.offset, int(value)) - } - - // Check for a high surrogate area. - if value&0xFC00 == 0xD800 { - width = 4 - - // Check for incomplete surrogate pair. - if raw_unread < 4 { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 surrogate pair", - parser.offset, -1) - } - break inner - } - - // Get the next character. - value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) + - (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8) - - // Check for a low surrogate area. - if value2&0xFC00 != 0xDC00 { - return yaml_parser_set_reader_error(parser, - "expected low surrogate area", - parser.offset+2, int(value2)) - } - - // Generate the value of the surrogate pair. - value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF) - } else { - width = 2 - } - - default: - panic("impossible") - } - - // Check if the character is in the allowed range: - // #x9 | #xA | #xD | [#x20-#x7E] (8 bit) - // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) - // | [#x10000-#x10FFFF] (32 bit) - switch { - case value == 0x09: - case value == 0x0A: - case value == 0x0D: - case value >= 0x20 && value <= 0x7E: - case value == 0x85: - case value >= 0xA0 && value <= 0xD7FF: - case value >= 0xE000 && value <= 0xFFFD: - case value >= 0x10000 && value <= 0x10FFFF: - default: - return yaml_parser_set_reader_error(parser, - "control characters are not allowed", - parser.offset, int(value)) - } - - // Move the raw pointers. - parser.raw_buffer_pos += width - parser.offset += width - - // Finally put the character into the buffer. - if value <= 0x7F { - // 0000 0000-0000 007F . 0xxxxxxx - parser.buffer[buffer_len+0] = byte(value) - buffer_len += 1 - } else if value <= 0x7FF { - // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6)) - parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F)) - buffer_len += 2 - } else if value <= 0xFFFF { - // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12)) - parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F)) - parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F)) - buffer_len += 3 - } else { - // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18)) - parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F)) - parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F)) - parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F)) - buffer_len += 4 - } - - parser.unread++ - } - - // On EOF, put NUL into the buffer and return. - if parser.eof { - parser.buffer[buffer_len] = 0 - buffer_len++ - parser.unread++ - break - } - } - // [Go] Read the documentation of this function above. To return true, - // we need to have the given length in the buffer. Not doing that means - // every single check that calls this function to make sure the buffer - // has a given length is Go) panicking; or C) accessing invalid memory. - // This happens here due to the EOF above breaking early. - for buffer_len < length { - parser.buffer[buffer_len] = 0 - buffer_len++ - } - parser.buffer = parser.buffer[:buffer_len] - return true -} diff --git a/vendor/gopkg.in/yaml.v3/resolve.go b/vendor/gopkg.in/yaml.v3/resolve.go deleted file mode 100644 index 64ae8880..00000000 --- a/vendor/gopkg.in/yaml.v3/resolve.go +++ /dev/null @@ -1,326 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// 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 yaml - -import ( - "encoding/base64" - "math" - "regexp" - "strconv" - "strings" - "time" -) - -type resolveMapItem struct { - value interface{} - tag string -} - -var resolveTable = make([]byte, 256) -var resolveMap = make(map[string]resolveMapItem) - -func init() { - t := resolveTable - t[int('+')] = 'S' // Sign - t[int('-')] = 'S' - for _, c := range "0123456789" { - t[int(c)] = 'D' // Digit - } - for _, c := range "yYnNtTfFoO~" { - t[int(c)] = 'M' // In map - } - t[int('.')] = '.' // Float (potentially in map) - - var resolveMapList = []struct { - v interface{} - tag string - l []string - }{ - {true, boolTag, []string{"true", "True", "TRUE"}}, - {false, boolTag, []string{"false", "False", "FALSE"}}, - {nil, nullTag, []string{"", "~", "null", "Null", "NULL"}}, - {math.NaN(), floatTag, []string{".nan", ".NaN", ".NAN"}}, - {math.Inf(+1), floatTag, []string{".inf", ".Inf", ".INF"}}, - {math.Inf(+1), floatTag, []string{"+.inf", "+.Inf", "+.INF"}}, - {math.Inf(-1), floatTag, []string{"-.inf", "-.Inf", "-.INF"}}, - {"<<", mergeTag, []string{"<<"}}, - } - - m := resolveMap - for _, item := range resolveMapList { - for _, s := range item.l { - m[s] = resolveMapItem{item.v, item.tag} - } - } -} - -const ( - nullTag = "!!null" - boolTag = "!!bool" - strTag = "!!str" - intTag = "!!int" - floatTag = "!!float" - timestampTag = "!!timestamp" - seqTag = "!!seq" - mapTag = "!!map" - binaryTag = "!!binary" - mergeTag = "!!merge" -) - -var longTags = make(map[string]string) -var shortTags = make(map[string]string) - -func init() { - for _, stag := range []string{nullTag, boolTag, strTag, intTag, floatTag, timestampTag, seqTag, mapTag, binaryTag, mergeTag} { - ltag := longTag(stag) - longTags[stag] = ltag - shortTags[ltag] = stag - } -} - -const longTagPrefix = "tag:yaml.org,2002:" - -func shortTag(tag string) string { - if strings.HasPrefix(tag, longTagPrefix) { - if stag, ok := shortTags[tag]; ok { - return stag - } - return "!!" + tag[len(longTagPrefix):] - } - return tag -} - -func longTag(tag string) string { - if strings.HasPrefix(tag, "!!") { - if ltag, ok := longTags[tag]; ok { - return ltag - } - return longTagPrefix + tag[2:] - } - return tag -} - -func resolvableTag(tag string) bool { - switch tag { - case "", strTag, boolTag, intTag, floatTag, nullTag, timestampTag: - return true - } - return false -} - -var yamlStyleFloat = regexp.MustCompile(`^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$`) - -func resolve(tag string, in string) (rtag string, out interface{}) { - tag = shortTag(tag) - if !resolvableTag(tag) { - return tag, in - } - - defer func() { - switch tag { - case "", rtag, strTag, binaryTag: - return - case floatTag: - if rtag == intTag { - switch v := out.(type) { - case int64: - rtag = floatTag - out = float64(v) - return - case int: - rtag = floatTag - out = float64(v) - return - } - } - } - failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) - }() - - // Any data is accepted as a !!str or !!binary. - // Otherwise, the prefix is enough of a hint about what it might be. - hint := byte('N') - if in != "" { - hint = resolveTable[in[0]] - } - if hint != 0 && tag != strTag && tag != binaryTag { - // Handle things we can lookup in a map. - if item, ok := resolveMap[in]; ok { - return item.tag, item.value - } - - // Base 60 floats are a bad idea, were dropped in YAML 1.2, and - // are purposefully unsupported here. They're still quoted on - // the way out for compatibility with other parser, though. - - switch hint { - case 'M': - // We've already checked the map above. - - case '.': - // Not in the map, so maybe a normal float. - floatv, err := strconv.ParseFloat(in, 64) - if err == nil { - return floatTag, floatv - } - - case 'D', 'S': - // Int, float, or timestamp. - // Only try values as a timestamp if the value is unquoted or there's an explicit - // !!timestamp tag. - if tag == "" || tag == timestampTag { - t, ok := parseTimestamp(in) - if ok { - return timestampTag, t - } - } - - plain := strings.Replace(in, "_", "", -1) - intv, err := strconv.ParseInt(plain, 0, 64) - if err == nil { - if intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - uintv, err := strconv.ParseUint(plain, 0, 64) - if err == nil { - return intTag, uintv - } - if yamlStyleFloat.MatchString(plain) { - floatv, err := strconv.ParseFloat(plain, 64) - if err == nil { - return floatTag, floatv - } - } - if strings.HasPrefix(plain, "0b") { - intv, err := strconv.ParseInt(plain[2:], 2, 64) - if err == nil { - if intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - uintv, err := strconv.ParseUint(plain[2:], 2, 64) - if err == nil { - return intTag, uintv - } - } else if strings.HasPrefix(plain, "-0b") { - intv, err := strconv.ParseInt("-"+plain[3:], 2, 64) - if err == nil { - if true || intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - } - // Octals as introduced in version 1.2 of the spec. - // Octals from the 1.1 spec, spelled as 0777, are still - // decoded by default in v3 as well for compatibility. - // May be dropped in v4 depending on how usage evolves. - if strings.HasPrefix(plain, "0o") { - intv, err := strconv.ParseInt(plain[2:], 8, 64) - if err == nil { - if intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - uintv, err := strconv.ParseUint(plain[2:], 8, 64) - if err == nil { - return intTag, uintv - } - } else if strings.HasPrefix(plain, "-0o") { - intv, err := strconv.ParseInt("-"+plain[3:], 8, 64) - if err == nil { - if true || intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - } - default: - panic("internal error: missing handler for resolver table: " + string(rune(hint)) + " (with " + in + ")") - } - } - return strTag, in -} - -// encodeBase64 encodes s as base64 that is broken up into multiple lines -// as appropriate for the resulting length. -func encodeBase64(s string) string { - const lineLen = 70 - encLen := base64.StdEncoding.EncodedLen(len(s)) - lines := encLen/lineLen + 1 - buf := make([]byte, encLen*2+lines) - in := buf[0:encLen] - out := buf[encLen:] - base64.StdEncoding.Encode(in, []byte(s)) - k := 0 - for i := 0; i < len(in); i += lineLen { - j := i + lineLen - if j > len(in) { - j = len(in) - } - k += copy(out[k:], in[i:j]) - if lines > 1 { - out[k] = '\n' - k++ - } - } - return string(out[:k]) -} - -// This is a subset of the formats allowed by the regular expression -// defined at http://yaml.org/type/timestamp.html. -var allowedTimestampFormats = []string{ - "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields. - "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t". - "2006-1-2 15:4:5.999999999", // space separated with no time zone - "2006-1-2", // date only - // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5" - // from the set of examples. -} - -// parseTimestamp parses s as a timestamp string and -// returns the timestamp and reports whether it succeeded. -// Timestamp formats are defined at http://yaml.org/type/timestamp.html -func parseTimestamp(s string) (time.Time, bool) { - // TODO write code to check all the formats supported by - // http://yaml.org/type/timestamp.html instead of using time.Parse. - - // Quick check: all date formats start with YYYY-. - i := 0 - for ; i < len(s); i++ { - if c := s[i]; c < '0' || c > '9' { - break - } - } - if i != 4 || i == len(s) || s[i] != '-' { - return time.Time{}, false - } - for _, format := range allowedTimestampFormats { - if t, err := time.Parse(format, s); err == nil { - return t, true - } - } - return time.Time{}, false -} diff --git a/vendor/gopkg.in/yaml.v3/scannerc.go b/vendor/gopkg.in/yaml.v3/scannerc.go deleted file mode 100644 index ca007010..00000000 --- a/vendor/gopkg.in/yaml.v3/scannerc.go +++ /dev/null @@ -1,3038 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -import ( - "bytes" - "fmt" -) - -// Introduction -// ************ -// -// The following notes assume that you are familiar with the YAML specification -// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in -// some cases we are less restrictive that it requires. -// -// The process of transforming a YAML stream into a sequence of events is -// divided on two steps: Scanning and Parsing. -// -// The Scanner transforms the input stream into a sequence of tokens, while the -// parser transform the sequence of tokens produced by the Scanner into a -// sequence of parsing events. -// -// The Scanner is rather clever and complicated. The Parser, on the contrary, -// is a straightforward implementation of a recursive-descendant parser (or, -// LL(1) parser, as it is usually called). -// -// Actually there are two issues of Scanning that might be called "clever", the -// rest is quite straightforward. The issues are "block collection start" and -// "simple keys". Both issues are explained below in details. -// -// Here the Scanning step is explained and implemented. We start with the list -// of all the tokens produced by the Scanner together with short descriptions. -// -// Now, tokens: -// -// STREAM-START(encoding) # The stream start. -// STREAM-END # The stream end. -// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. -// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. -// DOCUMENT-START # '---' -// DOCUMENT-END # '...' -// BLOCK-SEQUENCE-START # Indentation increase denoting a block -// BLOCK-MAPPING-START # sequence or a block mapping. -// BLOCK-END # Indentation decrease. -// FLOW-SEQUENCE-START # '[' -// FLOW-SEQUENCE-END # ']' -// BLOCK-SEQUENCE-START # '{' -// BLOCK-SEQUENCE-END # '}' -// BLOCK-ENTRY # '-' -// FLOW-ENTRY # ',' -// KEY # '?' or nothing (simple keys). -// VALUE # ':' -// ALIAS(anchor) # '*anchor' -// ANCHOR(anchor) # '&anchor' -// TAG(handle,suffix) # '!handle!suffix' -// SCALAR(value,style) # A scalar. -// -// The following two tokens are "virtual" tokens denoting the beginning and the -// end of the stream: -// -// STREAM-START(encoding) -// STREAM-END -// -// We pass the information about the input stream encoding with the -// STREAM-START token. -// -// The next two tokens are responsible for tags: -// -// VERSION-DIRECTIVE(major,minor) -// TAG-DIRECTIVE(handle,prefix) -// -// Example: -// -// %YAML 1.1 -// %TAG ! !foo -// %TAG !yaml! tag:yaml.org,2002: -// --- -// -// The correspoding sequence of tokens: -// -// STREAM-START(utf-8) -// VERSION-DIRECTIVE(1,1) -// TAG-DIRECTIVE("!","!foo") -// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") -// DOCUMENT-START -// STREAM-END -// -// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole -// line. -// -// The document start and end indicators are represented by: -// -// DOCUMENT-START -// DOCUMENT-END -// -// Note that if a YAML stream contains an implicit document (without '---' -// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be -// produced. -// -// In the following examples, we present whole documents together with the -// produced tokens. -// -// 1. An implicit document: -// -// 'a scalar' -// -// Tokens: -// -// STREAM-START(utf-8) -// SCALAR("a scalar",single-quoted) -// STREAM-END -// -// 2. An explicit document: -// -// --- -// 'a scalar' -// ... -// -// Tokens: -// -// STREAM-START(utf-8) -// DOCUMENT-START -// SCALAR("a scalar",single-quoted) -// DOCUMENT-END -// STREAM-END -// -// 3. Several documents in a stream: -// -// 'a scalar' -// --- -// 'another scalar' -// --- -// 'yet another scalar' -// -// Tokens: -// -// STREAM-START(utf-8) -// SCALAR("a scalar",single-quoted) -// DOCUMENT-START -// SCALAR("another scalar",single-quoted) -// DOCUMENT-START -// SCALAR("yet another scalar",single-quoted) -// STREAM-END -// -// We have already introduced the SCALAR token above. The following tokens are -// used to describe aliases, anchors, tag, and scalars: -// -// ALIAS(anchor) -// ANCHOR(anchor) -// TAG(handle,suffix) -// SCALAR(value,style) -// -// The following series of examples illustrate the usage of these tokens: -// -// 1. A recursive sequence: -// -// &A [ *A ] -// -// Tokens: -// -// STREAM-START(utf-8) -// ANCHOR("A") -// FLOW-SEQUENCE-START -// ALIAS("A") -// FLOW-SEQUENCE-END -// STREAM-END -// -// 2. A tagged scalar: -// -// !!float "3.14" # A good approximation. -// -// Tokens: -// -// STREAM-START(utf-8) -// TAG("!!","float") -// SCALAR("3.14",double-quoted) -// STREAM-END -// -// 3. Various scalar styles: -// -// --- # Implicit empty plain scalars do not produce tokens. -// --- a plain scalar -// --- 'a single-quoted scalar' -// --- "a double-quoted scalar" -// --- |- -// a literal scalar -// --- >- -// a folded -// scalar -// -// Tokens: -// -// STREAM-START(utf-8) -// DOCUMENT-START -// DOCUMENT-START -// SCALAR("a plain scalar",plain) -// DOCUMENT-START -// SCALAR("a single-quoted scalar",single-quoted) -// DOCUMENT-START -// SCALAR("a double-quoted scalar",double-quoted) -// DOCUMENT-START -// SCALAR("a literal scalar",literal) -// DOCUMENT-START -// SCALAR("a folded scalar",folded) -// STREAM-END -// -// Now it's time to review collection-related tokens. We will start with -// flow collections: -// -// FLOW-SEQUENCE-START -// FLOW-SEQUENCE-END -// FLOW-MAPPING-START -// FLOW-MAPPING-END -// FLOW-ENTRY -// KEY -// VALUE -// -// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and -// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' -// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the -// indicators '?' and ':', which are used for denoting mapping keys and values, -// are represented by the KEY and VALUE tokens. -// -// The following examples show flow collections: -// -// 1. A flow sequence: -// -// [item 1, item 2, item 3] -// -// Tokens: -// -// STREAM-START(utf-8) -// FLOW-SEQUENCE-START -// SCALAR("item 1",plain) -// FLOW-ENTRY -// SCALAR("item 2",plain) -// FLOW-ENTRY -// SCALAR("item 3",plain) -// FLOW-SEQUENCE-END -// STREAM-END -// -// 2. A flow mapping: -// -// { -// a simple key: a value, # Note that the KEY token is produced. -// ? a complex key: another value, -// } -// -// Tokens: -// -// STREAM-START(utf-8) -// FLOW-MAPPING-START -// KEY -// SCALAR("a simple key",plain) -// VALUE -// SCALAR("a value",plain) -// FLOW-ENTRY -// KEY -// SCALAR("a complex key",plain) -// VALUE -// SCALAR("another value",plain) -// FLOW-ENTRY -// FLOW-MAPPING-END -// STREAM-END -// -// A simple key is a key which is not denoted by the '?' indicator. Note that -// the Scanner still produce the KEY token whenever it encounters a simple key. -// -// For scanning block collections, the following tokens are used (note that we -// repeat KEY and VALUE here): -// -// BLOCK-SEQUENCE-START -// BLOCK-MAPPING-START -// BLOCK-END -// BLOCK-ENTRY -// KEY -// VALUE -// -// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation -// increase that precedes a block collection (cf. the INDENT token in Python). -// The token BLOCK-END denote indentation decrease that ends a block collection -// (cf. the DEDENT token in Python). However YAML has some syntax pecularities -// that makes detections of these tokens more complex. -// -// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators -// '-', '?', and ':' correspondingly. -// -// The following examples show how the tokens BLOCK-SEQUENCE-START, -// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: -// -// 1. Block sequences: -// -// - item 1 -// - item 2 -// - -// - item 3.1 -// - item 3.2 -// - -// key 1: value 1 -// key 2: value 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-ENTRY -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 3.1",plain) -// BLOCK-ENTRY -// SCALAR("item 3.2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// 2. Block mappings: -// -// a simple key: a value # The KEY token is produced here. -// ? a complex key -// : another value -// a mapping: -// key 1: value 1 -// key 2: value 2 -// a sequence: -// - item 1 -// - item 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("a simple key",plain) -// VALUE -// SCALAR("a value",plain) -// KEY -// SCALAR("a complex key",plain) -// VALUE -// SCALAR("another value",plain) -// KEY -// SCALAR("a mapping",plain) -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// KEY -// SCALAR("a sequence",plain) -// VALUE -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// YAML does not always require to start a new block collection from a new -// line. If the current line contains only '-', '?', and ':' indicators, a new -// block collection may start at the current line. The following examples -// illustrate this case: -// -// 1. Collections in a sequence: -// -// - - item 1 -// - item 2 -// - key 1: value 1 -// key 2: value 2 -// - ? complex key -// : complex value -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("complex key") -// VALUE -// SCALAR("complex value") -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// 2. Collections in a mapping: -// -// ? a sequence -// : - item 1 -// - item 2 -// ? a mapping -// : key 1: value 1 -// key 2: value 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("a sequence",plain) -// VALUE -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// KEY -// SCALAR("a mapping",plain) -// VALUE -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// YAML also permits non-indented sequences if they are included into a block -// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: -// -// key: -// - item 1 # BLOCK-SEQUENCE-START is NOT produced here. -// - item 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("key",plain) -// VALUE -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// - -// Ensure that the buffer contains the required number of characters. -// Return true on success, false on failure (reader error or memory error). -func cache(parser *yaml_parser_t, length int) bool { - // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B) - return parser.unread >= length || yaml_parser_update_buffer(parser, length) -} - -// Advance the buffer pointer. -func skip(parser *yaml_parser_t) { - if !is_blank(parser.buffer, parser.buffer_pos) { - parser.newlines = 0 - } - parser.mark.index++ - parser.mark.column++ - parser.unread-- - parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) -} - -func skip_line(parser *yaml_parser_t) { - if is_crlf(parser.buffer, parser.buffer_pos) { - parser.mark.index += 2 - parser.mark.column = 0 - parser.mark.line++ - parser.unread -= 2 - parser.buffer_pos += 2 - parser.newlines++ - } else if is_break(parser.buffer, parser.buffer_pos) { - parser.mark.index++ - parser.mark.column = 0 - parser.mark.line++ - parser.unread-- - parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) - parser.newlines++ - } -} - -// Copy a character to a string buffer and advance pointers. -func read(parser *yaml_parser_t, s []byte) []byte { - if !is_blank(parser.buffer, parser.buffer_pos) { - parser.newlines = 0 - } - w := width(parser.buffer[parser.buffer_pos]) - if w == 0 { - panic("invalid character sequence") - } - if len(s) == 0 { - s = make([]byte, 0, 32) - } - if w == 1 && len(s)+w <= cap(s) { - s = s[:len(s)+1] - s[len(s)-1] = parser.buffer[parser.buffer_pos] - parser.buffer_pos++ - } else { - s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...) - parser.buffer_pos += w - } - parser.mark.index++ - parser.mark.column++ - parser.unread-- - return s -} - -// Copy a line break character to a string buffer and advance pointers. -func read_line(parser *yaml_parser_t, s []byte) []byte { - buf := parser.buffer - pos := parser.buffer_pos - switch { - case buf[pos] == '\r' && buf[pos+1] == '\n': - // CR LF . LF - s = append(s, '\n') - parser.buffer_pos += 2 - parser.mark.index++ - parser.unread-- - case buf[pos] == '\r' || buf[pos] == '\n': - // CR|LF . LF - s = append(s, '\n') - parser.buffer_pos += 1 - case buf[pos] == '\xC2' && buf[pos+1] == '\x85': - // NEL . LF - s = append(s, '\n') - parser.buffer_pos += 2 - case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'): - // LS|PS . LS|PS - s = append(s, buf[parser.buffer_pos:pos+3]...) - parser.buffer_pos += 3 - default: - return s - } - parser.mark.index++ - parser.mark.column = 0 - parser.mark.line++ - parser.unread-- - parser.newlines++ - return s -} - -// Get the next token. -func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool { - // Erase the token object. - *token = yaml_token_t{} // [Go] Is this necessary? - - // No tokens after STREAM-END or error. - if parser.stream_end_produced || parser.error != yaml_NO_ERROR { - return true - } - - // Ensure that the tokens queue contains enough tokens. - if !parser.token_available { - if !yaml_parser_fetch_more_tokens(parser) { - return false - } - } - - // Fetch the next token from the queue. - *token = parser.tokens[parser.tokens_head] - parser.tokens_head++ - parser.tokens_parsed++ - parser.token_available = false - - if token.typ == yaml_STREAM_END_TOKEN { - parser.stream_end_produced = true - } - return true -} - -// Set the scanner error and return false. -func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool { - parser.error = yaml_SCANNER_ERROR - parser.context = context - parser.context_mark = context_mark - parser.problem = problem - parser.problem_mark = parser.mark - return false -} - -func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool { - context := "while parsing a tag" - if directive { - context = "while parsing a %TAG directive" - } - return yaml_parser_set_scanner_error(parser, context, context_mark, problem) -} - -func trace(args ...interface{}) func() { - pargs := append([]interface{}{"+++"}, args...) - fmt.Println(pargs...) - pargs = append([]interface{}{"---"}, args...) - return func() { fmt.Println(pargs...) } -} - -// Ensure that the tokens queue contains at least one token which can be -// returned to the Parser. -func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { - // While we need more tokens to fetch, do it. - for { - // [Go] The comment parsing logic requires a lookahead of two tokens - // so that foot comments may be parsed in time of associating them - // with the tokens that are parsed before them, and also for line - // comments to be transformed into head comments in some edge cases. - if parser.tokens_head < len(parser.tokens)-2 { - // If a potential simple key is at the head position, we need to fetch - // the next token to disambiguate it. - head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed] - if !ok { - break - } else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok { - return false - } else if !valid { - break - } - } - // Fetch the next token. - if !yaml_parser_fetch_next_token(parser) { - return false - } - } - - parser.token_available = true - return true -} - -// The dispatcher for token fetchers. -func yaml_parser_fetch_next_token(parser *yaml_parser_t) (ok bool) { - // Ensure that the buffer is initialized. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check if we just started scanning. Fetch STREAM-START then. - if !parser.stream_start_produced { - return yaml_parser_fetch_stream_start(parser) - } - - scan_mark := parser.mark - - // Eat whitespaces and comments until we reach the next token. - if !yaml_parser_scan_to_next_token(parser) { - return false - } - - // [Go] While unrolling indents, transform the head comments of prior - // indentation levels observed after scan_start into foot comments at - // the respective indexes. - - // Check the indentation level against the current column. - if !yaml_parser_unroll_indent(parser, parser.mark.column, scan_mark) { - return false - } - - // Ensure that the buffer contains at least 4 characters. 4 is the length - // of the longest indicators ('--- ' and '... '). - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - - // Is it the end of the stream? - if is_z(parser.buffer, parser.buffer_pos) { - return yaml_parser_fetch_stream_end(parser) - } - - // Is it a directive? - if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' { - return yaml_parser_fetch_directive(parser) - } - - buf := parser.buffer - pos := parser.buffer_pos - - // Is it the document start indicator? - if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) { - return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN) - } - - // Is it the document end indicator? - if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) { - return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN) - } - - comment_mark := parser.mark - if len(parser.tokens) > 0 && (parser.flow_level == 0 && buf[pos] == ':' || parser.flow_level > 0 && buf[pos] == ',') { - // Associate any following comments with the prior token. - comment_mark = parser.tokens[len(parser.tokens)-1].start_mark - } - defer func() { - if !ok { - return - } - if len(parser.tokens) > 0 && parser.tokens[len(parser.tokens)-1].typ == yaml_BLOCK_ENTRY_TOKEN { - // Sequence indicators alone have no line comments. It becomes - // a head comment for whatever follows. - return - } - if !yaml_parser_scan_line_comment(parser, comment_mark) { - ok = false - return - } - }() - - // Is it the flow sequence start indicator? - if buf[pos] == '[' { - return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN) - } - - // Is it the flow mapping start indicator? - if parser.buffer[parser.buffer_pos] == '{' { - return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN) - } - - // Is it the flow sequence end indicator? - if parser.buffer[parser.buffer_pos] == ']' { - return yaml_parser_fetch_flow_collection_end(parser, - yaml_FLOW_SEQUENCE_END_TOKEN) - } - - // Is it the flow mapping end indicator? - if parser.buffer[parser.buffer_pos] == '}' { - return yaml_parser_fetch_flow_collection_end(parser, - yaml_FLOW_MAPPING_END_TOKEN) - } - - // Is it the flow entry indicator? - if parser.buffer[parser.buffer_pos] == ',' { - return yaml_parser_fetch_flow_entry(parser) - } - - // Is it the block entry indicator? - if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) { - return yaml_parser_fetch_block_entry(parser) - } - - // Is it the key indicator? - if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_key(parser) - } - - // Is it the value indicator? - if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_value(parser) - } - - // Is it an alias? - if parser.buffer[parser.buffer_pos] == '*' { - return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN) - } - - // Is it an anchor? - if parser.buffer[parser.buffer_pos] == '&' { - return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN) - } - - // Is it a tag? - if parser.buffer[parser.buffer_pos] == '!' { - return yaml_parser_fetch_tag(parser) - } - - // Is it a literal scalar? - if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 { - return yaml_parser_fetch_block_scalar(parser, true) - } - - // Is it a folded scalar? - if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 { - return yaml_parser_fetch_block_scalar(parser, false) - } - - // Is it a single-quoted scalar? - if parser.buffer[parser.buffer_pos] == '\'' { - return yaml_parser_fetch_flow_scalar(parser, true) - } - - // Is it a double-quoted scalar? - if parser.buffer[parser.buffer_pos] == '"' { - return yaml_parser_fetch_flow_scalar(parser, false) - } - - // Is it a plain scalar? - // - // A plain scalar may start with any non-blank characters except - // - // '-', '?', ':', ',', '[', ']', '{', '}', - // '#', '&', '*', '!', '|', '>', '\'', '\"', - // '%', '@', '`'. - // - // In the block context (and, for the '-' indicator, in the flow context - // too), it may also start with the characters - // - // '-', '?', ':' - // - // if it is followed by a non-space character. - // - // The last rule is more restrictive than the specification requires. - // [Go] TODO Make this logic more reasonable. - //switch parser.buffer[parser.buffer_pos] { - //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`': - //} - if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' || - parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' || - parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || - parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' || - parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' || - parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' || - parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' || - parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' || - parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') || - (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) || - (parser.flow_level == 0 && - (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') && - !is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_plain_scalar(parser) - } - - // If we don't determine the token type so far, it is an error. - return yaml_parser_set_scanner_error(parser, - "while scanning for the next token", parser.mark, - "found character that cannot start any token") -} - -func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) { - if !simple_key.possible { - return false, true - } - - // The 1.2 specification says: - // - // "If the ? indicator is omitted, parsing needs to see past the - // implicit key to recognize it as such. To limit the amount of - // lookahead required, the “:” indicator must appear at most 1024 - // Unicode characters beyond the start of the key. In addition, the key - // is restricted to a single line." - // - if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index { - // Check if the potential simple key to be removed is required. - if simple_key.required { - return false, yaml_parser_set_scanner_error(parser, - "while scanning a simple key", simple_key.mark, - "could not find expected ':'") - } - simple_key.possible = false - return false, true - } - return true, true -} - -// Check if a simple key may start at the current position and add it if -// needed. -func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { - // A simple key is required at the current position if the scanner is in - // the block context and the current column coincides with the indentation - // level. - - required := parser.flow_level == 0 && parser.indent == parser.mark.column - - // - // If the current position may start a simple key, save it. - // - if parser.simple_key_allowed { - simple_key := yaml_simple_key_t{ - possible: true, - required: required, - token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), - mark: parser.mark, - } - - if !yaml_parser_remove_simple_key(parser) { - return false - } - parser.simple_keys[len(parser.simple_keys)-1] = simple_key - parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1 - } - return true -} - -// Remove a potential simple key at the current flow level. -func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool { - i := len(parser.simple_keys) - 1 - if parser.simple_keys[i].possible { - // If the key is required, it is an error. - if parser.simple_keys[i].required { - return yaml_parser_set_scanner_error(parser, - "while scanning a simple key", parser.simple_keys[i].mark, - "could not find expected ':'") - } - // Remove the key from the stack. - parser.simple_keys[i].possible = false - delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number) - } - return true -} - -// max_flow_level limits the flow_level -const max_flow_level = 10000 - -// Increase the flow level and resize the simple key list if needed. -func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { - // Reset the simple key on the next level. - parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{ - possible: false, - required: false, - token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), - mark: parser.mark, - }) - - // Increase the flow level. - parser.flow_level++ - if parser.flow_level > max_flow_level { - return yaml_parser_set_scanner_error(parser, - "while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark, - fmt.Sprintf("exceeded max depth of %d", max_flow_level)) - } - return true -} - -// Decrease the flow level. -func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { - if parser.flow_level > 0 { - parser.flow_level-- - last := len(parser.simple_keys) - 1 - delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number) - parser.simple_keys = parser.simple_keys[:last] - } - return true -} - -// max_indents limits the indents stack size -const max_indents = 10000 - -// Push the current indentation level to the stack and set the new level -// the current column is greater than the indentation level. In this case, -// append or insert the specified token into the token queue. -func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool { - // In the flow context, do nothing. - if parser.flow_level > 0 { - return true - } - - if parser.indent < column { - // Push the current indentation level to the stack and set the new - // indentation level. - parser.indents = append(parser.indents, parser.indent) - parser.indent = column - if len(parser.indents) > max_indents { - return yaml_parser_set_scanner_error(parser, - "while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark, - fmt.Sprintf("exceeded max depth of %d", max_indents)) - } - - // Create a token and insert it into the queue. - token := yaml_token_t{ - typ: typ, - start_mark: mark, - end_mark: mark, - } - if number > -1 { - number -= parser.tokens_parsed - } - yaml_insert_token(parser, number, &token) - } - return true -} - -// Pop indentation levels from the indents stack until the current level -// becomes less or equal to the column. For each indentation level, append -// the BLOCK-END token. -func yaml_parser_unroll_indent(parser *yaml_parser_t, column int, scan_mark yaml_mark_t) bool { - // In the flow context, do nothing. - if parser.flow_level > 0 { - return true - } - - block_mark := scan_mark - block_mark.index-- - - // Loop through the indentation levels in the stack. - for parser.indent > column { - - // [Go] Reposition the end token before potential following - // foot comments of parent blocks. For that, search - // backwards for recent comments that were at the same - // indent as the block that is ending now. - stop_index := block_mark.index - for i := len(parser.comments) - 1; i >= 0; i-- { - comment := &parser.comments[i] - - if comment.end_mark.index < stop_index { - // Don't go back beyond the start of the comment/whitespace scan, unless column < 0. - // If requested indent column is < 0, then the document is over and everything else - // is a foot anyway. - break - } - if comment.start_mark.column == parser.indent+1 { - // This is a good match. But maybe there's a former comment - // at that same indent level, so keep searching. - block_mark = comment.start_mark - } - - // While the end of the former comment matches with - // the start of the following one, we know there's - // nothing in between and scanning is still safe. - stop_index = comment.scan_mark.index - } - - // Create a token and append it to the queue. - token := yaml_token_t{ - typ: yaml_BLOCK_END_TOKEN, - start_mark: block_mark, - end_mark: block_mark, - } - yaml_insert_token(parser, -1, &token) - - // Pop the indentation level. - parser.indent = parser.indents[len(parser.indents)-1] - parser.indents = parser.indents[:len(parser.indents)-1] - } - return true -} - -// Initialize the scanner and produce the STREAM-START token. -func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool { - - // Set the initial indentation. - parser.indent = -1 - - // Initialize the simple key stack. - parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) - - parser.simple_keys_by_tok = make(map[int]int) - - // A simple key is allowed at the beginning of the stream. - parser.simple_key_allowed = true - - // We have started. - parser.stream_start_produced = true - - // Create the STREAM-START token and append it to the queue. - token := yaml_token_t{ - typ: yaml_STREAM_START_TOKEN, - start_mark: parser.mark, - end_mark: parser.mark, - encoding: parser.encoding, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the STREAM-END token and shut down the scanner. -func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool { - - // Force new line. - if parser.mark.column != 0 { - parser.mark.column = 0 - parser.mark.line++ - } - - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1, parser.mark) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Create the STREAM-END token and append it to the queue. - token := yaml_token_t{ - typ: yaml_STREAM_END_TOKEN, - start_mark: parser.mark, - end_mark: parser.mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. -func yaml_parser_fetch_directive(parser *yaml_parser_t) bool { - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1, parser.mark) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. - token := yaml_token_t{} - if !yaml_parser_scan_directive(parser, &token) { - return false - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the DOCUMENT-START or DOCUMENT-END token. -func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1, parser.mark) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Consume the token. - start_mark := parser.mark - - skip(parser) - skip(parser) - skip(parser) - - end_mark := parser.mark - - // Create the DOCUMENT-START or DOCUMENT-END token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. -func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool { - - // The indicators '[' and '{' may start a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // Increase the flow level. - if !yaml_parser_increase_flow_level(parser) { - return false - } - - // A simple key may follow the indicators '[' and '{'. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. -func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // Reset any potential simple key on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Decrease the flow level. - if !yaml_parser_decrease_flow_level(parser) { - return false - } - - // No simple keys after the indicators ']' and '}'. - parser.simple_key_allowed = false - - // Consume the token. - - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-ENTRY token. -func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool { - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after ','. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-ENTRY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_FLOW_ENTRY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the BLOCK-ENTRY token. -func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool { - // Check if the scanner is in the block context. - if parser.flow_level == 0 { - // Check if we are allowed to start a new entry. - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "block sequence entries are not allowed in this context") - } - // Add the BLOCK-SEQUENCE-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) { - return false - } - } else { - // It is an error for the '-' indicator to occur in the flow context, - // but we let the Parser detect and report about it because the Parser - // is able to point to the context. - } - - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after '-'. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the BLOCK-ENTRY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_BLOCK_ENTRY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the KEY token. -func yaml_parser_fetch_key(parser *yaml_parser_t) bool { - - // In the block context, additional checks are required. - if parser.flow_level == 0 { - // Check if we are allowed to start a new key (not nessesary simple). - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "mapping keys are not allowed in this context") - } - // Add the BLOCK-MAPPING-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { - return false - } - } - - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after '?' in the block context. - parser.simple_key_allowed = parser.flow_level == 0 - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the KEY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_KEY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the VALUE token. -func yaml_parser_fetch_value(parser *yaml_parser_t) bool { - - simple_key := &parser.simple_keys[len(parser.simple_keys)-1] - - // Have we found a simple key? - if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok { - return false - - } else if valid { - - // Create the KEY token and insert it into the queue. - token := yaml_token_t{ - typ: yaml_KEY_TOKEN, - start_mark: simple_key.mark, - end_mark: simple_key.mark, - } - yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token) - - // In the block context, we may need to add the BLOCK-MAPPING-START token. - if !yaml_parser_roll_indent(parser, simple_key.mark.column, - simple_key.token_number, - yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) { - return false - } - - // Remove the simple key. - simple_key.possible = false - delete(parser.simple_keys_by_tok, simple_key.token_number) - - // A simple key cannot follow another simple key. - parser.simple_key_allowed = false - - } else { - // The ':' indicator follows a complex key. - - // In the block context, extra checks are required. - if parser.flow_level == 0 { - - // Check if we are allowed to start a complex value. - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "mapping values are not allowed in this context") - } - - // Add the BLOCK-MAPPING-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { - return false - } - } - - // Simple keys after ':' are allowed in the block context. - parser.simple_key_allowed = parser.flow_level == 0 - } - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the VALUE token and append it to the queue. - token := yaml_token_t{ - typ: yaml_VALUE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the ALIAS or ANCHOR token. -func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // An anchor or an alias could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow an anchor or an alias. - parser.simple_key_allowed = false - - // Create the ALIAS or ANCHOR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_anchor(parser, &token, typ) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the TAG token. -func yaml_parser_fetch_tag(parser *yaml_parser_t) bool { - // A tag could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a tag. - parser.simple_key_allowed = false - - // Create the TAG token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_tag(parser, &token) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. -func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool { - // Remove any potential simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // A simple key may follow a block scalar. - parser.simple_key_allowed = true - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_block_scalar(parser, &token, literal) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. -func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool { - // A plain scalar could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a flow scalar. - parser.simple_key_allowed = false - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_flow_scalar(parser, &token, single) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,plain) token. -func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool { - // A plain scalar could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a flow scalar. - parser.simple_key_allowed = false - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_plain_scalar(parser, &token) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Eat whitespaces and comments until the next token is found. -func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool { - - scan_mark := parser.mark - - // Until the next token is not found. - for { - // Allow the BOM mark to start a line. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) { - skip(parser) - } - - // Eat whitespaces. - // Tabs are allowed: - // - in the flow context - // - in the block context, but not at the beginning of the line or - // after '-', '?', or ':' (complex value). - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if we just had a line comment under a sequence entry that - // looks more like a header to the following content. Similar to this: - // - // - # The comment - // - Some data - // - // If so, transform the line comment to a head comment and reposition. - if len(parser.comments) > 0 && len(parser.tokens) > 1 { - tokenA := parser.tokens[len(parser.tokens)-2] - tokenB := parser.tokens[len(parser.tokens)-1] - comment := &parser.comments[len(parser.comments)-1] - if tokenA.typ == yaml_BLOCK_SEQUENCE_START_TOKEN && tokenB.typ == yaml_BLOCK_ENTRY_TOKEN && len(comment.line) > 0 && !is_break(parser.buffer, parser.buffer_pos) { - // If it was in the prior line, reposition so it becomes a - // header of the follow up token. Otherwise, keep it in place - // so it becomes a header of the former. - comment.head = comment.line - comment.line = nil - if comment.start_mark.line == parser.mark.line-1 { - comment.token_mark = parser.mark - } - } - } - - // Eat a comment until a line break. - if parser.buffer[parser.buffer_pos] == '#' { - if !yaml_parser_scan_comments(parser, scan_mark) { - return false - } - } - - // If it is a line break, eat it. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - - // In the block context, a new line may start a simple key. - if parser.flow_level == 0 { - parser.simple_key_allowed = true - } - } else { - break // We have found a token. - } - } - - return true -} - -// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// -func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool { - // Eat '%'. - start_mark := parser.mark - skip(parser) - - // Scan the directive name. - var name []byte - if !yaml_parser_scan_directive_name(parser, start_mark, &name) { - return false - } - - // Is it a YAML directive? - if bytes.Equal(name, []byte("YAML")) { - // Scan the VERSION directive value. - var major, minor int8 - if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) { - return false - } - end_mark := parser.mark - - // Create a VERSION-DIRECTIVE token. - *token = yaml_token_t{ - typ: yaml_VERSION_DIRECTIVE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - major: major, - minor: minor, - } - - // Is it a TAG directive? - } else if bytes.Equal(name, []byte("TAG")) { - // Scan the TAG directive value. - var handle, prefix []byte - if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) { - return false - } - end_mark := parser.mark - - // Create a TAG-DIRECTIVE token. - *token = yaml_token_t{ - typ: yaml_TAG_DIRECTIVE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: handle, - prefix: prefix, - } - - // Unknown directive. - } else { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unknown directive name") - return false - } - - // Eat the rest of the line including any comments. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - if parser.buffer[parser.buffer_pos] == '#' { - // [Go] Discard this inline comment for the time being. - //if !yaml_parser_scan_line_comment(parser, start_mark) { - // return false - //} - for !is_breakz(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - } - - // Check if we are at the end of the line. - if !is_breakz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "did not find expected comment or line break") - return false - } - - // Eat a line break. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } - - return true -} - -// Scan the directive name. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^ -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^ -// -func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool { - // Consume the directive name. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - var s []byte - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the name is empty. - if len(s) == 0 { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "could not find expected directive name") - return false - } - - // Check for an blank character after the name. - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unexpected non-alphabetical character") - return false - } - *name = s - return true -} - -// Scan the value of VERSION-DIRECTIVE. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^^^ -func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool { - // Eat whitespaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Consume the major version number. - if !yaml_parser_scan_version_directive_number(parser, start_mark, major) { - return false - } - - // Eat '.'. - if parser.buffer[parser.buffer_pos] != '.' { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected digit or '.' character") - } - - skip(parser) - - // Consume the minor version number. - if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) { - return false - } - return true -} - -const max_number_length = 2 - -// Scan the version number of VERSION-DIRECTIVE. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^ -// %YAML 1.1 # a comment \n -// ^ -func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool { - - // Repeat while the next character is digit. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - var value, length int8 - for is_digit(parser.buffer, parser.buffer_pos) { - // Check if the number is too long. - length++ - if length > max_number_length { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "found extremely long version number") - } - value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos)) - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the number was present. - if length == 0 { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected version number") - } - *number = value - return true -} - -// Scan the value of a TAG-DIRECTIVE token. -// -// Scope: -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// -func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool { - var handle_value, prefix_value []byte - - // Eat whitespaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Scan a handle. - if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) { - return false - } - - // Expect a whitespace. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blank(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace") - return false - } - - // Eat whitespaces. - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Scan a prefix. - if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) { - return false - } - - // Expect a whitespace or line break. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace or line break") - return false - } - - *handle = handle_value - *prefix = prefix_value - return true -} - -func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool { - var s []byte - - // Eat the indicator character. - start_mark := parser.mark - skip(parser) - - // Consume the value. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - end_mark := parser.mark - - /* - * Check if length of the anchor is greater than 0 and it is followed by - * a whitespace character or one of the indicators: - * - * '?', ':', ',', ']', '}', '%', '@', '`'. - */ - - if len(s) == 0 || - !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' || - parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' || - parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' || - parser.buffer[parser.buffer_pos] == '`') { - context := "while scanning an alias" - if typ == yaml_ANCHOR_TOKEN { - context = "while scanning an anchor" - } - yaml_parser_set_scanner_error(parser, context, start_mark, - "did not find expected alphabetic or numeric character") - return false - } - - // Create a token. - *token = yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - value: s, - } - - return true -} - -/* - * Scan a TAG token. - */ - -func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool { - var handle, suffix []byte - - start_mark := parser.mark - - // Check if the tag is in the canonical form. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - if parser.buffer[parser.buffer_pos+1] == '<' { - // Keep the handle as '' - - // Eat '!<' - skip(parser) - skip(parser) - - // Consume the tag value. - if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { - return false - } - - // Check for '>' and eat it. - if parser.buffer[parser.buffer_pos] != '>' { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find the expected '>'") - return false - } - - skip(parser) - } else { - // The tag has either the '!suffix' or the '!handle!suffix' form. - - // First, try to scan a handle. - if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) { - return false - } - - // Check if it is, indeed, handle. - if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' { - // Scan the suffix now. - if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { - return false - } - } else { - // It wasn't a handle after all. Scan the rest of the tag. - if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) { - return false - } - - // Set the handle to '!'. - handle = []byte{'!'} - - // A special case: the '!' tag. Set the handle to '' and the - // suffix to '!'. - if len(suffix) == 0 { - handle, suffix = suffix, handle - } - } - } - - // Check the character which ends the tag. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find expected whitespace or line break") - return false - } - - end_mark := parser.mark - - // Create a token. - *token = yaml_token_t{ - typ: yaml_TAG_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: handle, - suffix: suffix, - } - return true -} - -// Scan a tag handle. -func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool { - // Check the initial '!' character. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.buffer[parser.buffer_pos] != '!' { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected '!'") - return false - } - - var s []byte - - // Copy the '!' character. - s = read(parser, s) - - // Copy all subsequent alphabetical and numerical characters. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the trailing character is '!' and copy it. - if parser.buffer[parser.buffer_pos] == '!' { - s = read(parser, s) - } else { - // It's either the '!' tag or not really a tag handle. If it's a %TAG - // directive, it's an error. If it's a tag token, it must be a part of URI. - if directive && string(s) != "!" { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected '!'") - return false - } - } - - *handle = s - return true -} - -// Scan a tag. -func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool { - //size_t length = head ? strlen((char *)head) : 0 - var s []byte - hasTag := len(head) > 0 - - // Copy the head if needed. - // - // Note that we don't copy the leading '!' character. - if len(head) > 1 { - s = append(s, head[1:]...) - } - - // Scan the tag. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // The set of characters that may appear in URI is as follows: - // - // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', - // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', - // '%'. - // [Go] TODO Convert this into more reasonable logic. - for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' || - parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' || - parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' || - parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' || - parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' || - parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' || - parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' || - parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' || - parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' || - parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' || - parser.buffer[parser.buffer_pos] == '%' { - // Check if it is a URI-escape sequence. - if parser.buffer[parser.buffer_pos] == '%' { - if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) { - return false - } - } else { - s = read(parser, s) - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - hasTag = true - } - - if !hasTag { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected tag URI") - return false - } - *uri = s - return true -} - -// Decode an URI-escape sequence corresponding to a single UTF-8 character. -func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool { - - // Decode the required number of characters. - w := 1024 - for w > 0 { - // Check for a URI-escaped octet. - if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { - return false - } - - if !(parser.buffer[parser.buffer_pos] == '%' && - is_hex(parser.buffer, parser.buffer_pos+1) && - is_hex(parser.buffer, parser.buffer_pos+2)) { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find URI escaped octet") - } - - // Get the octet. - octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2)) - - // If it is the leading octet, determine the length of the UTF-8 sequence. - if w == 1024 { - w = width(octet) - if w == 0 { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "found an incorrect leading UTF-8 octet") - } - } else { - // Check if the trailing octet is correct. - if octet&0xC0 != 0x80 { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "found an incorrect trailing UTF-8 octet") - } - } - - // Copy the octet and move the pointers. - *s = append(*s, octet) - skip(parser) - skip(parser) - skip(parser) - w-- - } - return true -} - -// Scan a block scalar. -func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool { - // Eat the indicator '|' or '>'. - start_mark := parser.mark - skip(parser) - - // Scan the additional block scalar indicators. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check for a chomping indicator. - var chomping, increment int - if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { - // Set the chomping method and eat the indicator. - if parser.buffer[parser.buffer_pos] == '+' { - chomping = +1 - } else { - chomping = -1 - } - skip(parser) - - // Check for an indentation indicator. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if is_digit(parser.buffer, parser.buffer_pos) { - // Check that the indentation is greater than 0. - if parser.buffer[parser.buffer_pos] == '0' { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0") - return false - } - - // Get the indentation level and eat the indicator. - increment = as_digit(parser.buffer, parser.buffer_pos) - skip(parser) - } - - } else if is_digit(parser.buffer, parser.buffer_pos) { - // Do the same as above, but in the opposite order. - - if parser.buffer[parser.buffer_pos] == '0' { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0") - return false - } - increment = as_digit(parser.buffer, parser.buffer_pos) - skip(parser) - - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { - if parser.buffer[parser.buffer_pos] == '+' { - chomping = +1 - } else { - chomping = -1 - } - skip(parser) - } - } - - // Eat whitespaces and comments to the end of the line. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - if parser.buffer[parser.buffer_pos] == '#' { - if !yaml_parser_scan_line_comment(parser, start_mark) { - return false - } - for !is_breakz(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - } - - // Check if we are at the end of the line. - if !is_breakz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "did not find expected comment or line break") - return false - } - - // Eat a line break. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } - - end_mark := parser.mark - - // Set the indentation level if it was specified. - var indent int - if increment > 0 { - if parser.indent >= 0 { - indent = parser.indent + increment - } else { - indent = increment - } - } - - // Scan the leading line breaks and determine the indentation level if needed. - var s, leading_break, trailing_breaks []byte - if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { - return false - } - - // Scan the block scalar content. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - var leading_blank, trailing_blank bool - for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) { - // We are at the beginning of a non-empty line. - - // Is it a trailing whitespace? - trailing_blank = is_blank(parser.buffer, parser.buffer_pos) - - // Check if we need to fold the leading line break. - if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' { - // Do we need to join the lines by space? - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } - } else { - s = append(s, leading_break...) - } - leading_break = leading_break[:0] - - // Append the remaining line breaks. - s = append(s, trailing_breaks...) - trailing_breaks = trailing_breaks[:0] - - // Is it a leading whitespace? - leading_blank = is_blank(parser.buffer, parser.buffer_pos) - - // Consume the current line. - for !is_breakz(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Consume the line break. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - leading_break = read_line(parser, leading_break) - - // Eat the following indentation spaces and line breaks. - if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { - return false - } - } - - // Chomp the tail. - if chomping != -1 { - s = append(s, leading_break...) - } - if chomping == 1 { - s = append(s, trailing_breaks...) - } - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_LITERAL_SCALAR_STYLE, - } - if !literal { - token.style = yaml_FOLDED_SCALAR_STYLE - } - return true -} - -// Scan indentation spaces and line breaks for a block scalar. Determine the -// indentation level if needed. -func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool { - *end_mark = parser.mark - - // Eat the indentation spaces and line breaks. - max_indent := 0 - for { - // Eat the indentation spaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - if parser.mark.column > max_indent { - max_indent = parser.mark.column - } - - // Check for a tab character messing the indentation. - if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) { - return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found a tab character where an indentation space is expected") - } - - // Have we found a non-empty line? - if !is_break(parser.buffer, parser.buffer_pos) { - break - } - - // Consume the line break. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - // [Go] Should really be returning breaks instead. - *breaks = read_line(parser, *breaks) - *end_mark = parser.mark - } - - // Determine the indentation level if needed. - if *indent == 0 { - *indent = max_indent - if *indent < parser.indent+1 { - *indent = parser.indent + 1 - } - if *indent < 1 { - *indent = 1 - } - } - return true -} - -// Scan a quoted scalar. -func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool { - // Eat the left quote. - start_mark := parser.mark - skip(parser) - - // Consume the content of the quoted scalar. - var s, leading_break, trailing_breaks, whitespaces []byte - for { - // Check that there are no document indicators at the beginning of the line. - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - - if parser.mark.column == 0 && - ((parser.buffer[parser.buffer_pos+0] == '-' && - parser.buffer[parser.buffer_pos+1] == '-' && - parser.buffer[parser.buffer_pos+2] == '-') || - (parser.buffer[parser.buffer_pos+0] == '.' && - parser.buffer[parser.buffer_pos+1] == '.' && - parser.buffer[parser.buffer_pos+2] == '.')) && - is_blankz(parser.buffer, parser.buffer_pos+3) { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected document indicator") - return false - } - - // Check for EOF. - if is_z(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected end of stream") - return false - } - - // Consume non-blank characters. - leading_blanks := false - for !is_blankz(parser.buffer, parser.buffer_pos) { - if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' { - // Is is an escaped single quote. - s = append(s, '\'') - skip(parser) - skip(parser) - - } else if single && parser.buffer[parser.buffer_pos] == '\'' { - // It is a right single quote. - break - } else if !single && parser.buffer[parser.buffer_pos] == '"' { - // It is a right double quote. - break - - } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) { - // It is an escaped line break. - if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { - return false - } - skip(parser) - skip_line(parser) - leading_blanks = true - break - - } else if !single && parser.buffer[parser.buffer_pos] == '\\' { - // It is an escape sequence. - code_length := 0 - - // Check the escape character. - switch parser.buffer[parser.buffer_pos+1] { - case '0': - s = append(s, 0) - case 'a': - s = append(s, '\x07') - case 'b': - s = append(s, '\x08') - case 't', '\t': - s = append(s, '\x09') - case 'n': - s = append(s, '\x0A') - case 'v': - s = append(s, '\x0B') - case 'f': - s = append(s, '\x0C') - case 'r': - s = append(s, '\x0D') - case 'e': - s = append(s, '\x1B') - case ' ': - s = append(s, '\x20') - case '"': - s = append(s, '"') - case '\'': - s = append(s, '\'') - case '\\': - s = append(s, '\\') - case 'N': // NEL (#x85) - s = append(s, '\xC2') - s = append(s, '\x85') - case '_': // #xA0 - s = append(s, '\xC2') - s = append(s, '\xA0') - case 'L': // LS (#x2028) - s = append(s, '\xE2') - s = append(s, '\x80') - s = append(s, '\xA8') - case 'P': // PS (#x2029) - s = append(s, '\xE2') - s = append(s, '\x80') - s = append(s, '\xA9') - case 'x': - code_length = 2 - case 'u': - code_length = 4 - case 'U': - code_length = 8 - default: - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found unknown escape character") - return false - } - - skip(parser) - skip(parser) - - // Consume an arbitrary escape code. - if code_length > 0 { - var value int - - // Scan the character value. - if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) { - return false - } - for k := 0; k < code_length; k++ { - if !is_hex(parser.buffer, parser.buffer_pos+k) { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "did not find expected hexdecimal number") - return false - } - value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k) - } - - // Check the value and write the character. - if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found invalid Unicode character escape code") - return false - } - if value <= 0x7F { - s = append(s, byte(value)) - } else if value <= 0x7FF { - s = append(s, byte(0xC0+(value>>6))) - s = append(s, byte(0x80+(value&0x3F))) - } else if value <= 0xFFFF { - s = append(s, byte(0xE0+(value>>12))) - s = append(s, byte(0x80+((value>>6)&0x3F))) - s = append(s, byte(0x80+(value&0x3F))) - } else { - s = append(s, byte(0xF0+(value>>18))) - s = append(s, byte(0x80+((value>>12)&0x3F))) - s = append(s, byte(0x80+((value>>6)&0x3F))) - s = append(s, byte(0x80+(value&0x3F))) - } - - // Advance the pointer. - for k := 0; k < code_length; k++ { - skip(parser) - } - } - } else { - // It is a non-escaped non-blank character. - s = read(parser, s) - } - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - } - - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check if we are at the end of the scalar. - if single { - if parser.buffer[parser.buffer_pos] == '\'' { - break - } - } else { - if parser.buffer[parser.buffer_pos] == '"' { - break - } - } - - // Consume blank characters. - for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { - if is_blank(parser.buffer, parser.buffer_pos) { - // Consume a space or a tab character. - if !leading_blanks { - whitespaces = read(parser, whitespaces) - } else { - skip(parser) - } - } else { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - // Check if it is a first line break. - if !leading_blanks { - whitespaces = whitespaces[:0] - leading_break = read_line(parser, leading_break) - leading_blanks = true - } else { - trailing_breaks = read_line(parser, trailing_breaks) - } - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Join the whitespaces or fold line breaks. - if leading_blanks { - // Do we need to fold line breaks? - if len(leading_break) > 0 && leading_break[0] == '\n' { - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } else { - s = append(s, trailing_breaks...) - } - } else { - s = append(s, leading_break...) - s = append(s, trailing_breaks...) - } - trailing_breaks = trailing_breaks[:0] - leading_break = leading_break[:0] - } else { - s = append(s, whitespaces...) - whitespaces = whitespaces[:0] - } - } - - // Eat the right quote. - skip(parser) - end_mark := parser.mark - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_SINGLE_QUOTED_SCALAR_STYLE, - } - if !single { - token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - return true -} - -// Scan a plain scalar. -func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool { - - var s, leading_break, trailing_breaks, whitespaces []byte - var leading_blanks bool - var indent = parser.indent + 1 - - start_mark := parser.mark - end_mark := parser.mark - - // Consume the content of the plain scalar. - for { - // Check for a document indicator. - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - if parser.mark.column == 0 && - ((parser.buffer[parser.buffer_pos+0] == '-' && - parser.buffer[parser.buffer_pos+1] == '-' && - parser.buffer[parser.buffer_pos+2] == '-') || - (parser.buffer[parser.buffer_pos+0] == '.' && - parser.buffer[parser.buffer_pos+1] == '.' && - parser.buffer[parser.buffer_pos+2] == '.')) && - is_blankz(parser.buffer, parser.buffer_pos+3) { - break - } - - // Check for a comment. - if parser.buffer[parser.buffer_pos] == '#' { - break - } - - // Consume non-blank characters. - for !is_blankz(parser.buffer, parser.buffer_pos) { - - // Check for indicators that may end a plain scalar. - if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) || - (parser.flow_level > 0 && - (parser.buffer[parser.buffer_pos] == ',' || - parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || - parser.buffer[parser.buffer_pos] == '}')) { - break - } - - // Check if we need to join whitespaces and breaks. - if leading_blanks || len(whitespaces) > 0 { - if leading_blanks { - // Do we need to fold line breaks? - if leading_break[0] == '\n' { - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } else { - s = append(s, trailing_breaks...) - } - } else { - s = append(s, leading_break...) - s = append(s, trailing_breaks...) - } - trailing_breaks = trailing_breaks[:0] - leading_break = leading_break[:0] - leading_blanks = false - } else { - s = append(s, whitespaces...) - whitespaces = whitespaces[:0] - } - } - - // Copy the character. - s = read(parser, s) - - end_mark = parser.mark - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - } - - // Is it the end? - if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) { - break - } - - // Consume blank characters. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { - if is_blank(parser.buffer, parser.buffer_pos) { - - // Check for tab characters that abuse indentation. - if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", - start_mark, "found a tab character that violates indentation") - return false - } - - // Consume a space or a tab character. - if !leading_blanks { - whitespaces = read(parser, whitespaces) - } else { - skip(parser) - } - } else { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - // Check if it is a first line break. - if !leading_blanks { - whitespaces = whitespaces[:0] - leading_break = read_line(parser, leading_break) - leading_blanks = true - } else { - trailing_breaks = read_line(parser, trailing_breaks) - } - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check indentation level. - if parser.flow_level == 0 && parser.mark.column < indent { - break - } - } - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_PLAIN_SCALAR_STYLE, - } - - // Note that we change the 'simple_key_allowed' flag. - if leading_blanks { - parser.simple_key_allowed = true - } - return true -} - -func yaml_parser_scan_line_comment(parser *yaml_parser_t, token_mark yaml_mark_t) bool { - if parser.newlines > 0 { - return true - } - - var start_mark yaml_mark_t - var text []byte - - for peek := 0; peek < 512; peek++ { - if parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) { - break - } - if is_blank(parser.buffer, parser.buffer_pos+peek) { - continue - } - if parser.buffer[parser.buffer_pos+peek] == '#' { - seen := parser.mark.index+peek - for { - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if is_breakz(parser.buffer, parser.buffer_pos) { - if parser.mark.index >= seen { - break - } - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } else if parser.mark.index >= seen { - if len(text) == 0 { - start_mark = parser.mark - } - text = read(parser, text) - } else { - skip(parser) - } - } - } - break - } - if len(text) > 0 { - parser.comments = append(parser.comments, yaml_comment_t{ - token_mark: token_mark, - start_mark: start_mark, - line: text, - }) - } - return true -} - -func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) bool { - token := parser.tokens[len(parser.tokens)-1] - - if token.typ == yaml_FLOW_ENTRY_TOKEN && len(parser.tokens) > 1 { - token = parser.tokens[len(parser.tokens)-2] - } - - var token_mark = token.start_mark - var start_mark yaml_mark_t - var next_indent = parser.indent - if next_indent < 0 { - next_indent = 0 - } - - var recent_empty = false - var first_empty = parser.newlines <= 1 - - var line = parser.mark.line - var column = parser.mark.column - - var text []byte - - // The foot line is the place where a comment must start to - // still be considered as a foot of the prior content. - // If there's some content in the currently parsed line, then - // the foot is the line below it. - var foot_line = -1 - if scan_mark.line > 0 { - foot_line = parser.mark.line-parser.newlines+1 - if parser.newlines == 0 && parser.mark.column > 1 { - foot_line++ - } - } - - var peek = 0 - for ; peek < 512; peek++ { - if parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) { - break - } - column++ - if is_blank(parser.buffer, parser.buffer_pos+peek) { - continue - } - c := parser.buffer[parser.buffer_pos+peek] - var close_flow = parser.flow_level > 0 && (c == ']' || c == '}') - if close_flow || is_breakz(parser.buffer, parser.buffer_pos+peek) { - // Got line break or terminator. - if close_flow || !recent_empty { - if close_flow || first_empty && (start_mark.line == foot_line && token.typ != yaml_VALUE_TOKEN || start_mark.column-1 < next_indent) { - // This is the first empty line and there were no empty lines before, - // so this initial part of the comment is a foot of the prior token - // instead of being a head for the following one. Split it up. - // Alternatively, this might also be the last comment inside a flow - // scope, so it must be a footer. - if len(text) > 0 { - if start_mark.column-1 < next_indent { - // If dedented it's unrelated to the prior token. - token_mark = start_mark - } - parser.comments = append(parser.comments, yaml_comment_t{ - scan_mark: scan_mark, - token_mark: token_mark, - start_mark: start_mark, - end_mark: yaml_mark_t{parser.mark.index + peek, line, column}, - foot: text, - }) - scan_mark = yaml_mark_t{parser.mark.index + peek, line, column} - token_mark = scan_mark - text = nil - } - } else { - if len(text) > 0 && parser.buffer[parser.buffer_pos+peek] != 0 { - text = append(text, '\n') - } - } - } - if !is_break(parser.buffer, parser.buffer_pos+peek) { - break - } - first_empty = false - recent_empty = true - column = 0 - line++ - continue - } - - if len(text) > 0 && (close_flow || column-1 < next_indent && column != start_mark.column) { - // The comment at the different indentation is a foot of the - // preceding data rather than a head of the upcoming one. - parser.comments = append(parser.comments, yaml_comment_t{ - scan_mark: scan_mark, - token_mark: token_mark, - start_mark: start_mark, - end_mark: yaml_mark_t{parser.mark.index + peek, line, column}, - foot: text, - }) - scan_mark = yaml_mark_t{parser.mark.index + peek, line, column} - token_mark = scan_mark - text = nil - } - - if parser.buffer[parser.buffer_pos+peek] != '#' { - break - } - - if len(text) == 0 { - start_mark = yaml_mark_t{parser.mark.index + peek, line, column} - } else { - text = append(text, '\n') - } - - recent_empty = false - - // Consume until after the consumed comment line. - seen := parser.mark.index+peek - for { - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if is_breakz(parser.buffer, parser.buffer_pos) { - if parser.mark.index >= seen { - break - } - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } else if parser.mark.index >= seen { - text = read(parser, text) - } else { - skip(parser) - } - } - - peek = 0 - column = 0 - line = parser.mark.line - next_indent = parser.indent - if next_indent < 0 { - next_indent = 0 - } - } - - if len(text) > 0 { - parser.comments = append(parser.comments, yaml_comment_t{ - scan_mark: scan_mark, - token_mark: start_mark, - start_mark: start_mark, - end_mark: yaml_mark_t{parser.mark.index + peek - 1, line, column}, - head: text, - }) - } - return true -} diff --git a/vendor/gopkg.in/yaml.v3/sorter.go b/vendor/gopkg.in/yaml.v3/sorter.go deleted file mode 100644 index 9210ece7..00000000 --- a/vendor/gopkg.in/yaml.v3/sorter.go +++ /dev/null @@ -1,134 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// 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 yaml - -import ( - "reflect" - "unicode" -) - -type keyList []reflect.Value - -func (l keyList) Len() int { return len(l) } -func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } -func (l keyList) Less(i, j int) bool { - a := l[i] - b := l[j] - ak := a.Kind() - bk := b.Kind() - for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { - a = a.Elem() - ak = a.Kind() - } - for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { - b = b.Elem() - bk = b.Kind() - } - af, aok := keyFloat(a) - bf, bok := keyFloat(b) - if aok && bok { - if af != bf { - return af < bf - } - if ak != bk { - return ak < bk - } - return numLess(a, b) - } - if ak != reflect.String || bk != reflect.String { - return ak < bk - } - ar, br := []rune(a.String()), []rune(b.String()) - digits := false - for i := 0; i < len(ar) && i < len(br); i++ { - if ar[i] == br[i] { - digits = unicode.IsDigit(ar[i]) - continue - } - al := unicode.IsLetter(ar[i]) - bl := unicode.IsLetter(br[i]) - if al && bl { - return ar[i] < br[i] - } - if al || bl { - if digits { - return al - } else { - return bl - } - } - var ai, bi int - var an, bn int64 - if ar[i] == '0' || br[i] == '0' { - for j := i - 1; j >= 0 && unicode.IsDigit(ar[j]); j-- { - if ar[j] != '0' { - an = 1 - bn = 1 - break - } - } - } - for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { - an = an*10 + int64(ar[ai]-'0') - } - for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { - bn = bn*10 + int64(br[bi]-'0') - } - if an != bn { - return an < bn - } - if ai != bi { - return ai < bi - } - return ar[i] < br[i] - } - return len(ar) < len(br) -} - -// keyFloat returns a float value for v if it is a number/bool -// and whether it is a number/bool or not. -func keyFloat(v reflect.Value) (f float64, ok bool) { - switch v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return float64(v.Int()), true - case reflect.Float32, reflect.Float64: - return v.Float(), true - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return float64(v.Uint()), true - case reflect.Bool: - if v.Bool() { - return 1, true - } - return 0, true - } - return 0, false -} - -// numLess returns whether a < b. -// a and b must necessarily have the same kind. -func numLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return a.Int() < b.Int() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Bool: - return !a.Bool() && b.Bool() - } - panic("not a number") -} diff --git a/vendor/gopkg.in/yaml.v3/writerc.go b/vendor/gopkg.in/yaml.v3/writerc.go deleted file mode 100644 index b8a116bf..00000000 --- a/vendor/gopkg.in/yaml.v3/writerc.go +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -// Set the writer error and return false. -func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { - emitter.error = yaml_WRITER_ERROR - emitter.problem = problem - return false -} - -// Flush the output buffer. -func yaml_emitter_flush(emitter *yaml_emitter_t) bool { - if emitter.write_handler == nil { - panic("write handler not set") - } - - // Check if the buffer is empty. - if emitter.buffer_pos == 0 { - return true - } - - if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { - return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) - } - emitter.buffer_pos = 0 - return true -} diff --git a/vendor/gopkg.in/yaml.v3/yaml.go b/vendor/gopkg.in/yaml.v3/yaml.go deleted file mode 100644 index 8cec6da4..00000000 --- a/vendor/gopkg.in/yaml.v3/yaml.go +++ /dev/null @@ -1,698 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// 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 yaml implements YAML support for the Go language. -// -// Source code and other details for the project are available at GitHub: -// -// https://github.com/go-yaml/yaml -// -package yaml - -import ( - "errors" - "fmt" - "io" - "reflect" - "strings" - "sync" - "unicode/utf8" -) - -// The Unmarshaler interface may be implemented by types to customize their -// behavior when being unmarshaled from a YAML document. -type Unmarshaler interface { - UnmarshalYAML(value *Node) error -} - -type obsoleteUnmarshaler interface { - UnmarshalYAML(unmarshal func(interface{}) error) error -} - -// The Marshaler interface may be implemented by types to customize their -// behavior when being marshaled into a YAML document. The returned value -// is marshaled in place of the original value implementing Marshaler. -// -// If an error is returned by MarshalYAML, the marshaling procedure stops -// and returns with the provided error. -type Marshaler interface { - MarshalYAML() (interface{}, error) -} - -// Unmarshal decodes the first document found within the in byte slice -// and assigns decoded values into the out value. -// -// Maps and pointers (to a struct, string, int, etc) are accepted as out -// values. If an internal pointer within a struct is not initialized, -// the yaml package will initialize it if necessary for unmarshalling -// the provided data. The out parameter must not be nil. -// -// The type of the decoded values should be compatible with the respective -// values in out. If one or more values cannot be decoded due to a type -// mismatches, decoding continues partially until the end of the YAML -// content, and a *yaml.TypeError is returned with details for all -// missed values. -// -// Struct fields are only unmarshalled if they are exported (have an -// upper case first letter), and are unmarshalled using the field name -// lowercased as the default key. Custom keys may be defined via the -// "yaml" name in the field tag: the content preceding the first comma -// is used as the key, and the following comma-separated options are -// used to tweak the marshalling process (see Marshal). -// Conflicting names result in a runtime error. -// -// For example: -// -// type T struct { -// F int `yaml:"a,omitempty"` -// B int -// } -// var t T -// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t) -// -// See the documentation of Marshal for the format of tags and a list of -// supported tag options. -// -func Unmarshal(in []byte, out interface{}) (err error) { - return unmarshal(in, out, false) -} - -// A Decoder reads and decodes YAML values from an input stream. -type Decoder struct { - parser *parser - knownFields bool -} - -// NewDecoder returns a new decoder that reads from r. -// -// The decoder introduces its own buffering and may read -// data from r beyond the YAML values requested. -func NewDecoder(r io.Reader) *Decoder { - return &Decoder{ - parser: newParserFromReader(r), - } -} - -// KnownFields ensures that the keys in decoded mappings to -// exist as fields in the struct being decoded into. -func (dec *Decoder) KnownFields(enable bool) { - dec.knownFields = enable -} - -// Decode reads the next YAML-encoded value from its input -// and stores it in the value pointed to by v. -// -// See the documentation for Unmarshal for details about the -// conversion of YAML into a Go value. -func (dec *Decoder) Decode(v interface{}) (err error) { - d := newDecoder() - d.knownFields = dec.knownFields - defer handleErr(&err) - node := dec.parser.parse() - if node == nil { - return io.EOF - } - out := reflect.ValueOf(v) - if out.Kind() == reflect.Ptr && !out.IsNil() { - out = out.Elem() - } - d.unmarshal(node, out) - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -// Decode decodes the node and stores its data into the value pointed to by v. -// -// See the documentation for Unmarshal for details about the -// conversion of YAML into a Go value. -func (n *Node) Decode(v interface{}) (err error) { - d := newDecoder() - defer handleErr(&err) - out := reflect.ValueOf(v) - if out.Kind() == reflect.Ptr && !out.IsNil() { - out = out.Elem() - } - d.unmarshal(n, out) - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -func unmarshal(in []byte, out interface{}, strict bool) (err error) { - defer handleErr(&err) - d := newDecoder() - p := newParser(in) - defer p.destroy() - node := p.parse() - if node != nil { - v := reflect.ValueOf(out) - if v.Kind() == reflect.Ptr && !v.IsNil() { - v = v.Elem() - } - d.unmarshal(node, v) - } - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -// Marshal serializes the value provided into a YAML document. The structure -// of the generated document will reflect the structure of the value itself. -// Maps and pointers (to struct, string, int, etc) are accepted as the in value. -// -// Struct fields are only marshalled if they are exported (have an upper case -// first letter), and are marshalled using the field name lowercased as the -// default key. Custom keys may be defined via the "yaml" name in the field -// tag: the content preceding the first comma is used as the key, and the -// following comma-separated options are used to tweak the marshalling process. -// Conflicting names result in a runtime error. -// -// The field tag format accepted is: -// -// `(...) yaml:"[][,[,]]" (...)` -// -// The following flags are currently supported: -// -// omitempty Only include the field if it's not set to the zero -// value for the type or to empty slices or maps. -// Zero valued structs will be omitted if all their public -// fields are zero, unless they implement an IsZero -// method (see the IsZeroer interface type), in which -// case the field will be excluded if IsZero returns true. -// -// flow Marshal using a flow style (useful for structs, -// sequences and maps). -// -// inline Inline the field, which must be a struct or a map, -// causing all of its fields or keys to be processed as if -// they were part of the outer struct. For maps, keys must -// not conflict with the yaml keys of other struct fields. -// -// In addition, if the key is "-", the field is ignored. -// -// For example: -// -// type T struct { -// F int `yaml:"a,omitempty"` -// B int -// } -// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n" -// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n" -// -func Marshal(in interface{}) (out []byte, err error) { - defer handleErr(&err) - e := newEncoder() - defer e.destroy() - e.marshalDoc("", reflect.ValueOf(in)) - e.finish() - out = e.out - return -} - -// An Encoder writes YAML values to an output stream. -type Encoder struct { - encoder *encoder -} - -// NewEncoder returns a new encoder that writes to w. -// The Encoder should be closed after use to flush all data -// to w. -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{ - encoder: newEncoderWithWriter(w), - } -} - -// Encode writes the YAML encoding of v to the stream. -// If multiple items are encoded to the stream, the -// second and subsequent document will be preceded -// with a "---" document separator, but the first will not. -// -// See the documentation for Marshal for details about the conversion of Go -// values to YAML. -func (e *Encoder) Encode(v interface{}) (err error) { - defer handleErr(&err) - e.encoder.marshalDoc("", reflect.ValueOf(v)) - return nil -} - -// Encode encodes value v and stores its representation in n. -// -// See the documentation for Marshal for details about the -// conversion of Go values into YAML. -func (n *Node) Encode(v interface{}) (err error) { - defer handleErr(&err) - e := newEncoder() - defer e.destroy() - e.marshalDoc("", reflect.ValueOf(v)) - e.finish() - p := newParser(e.out) - p.textless = true - defer p.destroy() - doc := p.parse() - *n = *doc.Content[0] - return nil -} - -// SetIndent changes the used indentation used when encoding. -func (e *Encoder) SetIndent(spaces int) { - if spaces < 0 { - panic("yaml: cannot indent to a negative number of spaces") - } - e.encoder.indent = spaces -} - -// Close closes the encoder by writing any remaining data. -// It does not write a stream terminating string "...". -func (e *Encoder) Close() (err error) { - defer handleErr(&err) - e.encoder.finish() - return nil -} - -func handleErr(err *error) { - if v := recover(); v != nil { - if e, ok := v.(yamlError); ok { - *err = e.err - } else { - panic(v) - } - } -} - -type yamlError struct { - err error -} - -func fail(err error) { - panic(yamlError{err}) -} - -func failf(format string, args ...interface{}) { - panic(yamlError{fmt.Errorf("yaml: "+format, args...)}) -} - -// A TypeError is returned by Unmarshal when one or more fields in -// the YAML document cannot be properly decoded into the requested -// types. When this error is returned, the value is still -// unmarshaled partially. -type TypeError struct { - Errors []string -} - -func (e *TypeError) Error() string { - return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n ")) -} - -type Kind uint32 - -const ( - DocumentNode Kind = 1 << iota - SequenceNode - MappingNode - ScalarNode - AliasNode -) - -type Style uint32 - -const ( - TaggedStyle Style = 1 << iota - DoubleQuotedStyle - SingleQuotedStyle - LiteralStyle - FoldedStyle - FlowStyle -) - -// Node represents an element in the YAML document hierarchy. While documents -// are typically encoded and decoded into higher level types, such as structs -// and maps, Node is an intermediate representation that allows detailed -// control over the content being decoded or encoded. -// -// It's worth noting that although Node offers access into details such as -// line numbers, colums, and comments, the content when re-encoded will not -// have its original textual representation preserved. An effort is made to -// render the data plesantly, and to preserve comments near the data they -// describe, though. -// -// Values that make use of the Node type interact with the yaml package in the -// same way any other type would do, by encoding and decoding yaml data -// directly or indirectly into them. -// -// For example: -// -// var person struct { -// Name string -// Address yaml.Node -// } -// err := yaml.Unmarshal(data, &person) -// -// Or by itself: -// -// var person Node -// err := yaml.Unmarshal(data, &person) -// -type Node struct { - // Kind defines whether the node is a document, a mapping, a sequence, - // a scalar value, or an alias to another node. The specific data type of - // scalar nodes may be obtained via the ShortTag and LongTag methods. - Kind Kind - - // Style allows customizing the apperance of the node in the tree. - Style Style - - // Tag holds the YAML tag defining the data type for the value. - // When decoding, this field will always be set to the resolved tag, - // even when it wasn't explicitly provided in the YAML content. - // When encoding, if this field is unset the value type will be - // implied from the node properties, and if it is set, it will only - // be serialized into the representation if TaggedStyle is used or - // the implicit tag diverges from the provided one. - Tag string - - // Value holds the unescaped and unquoted represenation of the value. - Value string - - // Anchor holds the anchor name for this node, which allows aliases to point to it. - Anchor string - - // Alias holds the node that this alias points to. Only valid when Kind is AliasNode. - Alias *Node - - // Content holds contained nodes for documents, mappings, and sequences. - Content []*Node - - // HeadComment holds any comments in the lines preceding the node and - // not separated by an empty line. - HeadComment string - - // LineComment holds any comments at the end of the line where the node is in. - LineComment string - - // FootComment holds any comments following the node and before empty lines. - FootComment string - - // Line and Column hold the node position in the decoded YAML text. - // These fields are not respected when encoding the node. - Line int - Column int -} - -// IsZero returns whether the node has all of its fields unset. -func (n *Node) IsZero() bool { - return n.Kind == 0 && n.Style == 0 && n.Tag == "" && n.Value == "" && n.Anchor == "" && n.Alias == nil && n.Content == nil && - n.HeadComment == "" && n.LineComment == "" && n.FootComment == "" && n.Line == 0 && n.Column == 0 -} - - -// LongTag returns the long form of the tag that indicates the data type for -// the node. If the Tag field isn't explicitly defined, one will be computed -// based on the node properties. -func (n *Node) LongTag() string { - return longTag(n.ShortTag()) -} - -// ShortTag returns the short form of the YAML tag that indicates data type for -// the node. If the Tag field isn't explicitly defined, one will be computed -// based on the node properties. -func (n *Node) ShortTag() string { - if n.indicatedString() { - return strTag - } - if n.Tag == "" || n.Tag == "!" { - switch n.Kind { - case MappingNode: - return mapTag - case SequenceNode: - return seqTag - case AliasNode: - if n.Alias != nil { - return n.Alias.ShortTag() - } - case ScalarNode: - tag, _ := resolve("", n.Value) - return tag - case 0: - // Special case to make the zero value convenient. - if n.IsZero() { - return nullTag - } - } - return "" - } - return shortTag(n.Tag) -} - -func (n *Node) indicatedString() bool { - return n.Kind == ScalarNode && - (shortTag(n.Tag) == strTag || - (n.Tag == "" || n.Tag == "!") && n.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0) -} - -// SetString is a convenience function that sets the node to a string value -// and defines its style in a pleasant way depending on its content. -func (n *Node) SetString(s string) { - n.Kind = ScalarNode - if utf8.ValidString(s) { - n.Value = s - n.Tag = strTag - } else { - n.Value = encodeBase64(s) - n.Tag = binaryTag - } - if strings.Contains(n.Value, "\n") { - n.Style = LiteralStyle - } -} - -// -------------------------------------------------------------------------- -// Maintain a mapping of keys to structure field indexes - -// The code in this section was copied from mgo/bson. - -// structInfo holds details for the serialization of fields of -// a given struct. -type structInfo struct { - FieldsMap map[string]fieldInfo - FieldsList []fieldInfo - - // InlineMap is the number of the field in the struct that - // contains an ,inline map, or -1 if there's none. - InlineMap int - - // InlineUnmarshalers holds indexes to inlined fields that - // contain unmarshaler values. - InlineUnmarshalers [][]int -} - -type fieldInfo struct { - Key string - Num int - OmitEmpty bool - Flow bool - // Id holds the unique field identifier, so we can cheaply - // check for field duplicates without maintaining an extra map. - Id int - - // Inline holds the field index if the field is part of an inlined struct. - Inline []int -} - -var structMap = make(map[reflect.Type]*structInfo) -var fieldMapMutex sync.RWMutex -var unmarshalerType reflect.Type - -func init() { - var v Unmarshaler - unmarshalerType = reflect.ValueOf(&v).Elem().Type() -} - -func getStructInfo(st reflect.Type) (*structInfo, error) { - fieldMapMutex.RLock() - sinfo, found := structMap[st] - fieldMapMutex.RUnlock() - if found { - return sinfo, nil - } - - n := st.NumField() - fieldsMap := make(map[string]fieldInfo) - fieldsList := make([]fieldInfo, 0, n) - inlineMap := -1 - inlineUnmarshalers := [][]int(nil) - for i := 0; i != n; i++ { - field := st.Field(i) - if field.PkgPath != "" && !field.Anonymous { - continue // Private field - } - - info := fieldInfo{Num: i} - - tag := field.Tag.Get("yaml") - if tag == "" && strings.Index(string(field.Tag), ":") < 0 { - tag = string(field.Tag) - } - if tag == "-" { - continue - } - - inline := false - fields := strings.Split(tag, ",") - if len(fields) > 1 { - for _, flag := range fields[1:] { - switch flag { - case "omitempty": - info.OmitEmpty = true - case "flow": - info.Flow = true - case "inline": - inline = true - default: - return nil, errors.New(fmt.Sprintf("unsupported flag %q in tag %q of type %s", flag, tag, st)) - } - } - tag = fields[0] - } - - if inline { - switch field.Type.Kind() { - case reflect.Map: - if inlineMap >= 0 { - return nil, errors.New("multiple ,inline maps in struct " + st.String()) - } - if field.Type.Key() != reflect.TypeOf("") { - return nil, errors.New("option ,inline needs a map with string keys in struct " + st.String()) - } - inlineMap = info.Num - case reflect.Struct, reflect.Ptr: - ftype := field.Type - for ftype.Kind() == reflect.Ptr { - ftype = ftype.Elem() - } - if ftype.Kind() != reflect.Struct { - return nil, errors.New("option ,inline may only be used on a struct or map field") - } - if reflect.PtrTo(ftype).Implements(unmarshalerType) { - inlineUnmarshalers = append(inlineUnmarshalers, []int{i}) - } else { - sinfo, err := getStructInfo(ftype) - if err != nil { - return nil, err - } - for _, index := range sinfo.InlineUnmarshalers { - inlineUnmarshalers = append(inlineUnmarshalers, append([]int{i}, index...)) - } - for _, finfo := range sinfo.FieldsList { - if _, found := fieldsMap[finfo.Key]; found { - msg := "duplicated key '" + finfo.Key + "' in struct " + st.String() - return nil, errors.New(msg) - } - if finfo.Inline == nil { - finfo.Inline = []int{i, finfo.Num} - } else { - finfo.Inline = append([]int{i}, finfo.Inline...) - } - finfo.Id = len(fieldsList) - fieldsMap[finfo.Key] = finfo - fieldsList = append(fieldsList, finfo) - } - } - default: - return nil, errors.New("option ,inline may only be used on a struct or map field") - } - continue - } - - if tag != "" { - info.Key = tag - } else { - info.Key = strings.ToLower(field.Name) - } - - if _, found = fieldsMap[info.Key]; found { - msg := "duplicated key '" + info.Key + "' in struct " + st.String() - return nil, errors.New(msg) - } - - info.Id = len(fieldsList) - fieldsList = append(fieldsList, info) - fieldsMap[info.Key] = info - } - - sinfo = &structInfo{ - FieldsMap: fieldsMap, - FieldsList: fieldsList, - InlineMap: inlineMap, - InlineUnmarshalers: inlineUnmarshalers, - } - - fieldMapMutex.Lock() - structMap[st] = sinfo - fieldMapMutex.Unlock() - return sinfo, nil -} - -// IsZeroer is used to check whether an object is zero to -// determine whether it should be omitted when marshaling -// with the omitempty flag. One notable implementation -// is time.Time. -type IsZeroer interface { - IsZero() bool -} - -func isZero(v reflect.Value) bool { - kind := v.Kind() - if z, ok := v.Interface().(IsZeroer); ok { - if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() { - return true - } - return z.IsZero() - } - switch kind { - case reflect.String: - return len(v.String()) == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - case reflect.Slice: - return v.Len() == 0 - case reflect.Map: - return v.Len() == 0 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Struct: - vt := v.Type() - for i := v.NumField() - 1; i >= 0; i-- { - if vt.Field(i).PkgPath != "" { - continue // Private field - } - if !isZero(v.Field(i)) { - return false - } - } - return true - } - return false -} diff --git a/vendor/gopkg.in/yaml.v3/yamlh.go b/vendor/gopkg.in/yaml.v3/yamlh.go deleted file mode 100644 index 7c6d0077..00000000 --- a/vendor/gopkg.in/yaml.v3/yamlh.go +++ /dev/null @@ -1,807 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -import ( - "fmt" - "io" -) - -// The version directive data. -type yaml_version_directive_t struct { - major int8 // The major version number. - minor int8 // The minor version number. -} - -// The tag directive data. -type yaml_tag_directive_t struct { - handle []byte // The tag handle. - prefix []byte // The tag prefix. -} - -type yaml_encoding_t int - -// The stream encoding. -const ( - // Let the parser choose the encoding. - yaml_ANY_ENCODING yaml_encoding_t = iota - - yaml_UTF8_ENCODING // The default UTF-8 encoding. - yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM. - yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM. -) - -type yaml_break_t int - -// Line break types. -const ( - // Let the parser choose the break type. - yaml_ANY_BREAK yaml_break_t = iota - - yaml_CR_BREAK // Use CR for line breaks (Mac style). - yaml_LN_BREAK // Use LN for line breaks (Unix style). - yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style). -) - -type yaml_error_type_t int - -// Many bad things could happen with the parser and emitter. -const ( - // No error is produced. - yaml_NO_ERROR yaml_error_type_t = iota - - yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory. - yaml_READER_ERROR // Cannot read or decode the input stream. - yaml_SCANNER_ERROR // Cannot scan the input stream. - yaml_PARSER_ERROR // Cannot parse the input stream. - yaml_COMPOSER_ERROR // Cannot compose a YAML document. - yaml_WRITER_ERROR // Cannot write to the output stream. - yaml_EMITTER_ERROR // Cannot emit a YAML stream. -) - -// The pointer position. -type yaml_mark_t struct { - index int // The position index. - line int // The position line. - column int // The position column. -} - -// Node Styles - -type yaml_style_t int8 - -type yaml_scalar_style_t yaml_style_t - -// Scalar styles. -const ( - // Let the emitter choose the style. - yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = 0 - - yaml_PLAIN_SCALAR_STYLE yaml_scalar_style_t = 1 << iota // The plain scalar style. - yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style. - yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style. - yaml_LITERAL_SCALAR_STYLE // The literal scalar style. - yaml_FOLDED_SCALAR_STYLE // The folded scalar style. -) - -type yaml_sequence_style_t yaml_style_t - -// Sequence styles. -const ( - // Let the emitter choose the style. - yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota - - yaml_BLOCK_SEQUENCE_STYLE // The block sequence style. - yaml_FLOW_SEQUENCE_STYLE // The flow sequence style. -) - -type yaml_mapping_style_t yaml_style_t - -// Mapping styles. -const ( - // Let the emitter choose the style. - yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota - - yaml_BLOCK_MAPPING_STYLE // The block mapping style. - yaml_FLOW_MAPPING_STYLE // The flow mapping style. -) - -// Tokens - -type yaml_token_type_t int - -// Token types. -const ( - // An empty token. - yaml_NO_TOKEN yaml_token_type_t = iota - - yaml_STREAM_START_TOKEN // A STREAM-START token. - yaml_STREAM_END_TOKEN // A STREAM-END token. - - yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token. - yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token. - yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token. - yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token. - - yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token. - yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token. - yaml_BLOCK_END_TOKEN // A BLOCK-END token. - - yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token. - yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token. - yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token. - yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token. - - yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token. - yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token. - yaml_KEY_TOKEN // A KEY token. - yaml_VALUE_TOKEN // A VALUE token. - - yaml_ALIAS_TOKEN // An ALIAS token. - yaml_ANCHOR_TOKEN // An ANCHOR token. - yaml_TAG_TOKEN // A TAG token. - yaml_SCALAR_TOKEN // A SCALAR token. -) - -func (tt yaml_token_type_t) String() string { - switch tt { - case yaml_NO_TOKEN: - return "yaml_NO_TOKEN" - case yaml_STREAM_START_TOKEN: - return "yaml_STREAM_START_TOKEN" - case yaml_STREAM_END_TOKEN: - return "yaml_STREAM_END_TOKEN" - case yaml_VERSION_DIRECTIVE_TOKEN: - return "yaml_VERSION_DIRECTIVE_TOKEN" - case yaml_TAG_DIRECTIVE_TOKEN: - return "yaml_TAG_DIRECTIVE_TOKEN" - case yaml_DOCUMENT_START_TOKEN: - return "yaml_DOCUMENT_START_TOKEN" - case yaml_DOCUMENT_END_TOKEN: - return "yaml_DOCUMENT_END_TOKEN" - case yaml_BLOCK_SEQUENCE_START_TOKEN: - return "yaml_BLOCK_SEQUENCE_START_TOKEN" - case yaml_BLOCK_MAPPING_START_TOKEN: - return "yaml_BLOCK_MAPPING_START_TOKEN" - case yaml_BLOCK_END_TOKEN: - return "yaml_BLOCK_END_TOKEN" - case yaml_FLOW_SEQUENCE_START_TOKEN: - return "yaml_FLOW_SEQUENCE_START_TOKEN" - case yaml_FLOW_SEQUENCE_END_TOKEN: - return "yaml_FLOW_SEQUENCE_END_TOKEN" - case yaml_FLOW_MAPPING_START_TOKEN: - return "yaml_FLOW_MAPPING_START_TOKEN" - case yaml_FLOW_MAPPING_END_TOKEN: - return "yaml_FLOW_MAPPING_END_TOKEN" - case yaml_BLOCK_ENTRY_TOKEN: - return "yaml_BLOCK_ENTRY_TOKEN" - case yaml_FLOW_ENTRY_TOKEN: - return "yaml_FLOW_ENTRY_TOKEN" - case yaml_KEY_TOKEN: - return "yaml_KEY_TOKEN" - case yaml_VALUE_TOKEN: - return "yaml_VALUE_TOKEN" - case yaml_ALIAS_TOKEN: - return "yaml_ALIAS_TOKEN" - case yaml_ANCHOR_TOKEN: - return "yaml_ANCHOR_TOKEN" - case yaml_TAG_TOKEN: - return "yaml_TAG_TOKEN" - case yaml_SCALAR_TOKEN: - return "yaml_SCALAR_TOKEN" - } - return "" -} - -// The token structure. -type yaml_token_t struct { - // The token type. - typ yaml_token_type_t - - // The start/end of the token. - start_mark, end_mark yaml_mark_t - - // The stream encoding (for yaml_STREAM_START_TOKEN). - encoding yaml_encoding_t - - // The alias/anchor/scalar value or tag/tag directive handle - // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN). - value []byte - - // The tag suffix (for yaml_TAG_TOKEN). - suffix []byte - - // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN). - prefix []byte - - // The scalar style (for yaml_SCALAR_TOKEN). - style yaml_scalar_style_t - - // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN). - major, minor int8 -} - -// Events - -type yaml_event_type_t int8 - -// Event types. -const ( - // An empty event. - yaml_NO_EVENT yaml_event_type_t = iota - - yaml_STREAM_START_EVENT // A STREAM-START event. - yaml_STREAM_END_EVENT // A STREAM-END event. - yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event. - yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event. - yaml_ALIAS_EVENT // An ALIAS event. - yaml_SCALAR_EVENT // A SCALAR event. - yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event. - yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event. - yaml_MAPPING_START_EVENT // A MAPPING-START event. - yaml_MAPPING_END_EVENT // A MAPPING-END event. - yaml_TAIL_COMMENT_EVENT -) - -var eventStrings = []string{ - yaml_NO_EVENT: "none", - yaml_STREAM_START_EVENT: "stream start", - yaml_STREAM_END_EVENT: "stream end", - yaml_DOCUMENT_START_EVENT: "document start", - yaml_DOCUMENT_END_EVENT: "document end", - yaml_ALIAS_EVENT: "alias", - yaml_SCALAR_EVENT: "scalar", - yaml_SEQUENCE_START_EVENT: "sequence start", - yaml_SEQUENCE_END_EVENT: "sequence end", - yaml_MAPPING_START_EVENT: "mapping start", - yaml_MAPPING_END_EVENT: "mapping end", - yaml_TAIL_COMMENT_EVENT: "tail comment", -} - -func (e yaml_event_type_t) String() string { - if e < 0 || int(e) >= len(eventStrings) { - return fmt.Sprintf("unknown event %d", e) - } - return eventStrings[e] -} - -// The event structure. -type yaml_event_t struct { - - // The event type. - typ yaml_event_type_t - - // The start and end of the event. - start_mark, end_mark yaml_mark_t - - // The document encoding (for yaml_STREAM_START_EVENT). - encoding yaml_encoding_t - - // The version directive (for yaml_DOCUMENT_START_EVENT). - version_directive *yaml_version_directive_t - - // The list of tag directives (for yaml_DOCUMENT_START_EVENT). - tag_directives []yaml_tag_directive_t - - // The comments - head_comment []byte - line_comment []byte - foot_comment []byte - tail_comment []byte - - // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT). - anchor []byte - - // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). - tag []byte - - // The scalar value (for yaml_SCALAR_EVENT). - value []byte - - // Is the document start/end indicator implicit, or the tag optional? - // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT). - implicit bool - - // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT). - quoted_implicit bool - - // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). - style yaml_style_t -} - -func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) } -func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) } -func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) } - -// Nodes - -const ( - yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null. - yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false. - yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values. - yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values. - yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values. - yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values. - - yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences. - yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping. - - // Not in original libyaml. - yaml_BINARY_TAG = "tag:yaml.org,2002:binary" - yaml_MERGE_TAG = "tag:yaml.org,2002:merge" - - yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str. - yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq. - yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map. -) - -type yaml_node_type_t int - -// Node types. -const ( - // An empty node. - yaml_NO_NODE yaml_node_type_t = iota - - yaml_SCALAR_NODE // A scalar node. - yaml_SEQUENCE_NODE // A sequence node. - yaml_MAPPING_NODE // A mapping node. -) - -// An element of a sequence node. -type yaml_node_item_t int - -// An element of a mapping node. -type yaml_node_pair_t struct { - key int // The key of the element. - value int // The value of the element. -} - -// The node structure. -type yaml_node_t struct { - typ yaml_node_type_t // The node type. - tag []byte // The node tag. - - // The node data. - - // The scalar parameters (for yaml_SCALAR_NODE). - scalar struct { - value []byte // The scalar value. - length int // The length of the scalar value. - style yaml_scalar_style_t // The scalar style. - } - - // The sequence parameters (for YAML_SEQUENCE_NODE). - sequence struct { - items_data []yaml_node_item_t // The stack of sequence items. - style yaml_sequence_style_t // The sequence style. - } - - // The mapping parameters (for yaml_MAPPING_NODE). - mapping struct { - pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value). - pairs_start *yaml_node_pair_t // The beginning of the stack. - pairs_end *yaml_node_pair_t // The end of the stack. - pairs_top *yaml_node_pair_t // The top of the stack. - style yaml_mapping_style_t // The mapping style. - } - - start_mark yaml_mark_t // The beginning of the node. - end_mark yaml_mark_t // The end of the node. - -} - -// The document structure. -type yaml_document_t struct { - - // The document nodes. - nodes []yaml_node_t - - // The version directive. - version_directive *yaml_version_directive_t - - // The list of tag directives. - tag_directives_data []yaml_tag_directive_t - tag_directives_start int // The beginning of the tag directives list. - tag_directives_end int // The end of the tag directives list. - - start_implicit int // Is the document start indicator implicit? - end_implicit int // Is the document end indicator implicit? - - // The start/end of the document. - start_mark, end_mark yaml_mark_t -} - -// The prototype of a read handler. -// -// The read handler is called when the parser needs to read more bytes from the -// source. The handler should write not more than size bytes to the buffer. -// The number of written bytes should be set to the size_read variable. -// -// [in,out] data A pointer to an application data specified by -// yaml_parser_set_input(). -// [out] buffer The buffer to write the data from the source. -// [in] size The size of the buffer. -// [out] size_read The actual number of bytes read from the source. -// -// On success, the handler should return 1. If the handler failed, -// the returned value should be 0. On EOF, the handler should set the -// size_read to 0 and return 1. -type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error) - -// This structure holds information about a potential simple key. -type yaml_simple_key_t struct { - possible bool // Is a simple key possible? - required bool // Is a simple key required? - token_number int // The number of the token. - mark yaml_mark_t // The position mark. -} - -// The states of the parser. -type yaml_parser_state_t int - -const ( - yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota - - yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document. - yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START. - yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document. - yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END. - yaml_PARSE_BLOCK_NODE_STATE // Expect a block node. - yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence. - yaml_PARSE_FLOW_NODE_STATE // Expect a flow node. - yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence. - yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence. - yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence. - yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. - yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key. - yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value. - yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry. - yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. - yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. - yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. - yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping. - yaml_PARSE_END_STATE // Expect nothing. -) - -func (ps yaml_parser_state_t) String() string { - switch ps { - case yaml_PARSE_STREAM_START_STATE: - return "yaml_PARSE_STREAM_START_STATE" - case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE" - case yaml_PARSE_DOCUMENT_START_STATE: - return "yaml_PARSE_DOCUMENT_START_STATE" - case yaml_PARSE_DOCUMENT_CONTENT_STATE: - return "yaml_PARSE_DOCUMENT_CONTENT_STATE" - case yaml_PARSE_DOCUMENT_END_STATE: - return "yaml_PARSE_DOCUMENT_END_STATE" - case yaml_PARSE_BLOCK_NODE_STATE: - return "yaml_PARSE_BLOCK_NODE_STATE" - case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE" - case yaml_PARSE_FLOW_NODE_STATE: - return "yaml_PARSE_FLOW_NODE_STATE" - case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE" - case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE" - case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: - return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE" - case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: - return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE" - case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE" - case yaml_PARSE_FLOW_MAPPING_KEY_STATE: - return "yaml_PARSE_FLOW_MAPPING_KEY_STATE" - case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: - return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE" - case yaml_PARSE_END_STATE: - return "yaml_PARSE_END_STATE" - } - return "" -} - -// This structure holds aliases data. -type yaml_alias_data_t struct { - anchor []byte // The anchor. - index int // The node id. - mark yaml_mark_t // The anchor mark. -} - -// The parser structure. -// -// All members are internal. Manage the structure using the -// yaml_parser_ family of functions. -type yaml_parser_t struct { - - // Error handling - - error yaml_error_type_t // Error type. - - problem string // Error description. - - // The byte about which the problem occurred. - problem_offset int - problem_value int - problem_mark yaml_mark_t - - // The error context. - context string - context_mark yaml_mark_t - - // Reader stuff - - read_handler yaml_read_handler_t // Read handler. - - input_reader io.Reader // File input data. - input []byte // String input data. - input_pos int - - eof bool // EOF flag - - buffer []byte // The working buffer. - buffer_pos int // The current position of the buffer. - - unread int // The number of unread characters in the buffer. - - newlines int // The number of line breaks since last non-break/non-blank character - - raw_buffer []byte // The raw buffer. - raw_buffer_pos int // The current position of the buffer. - - encoding yaml_encoding_t // The input encoding. - - offset int // The offset of the current position (in bytes). - mark yaml_mark_t // The mark of the current position. - - // Comments - - head_comment []byte // The current head comments - line_comment []byte // The current line comments - foot_comment []byte // The current foot comments - tail_comment []byte // Foot comment that happens at the end of a block. - stem_comment []byte // Comment in item preceding a nested structure (list inside list item, etc) - - comments []yaml_comment_t // The folded comments for all parsed tokens - comments_head int - - // Scanner stuff - - stream_start_produced bool // Have we started to scan the input stream? - stream_end_produced bool // Have we reached the end of the input stream? - - flow_level int // The number of unclosed '[' and '{' indicators. - - tokens []yaml_token_t // The tokens queue. - tokens_head int // The head of the tokens queue. - tokens_parsed int // The number of tokens fetched from the queue. - token_available bool // Does the tokens queue contain a token ready for dequeueing. - - indent int // The current indentation level. - indents []int // The indentation levels stack. - - simple_key_allowed bool // May a simple key occur at the current position? - simple_keys []yaml_simple_key_t // The stack of simple keys. - simple_keys_by_tok map[int]int // possible simple_key indexes indexed by token_number - - // Parser stuff - - state yaml_parser_state_t // The current parser state. - states []yaml_parser_state_t // The parser states stack. - marks []yaml_mark_t // The stack of marks. - tag_directives []yaml_tag_directive_t // The list of TAG directives. - - // Dumper stuff - - aliases []yaml_alias_data_t // The alias data. - - document *yaml_document_t // The currently parsed document. -} - -type yaml_comment_t struct { - - scan_mark yaml_mark_t // Position where scanning for comments started - token_mark yaml_mark_t // Position after which tokens will be associated with this comment - start_mark yaml_mark_t // Position of '#' comment mark - end_mark yaml_mark_t // Position where comment terminated - - head []byte - line []byte - foot []byte -} - -// Emitter Definitions - -// The prototype of a write handler. -// -// The write handler is called when the emitter needs to flush the accumulated -// characters to the output. The handler should write @a size bytes of the -// @a buffer to the output. -// -// @param[in,out] data A pointer to an application data specified by -// yaml_emitter_set_output(). -// @param[in] buffer The buffer with bytes to be written. -// @param[in] size The size of the buffer. -// -// @returns On success, the handler should return @c 1. If the handler failed, -// the returned value should be @c 0. -// -type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error - -type yaml_emitter_state_t int - -// The emitter states. -const ( - // Expect STREAM-START. - yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota - - yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END. - yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END. - yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document. - yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END. - yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence. - yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE // Expect the next item of a flow sequence, with the comma already written out - yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence. - yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE // Expect the next key of a flow mapping, with the comma already written out - yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. - yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence. - yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence. - yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping. - yaml_EMIT_END_STATE // Expect nothing. -) - -// The emitter structure. -// -// All members are internal. Manage the structure using the @c yaml_emitter_ -// family of functions. -type yaml_emitter_t struct { - - // Error handling - - error yaml_error_type_t // Error type. - problem string // Error description. - - // Writer stuff - - write_handler yaml_write_handler_t // Write handler. - - output_buffer *[]byte // String output data. - output_writer io.Writer // File output data. - - buffer []byte // The working buffer. - buffer_pos int // The current position of the buffer. - - raw_buffer []byte // The raw buffer. - raw_buffer_pos int // The current position of the buffer. - - encoding yaml_encoding_t // The stream encoding. - - // Emitter stuff - - canonical bool // If the output is in the canonical style? - best_indent int // The number of indentation spaces. - best_width int // The preferred width of the output lines. - unicode bool // Allow unescaped non-ASCII characters? - line_break yaml_break_t // The preferred line break. - - state yaml_emitter_state_t // The current emitter state. - states []yaml_emitter_state_t // The stack of states. - - events []yaml_event_t // The event queue. - events_head int // The head of the event queue. - - indents []int // The stack of indentation levels. - - tag_directives []yaml_tag_directive_t // The list of tag directives. - - indent int // The current indentation level. - - flow_level int // The current flow level. - - root_context bool // Is it the document root context? - sequence_context bool // Is it a sequence context? - mapping_context bool // Is it a mapping context? - simple_key_context bool // Is it a simple mapping key context? - - line int // The current line. - column int // The current column. - whitespace bool // If the last character was a whitespace? - indention bool // If the last character was an indentation character (' ', '-', '?', ':')? - open_ended bool // If an explicit document end is required? - - space_above bool // Is there's an empty line above? - foot_indent int // The indent used to write the foot comment above, or -1 if none. - - // Anchor analysis. - anchor_data struct { - anchor []byte // The anchor value. - alias bool // Is it an alias? - } - - // Tag analysis. - tag_data struct { - handle []byte // The tag handle. - suffix []byte // The tag suffix. - } - - // Scalar analysis. - scalar_data struct { - value []byte // The scalar value. - multiline bool // Does the scalar contain line breaks? - flow_plain_allowed bool // Can the scalar be expessed in the flow plain style? - block_plain_allowed bool // Can the scalar be expressed in the block plain style? - single_quoted_allowed bool // Can the scalar be expressed in the single quoted style? - block_allowed bool // Can the scalar be expressed in the literal or folded styles? - style yaml_scalar_style_t // The output style. - } - - // Comments - head_comment []byte - line_comment []byte - foot_comment []byte - tail_comment []byte - - key_line_comment []byte - - // Dumper stuff - - opened bool // If the stream was already opened? - closed bool // If the stream was already closed? - - // The information associated with the document nodes. - anchors *struct { - references int // The number of references. - anchor int // The anchor id. - serialized bool // If the node has been emitted? - } - - last_anchor_id int // The last assigned anchor id. - - document *yaml_document_t // The currently emitted document. -} diff --git a/vendor/gopkg.in/yaml.v3/yamlprivateh.go b/vendor/gopkg.in/yaml.v3/yamlprivateh.go deleted file mode 100644 index e88f9c54..00000000 --- a/vendor/gopkg.in/yaml.v3/yamlprivateh.go +++ /dev/null @@ -1,198 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// 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. - -package yaml - -const ( - // The size of the input raw buffer. - input_raw_buffer_size = 512 - - // The size of the input buffer. - // It should be possible to decode the whole raw buffer. - input_buffer_size = input_raw_buffer_size * 3 - - // The size of the output buffer. - output_buffer_size = 128 - - // The size of the output raw buffer. - // It should be possible to encode the whole output buffer. - output_raw_buffer_size = (output_buffer_size*2 + 2) - - // The size of other stacks and queues. - initial_stack_size = 16 - initial_queue_size = 16 - initial_string_size = 16 -) - -// Check if the character at the specified position is an alphabetical -// character, a digit, '_', or '-'. -func is_alpha(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-' -} - -// Check if the character at the specified position is a digit. -func is_digit(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' -} - -// Get the value of a digit. -func as_digit(b []byte, i int) int { - return int(b[i]) - '0' -} - -// Check if the character at the specified position is a hex-digit. -func is_hex(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f' -} - -// Get the value of a hex-digit. -func as_hex(b []byte, i int) int { - bi := b[i] - if bi >= 'A' && bi <= 'F' { - return int(bi) - 'A' + 10 - } - if bi >= 'a' && bi <= 'f' { - return int(bi) - 'a' + 10 - } - return int(bi) - '0' -} - -// Check if the character is ASCII. -func is_ascii(b []byte, i int) bool { - return b[i] <= 0x7F -} - -// Check if the character at the start of the buffer can be printed unescaped. -func is_printable(b []byte, i int) bool { - return ((b[i] == 0x0A) || // . == #x0A - (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E - (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF - (b[i] > 0xC2 && b[i] < 0xED) || - (b[i] == 0xED && b[i+1] < 0xA0) || - (b[i] == 0xEE) || - (b[i] == 0xEF && // #xE000 <= . <= #xFFFD - !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF - !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF)))) -} - -// Check if the character at the specified position is NUL. -func is_z(b []byte, i int) bool { - return b[i] == 0x00 -} - -// Check if the beginning of the buffer is a BOM. -func is_bom(b []byte, i int) bool { - return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF -} - -// Check if the character at the specified position is space. -func is_space(b []byte, i int) bool { - return b[i] == ' ' -} - -// Check if the character at the specified position is tab. -func is_tab(b []byte, i int) bool { - return b[i] == '\t' -} - -// Check if the character at the specified position is blank (space or tab). -func is_blank(b []byte, i int) bool { - //return is_space(b, i) || is_tab(b, i) - return b[i] == ' ' || b[i] == '\t' -} - -// Check if the character at the specified position is a line break. -func is_break(b []byte, i int) bool { - return (b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029) -} - -func is_crlf(b []byte, i int) bool { - return b[i] == '\r' && b[i+1] == '\n' -} - -// Check if the character is a line break or NUL. -func is_breakz(b []byte, i int) bool { - //return is_break(b, i) || is_z(b, i) - return ( - // is_break: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - // is_z: - b[i] == 0) -} - -// Check if the character is a line break, space, or NUL. -func is_spacez(b []byte, i int) bool { - //return is_space(b, i) || is_breakz(b, i) - return ( - // is_space: - b[i] == ' ' || - // is_breakz: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - b[i] == 0) -} - -// Check if the character is a line break, space, tab, or NUL. -func is_blankz(b []byte, i int) bool { - //return is_blank(b, i) || is_breakz(b, i) - return ( - // is_blank: - b[i] == ' ' || b[i] == '\t' || - // is_breakz: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - b[i] == 0) -} - -// Determine the width of the character. -func width(b byte) int { - // Don't replace these by a switch without first - // confirming that it is being inlined. - if b&0x80 == 0x00 { - return 1 - } - if b&0xE0 == 0xC0 { - return 2 - } - if b&0xF0 == 0xE0 { - return 3 - } - if b&0xF8 == 0xF0 { - return 4 - } - return 0 - -} diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/interfaces.go b/vendor/k8s.io/apimachinery/pkg/api/meta/interfaces.go index a35ce3bd..628187ee 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/interfaces.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/interfaces.go @@ -17,6 +17,8 @@ limitations under the License. package meta import ( + "context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -109,7 +111,9 @@ type RESTMapping struct { // to API groups. In other words, kinds and resources should not be assumed to be // unique across groups. // -// TODO: split into sub-interfaces +// RESTMapperWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use RESTMapperWithContext instead. type RESTMapper interface { // KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) @@ -133,11 +137,114 @@ type RESTMapper interface { ResourceSingularizer(resource string) (singular string, err error) } +// RESTMapperWithContext allows clients to map resources to kind, and map kind and version +// to interfaces for manipulating those objects. It is primarily intended for +// consumers of Kubernetes compatible REST APIs as defined in docs/devel/api-conventions.md. +// +// The Kubernetes API provides versioned resources and object kinds which are scoped +// to API groups. In other words, kinds and resources should not be assumed to be +// unique across groups. +type RESTMapperWithContext interface { + // KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches + KindForWithContext(ctx context.Context, resource schema.GroupVersionResource) (schema.GroupVersionKind, error) + + // KindsFor takes a partial resource and returns the list of potential kinds in priority order + KindsForWithContext(ctx context.Context, resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) + + // ResourceFor takes a partial resource and returns the single match. Returns an error if there are multiple matches + ResourceForWithContext(ctx context.Context, input schema.GroupVersionResource) (schema.GroupVersionResource, error) + + // ResourcesFor takes a partial resource and returns the list of potential resource in priority order + ResourcesForWithContext(ctx context.Context, input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) + + // RESTMapping identifies a preferred resource mapping for the provided group kind. + RESTMappingWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) (*RESTMapping, error) + // RESTMappings returns all resource mappings for the provided group kind if no + // version search is provided. Otherwise identifies a preferred resource mapping for + // the provided version(s). + RESTMappingsWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) + + ResourceSingularizerWithContext(ctx context.Context, resource string) (singular string, err error) +} + +func ToRESTMapperWithContext(m RESTMapper) RESTMapperWithContext { + if m == nil { + return nil + } + if m, ok := m.(RESTMapperWithContext); ok { + return m + } + return &restMapperWrapper{ + delegate: m, + } +} + +type restMapperWrapper struct { + delegate RESTMapper +} + +func (m *restMapperWrapper) KindForWithContext(ctx context.Context, resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + return m.delegate.KindFor(resource) +} +func (m *restMapperWrapper) KindsForWithContext(ctx context.Context, resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { + return m.delegate.KindsFor(resource) +} +func (m *restMapperWrapper) ResourceForWithContext(ctx context.Context, input schema.GroupVersionResource) (schema.GroupVersionResource, error) { + return m.delegate.ResourceFor(input) +} +func (m *restMapperWrapper) ResourcesForWithContext(ctx context.Context, input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + return m.delegate.ResourcesFor(input) +} +func (m *restMapperWrapper) RESTMappingWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) (*RESTMapping, error) { + return m.delegate.RESTMapping(gk, versions...) +} +func (m *restMapperWrapper) RESTMappingsWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { + return m.delegate.RESTMappings(gk, versions...) +} +func (m *restMapperWrapper) ResourceSingularizerWithContext(ctx context.Context, resource string) (singular string, err error) { + return m.delegate.ResourceSingularizer(resource) +} + // ResettableRESTMapper is a RESTMapper which is capable of resetting itself // from discovery. // All rest mappers that delegate to other rest mappers must implement this interface and dynamically // check if the delegate mapper supports the Reset() operation. +// +// ResettableRESTMapperWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use ResettableRESTMapperWithContext instead. type ResettableRESTMapper interface { RESTMapper Reset() } + +// ResettableRESTMapperWithContext is a RESTMapper which is capable of resetting itself +// from discovery. +// All rest mappers that delegate to other rest mappers must implement this interface and dynamically +// check if the delegate mapper supports the ResetWithContext() operation. +type ResettableRESTMapperWithContext interface { + RESTMapperWithContext + ResetWithContext(ctx context.Context) +} + +func ToResettableRESTMapperWithContext(m ResettableRESTMapper) ResettableRESTMapperWithContext { + if m == nil { + return nil + } + if m, ok := m.(ResettableRESTMapperWithContext); ok { + return m + } + return &resettableRESTMapperWrapper{ + RESTMapperWithContext: ToRESTMapperWithContext(m), + delegate: m, + } +} + +type resettableRESTMapperWrapper struct { + RESTMapperWithContext + delegate ResettableRESTMapper +} + +func (m *resettableRESTMapperWrapper) ResetWithContext(ctx context.Context) { + m.delegate.Reset() +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go b/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go index 2551f07f..4bf24da5 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/meta.go @@ -600,6 +600,7 @@ func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference { var ret []metav1.OwnerReference s := a.ownerReferences if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice { + //nolint:logcheck // Should not happen. klog.Errorf("expect %v to be a pointer to slice", s) return ret } @@ -608,6 +609,7 @@ func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference { ret = make([]metav1.OwnerReference, s.Len(), s.Len()+1) for i := 0; i < s.Len(); i++ { if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil { + //nolint:logcheck // Should not happen. klog.Errorf("extractFromOwnerReference failed: %v", err) return ret } @@ -618,12 +620,14 @@ func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference { func (a genericAccessor) SetOwnerReferences(references []metav1.OwnerReference) { s := a.ownerReferences if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice { + //nolint:logcheck // Should not happen. klog.Errorf("expect %v to be a pointer to slice", s) } s = s.Elem() newReferences := reflect.MakeSlice(s.Type(), len(references), len(references)) for i := 0; i < len(references); i++ { if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil { + //nolint:logcheck // Should not happen. klog.Errorf("setOwnerReference failed: %v", err) return } diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go b/vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go index b7e97125..2b2c143c 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go @@ -17,6 +17,7 @@ limitations under the License. package meta import ( + "context" "fmt" "strings" @@ -25,13 +26,31 @@ import ( ) var ( - _ ResettableRESTMapper = MultiRESTMapper{} + _ ResettableRESTMapper = MultiRESTMapper{} + _ fmt.Stringer = MultiRESTMapper{} + _ ResettableRESTMapperWithContext = MultiRESTMapperWithContext{} + _ fmt.Stringer = MultiRESTMapperWithContext{} ) // MultiRESTMapper is a wrapper for multiple RESTMappers. +// +// MultiRESTMapperWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext instead. type MultiRESTMapper []RESTMapper +// MultiRESTMapperWithContext is a wrapper for multiple RESTMapperWithContext instances. +type MultiRESTMapperWithContext []RESTMapperWithContext + func (m MultiRESTMapper) String() string { + return stringifyMapper("MultiRESTMapper", m) +} + +func (m MultiRESTMapperWithContext) String() string { + return stringifyMapper("MultiRESTMapperWithContext", m) +} + +func stringifyMapper[T any](typeName string, m []T) string { nested := make([]string, 0, len(m)) for _, t := range m { currString := fmt.Sprintf("%v", t) @@ -39,14 +58,93 @@ func (m MultiRESTMapper) String() string { nested = append(nested, strings.Join(splitStrings, "\n\t")) } - return fmt.Sprintf("MultiRESTMapper{\n\t%s\n}", strings.Join(nested, "\n\t")) + return fmt.Sprintf("%s{\n\t%s\n}", typeName, strings.Join(nested, "\n\t")) +} + +func ToMultiRESTMapperWithContext(m MultiRESTMapper) MultiRESTMapperWithContext { + if m == nil { + return nil + } + mc := make(MultiRESTMapperWithContext, len(m)) + for i, m := range m { + mc[i] = ToRESTMapperWithContext(m) + } + return mc } // ResourceSingularizer converts a REST resource name from plural to singular (e.g., from pods to pod) // This implementation supports multiple REST schemas and return the first match. +// +// MultiRESTMapperWithContext.ResourceSingularizerWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.ResourceSingularizerWithContext instead. func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, err error) { + return ToMultiRESTMapperWithContext(m).ResourceSingularizerWithContext(context.Background(), resource) +} + +// MultiRESTMapperWithContext.ResourcesForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.ResourcesForWithContext instead. +func (m MultiRESTMapper) ResourcesFor(resource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + return ToMultiRESTMapperWithContext(m).ResourcesForWithContext(context.Background(), resource) +} + +// MultiRESTMapperWithContext.KindsForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.KindsForWithContext instead. +func (m MultiRESTMapper) KindsFor(resource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) { + return ToMultiRESTMapperWithContext(m).KindsForWithContext(context.Background(), resource) +} + +// MultiRESTMapperWithContext.ResourceForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.ResourceForWithContext instead. +func (m MultiRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) { + return ToMultiRESTMapperWithContext(m).ResourceForWithContext(context.Background(), resource) +} + +// MultiRESTMapperWithContext.KindForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.KindForWithContext instead. +func (m MultiRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + return ToMultiRESTMapperWithContext(m).KindForWithContext(context.Background(), resource) +} + +// RESTMapping provides the REST mapping for the resource based on the +// kind and version. This implementation supports multiple REST schemas and +// return the first match. +// +// MultiRESTMapperWithContext.RESTMappingWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.RESTMappingWithContext instead. +func (m MultiRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) { + return ToMultiRESTMapperWithContext(m).RESTMappingWithContext(context.Background(), gk, versions...) +} + +// RESTMappings returns all possible RESTMappings for the provided group kind, or an error +// if the type is not recognized. +// +// MultiRESTMapperWithContext.RESTMappingsWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.RESTMappingsWithContext instead. +func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { + return ToMultiRESTMapperWithContext(m).RESTMappingsWithContext(context.Background(), gk, versions...) +} + +// MultiRESTMapperWithContext.Reset is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MultiRESTMapperWithContext.Reset instead. +func (m MultiRESTMapper) Reset() { for _, t := range m { - singular, err = t.ResourceSingularizer(resource) + MaybeResetRESTMapper(t) + } +} + +// ResourceSingularizer converts a REST resource name from plural to singular (e.g., from pods to pod) +// This implementation supports multiple REST schemas and return the first match. +func (m MultiRESTMapperWithContext) ResourceSingularizerWithContext(ctx context.Context, resource string) (singular string, err error) { + for _, t := range m { + singular, err = t.ResourceSingularizerWithContext(ctx, resource) if err == nil { return } @@ -54,10 +152,10 @@ func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, return } -func (m MultiRESTMapper) ResourcesFor(resource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { +func (m MultiRESTMapperWithContext) ResourcesForWithContext(ctx context.Context, resource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { allGVRs := []schema.GroupVersionResource{} for _, t := range m { - gvrs, err := t.ResourcesFor(resource) + gvrs, err := t.ResourcesForWithContext(ctx, resource) // ignore "no match" errors, but any other error percolates back up if IsNoMatchError(err) { continue @@ -89,10 +187,10 @@ func (m MultiRESTMapper) ResourcesFor(resource schema.GroupVersionResource) ([]s return allGVRs, nil } -func (m MultiRESTMapper) KindsFor(resource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) { +func (m MultiRESTMapperWithContext) KindsForWithContext(ctx context.Context, resource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) { allGVKs := []schema.GroupVersionKind{} for _, t := range m { - gvks, err := t.KindsFor(resource) + gvks, err := t.KindsForWithContext(ctx, resource) // ignore "no match" errors, but any other error percolates back up if IsNoMatchError(err) { continue @@ -124,8 +222,8 @@ func (m MultiRESTMapper) KindsFor(resource schema.GroupVersionResource) (gvk []s return allGVKs, nil } -func (m MultiRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) { - resources, err := m.ResourcesFor(resource) +func (m MultiRESTMapperWithContext) ResourceForWithContext(ctx context.Context, resource schema.GroupVersionResource) (schema.GroupVersionResource, error) { + resources, err := m.ResourcesForWithContext(ctx, resource) if err != nil { return schema.GroupVersionResource{}, err } @@ -136,8 +234,8 @@ func (m MultiRESTMapper) ResourceFor(resource schema.GroupVersionResource) (sche return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources} } -func (m MultiRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { - kinds, err := m.KindsFor(resource) +func (m MultiRESTMapperWithContext) KindForWithContext(ctx context.Context, resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + kinds, err := m.KindsForWithContext(ctx, resource) if err != nil { return schema.GroupVersionKind{}, err } @@ -151,12 +249,12 @@ func (m MultiRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.G // RESTMapping provides the REST mapping for the resource based on the // kind and version. This implementation supports multiple REST schemas and // return the first match. -func (m MultiRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) { +func (m MultiRESTMapperWithContext) RESTMappingWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) (*RESTMapping, error) { allMappings := []*RESTMapping{} errors := []error{} for _, t := range m { - currMapping, err := t.RESTMapping(gk, versions...) + currMapping, err := t.RESTMappingWithContext(ctx, gk, versions...) // ignore "no match" errors, but any other error percolates back up if IsNoMatchError(err) { continue @@ -188,12 +286,12 @@ func (m MultiRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (* // RESTMappings returns all possible RESTMappings for the provided group kind, or an error // if the type is not recognized. -func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { +func (m MultiRESTMapperWithContext) RESTMappingsWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { var allMappings []*RESTMapping var errors []error for _, t := range m { - currMappings, err := t.RESTMappings(gk, versions...) + currMappings, err := t.RESTMappingsWithContext(ctx, gk, versions...) // ignore "no match" errors, but any other error percolates back up if IsNoMatchError(err) { continue @@ -213,8 +311,8 @@ func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ( return allMappings, nil } -func (m MultiRESTMapper) Reset() { +func (m MultiRESTMapperWithContext) ResetWithContext(ctx context.Context) { for _, t := range m { - MaybeResetRESTMapper(t) + MaybeResetRESTMapperWithContext(ctx, t) } } diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/priority.go b/vendor/k8s.io/apimachinery/pkg/api/meta/priority.go index 4f097c9c..d152e7e3 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/priority.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/priority.go @@ -17,6 +17,7 @@ limitations under the License. package meta import ( + "context" "fmt" "k8s.io/apimachinery/pkg/runtime/schema" @@ -30,11 +31,17 @@ const ( ) var ( - _ ResettableRESTMapper = PriorityRESTMapper{} + _ ResettableRESTMapper = PriorityRESTMapper{} + _ ResettableRESTMapperWithContext = PriorityRESTMapperWithContext{} + _ fmt.Stringer = PriorityRESTMapperWithContext{} ) // PriorityRESTMapper is a wrapper for automatically choosing a particular Resource or Kind // when multiple matches are possible +// +// PriorityRESTMapperWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext instead. type PriorityRESTMapper struct { // Delegate is the RESTMapper to use to locate all the Kind and Resource matches Delegate RESTMapper @@ -56,9 +63,100 @@ func (m PriorityRESTMapper) String() string { return fmt.Sprintf("PriorityRESTMapper{\n\t%v\n\t%v\n\t%v\n}", m.ResourcePriority, m.KindPriority, m.Delegate) } +// PriorityRESTMapperWithContext is a wrapper for automatically choosing a particular Resource or Kind +// when multiple matches are possible +type PriorityRESTMapperWithContext struct { + // Delegate is the RESTMapperWithContext to use to locate all the Kind and Resource matches + Delegate RESTMapperWithContext + + // ResourcePriority is a list of priority patterns to apply to matching resources. + // The list of all matching resources is narrowed based on the patterns until only one remains. + // A pattern with no matches is skipped. A pattern with more than one match uses its + // matches as the list to continue matching against. + ResourcePriority []schema.GroupVersionResource + + // KindPriority is a list of priority patterns to apply to matching kinds. + // The list of all matching kinds is narrowed based on the patterns until only one remains. + // A pattern with no matches is skipped. A pattern with more than one match uses its + // matches as the list to continue matching against. + KindPriority []schema.GroupVersionKind +} + +func (m PriorityRESTMapperWithContext) String() string { + return fmt.Sprintf("PriorityRESTMapperWithContext{\n\t%v\n\t%v\n\t%v\n}", m.ResourcePriority, m.KindPriority, m.Delegate) +} + +func ToPriorityRESTMapperWithContext(m PriorityRESTMapper) PriorityRESTMapperWithContext { + return PriorityRESTMapperWithContext{ + Delegate: ToRESTMapperWithContext(m.Delegate), + ResourcePriority: m.ResourcePriority, + KindPriority: m.KindPriority, + } +} + // ResourceFor finds all resources, then passes them through the ResourcePriority patterns to find a single matching hit. +// +// PriorityRESTMapperWithContext.ResourceForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.ResourceForWithContext instead. func (m PriorityRESTMapper) ResourceFor(partiallySpecifiedResource schema.GroupVersionResource) (schema.GroupVersionResource, error) { - originalGVRs, originalErr := m.Delegate.ResourcesFor(partiallySpecifiedResource) + return ToPriorityRESTMapperWithContext(m).ResourceForWithContext(context.Background(), partiallySpecifiedResource) +} + +// KindFor finds all kinds, then passes them through the KindPriority patterns to find a single matching hit. +// +// PriorityRESTMapperWithContext.KindForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.KindForWithContext instead. +func (m PriorityRESTMapper) KindFor(partiallySpecifiedResource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + return ToPriorityRESTMapperWithContext(m).KindForWithContext(context.Background(), partiallySpecifiedResource) +} + +// PriorityRESTMapperWithContext.RESTMappingWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.RESTMappingWithContext instead. +func (m PriorityRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (mapping *RESTMapping, err error) { + return ToPriorityRESTMapperWithContext(m).RESTMappingWithContext(context.Background(), gk, versions...) +} + +// PriorityRESTMapperWithContext.RESTMappingsWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.RESTMappingsWithContext instead. +func (m PriorityRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { + return m.Delegate.RESTMappings(gk, versions...) +} + +// PriorityRESTMapperWithContext.ResourceSingularizerWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.ResourceSingularizerWithContext instead. +func (m PriorityRESTMapper) ResourceSingularizer(resource string) (singular string, err error) { + return m.Delegate.ResourceSingularizer(resource) +} + +// PriorityRESTMapperWithContext.ResourcesForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.ResourcesForWithContext instead. +func (m PriorityRESTMapper) ResourcesFor(partiallySpecifiedResource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + return m.Delegate.ResourcesFor(partiallySpecifiedResource) +} + +// PriorityRESTMapperWithContext.KindsForWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.KindsForWithContext instead. +func (m PriorityRESTMapper) KindsFor(partiallySpecifiedResource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) { + return m.Delegate.KindsFor(partiallySpecifiedResource) +} + +// PriorityRESTMapperWithContext.ResetWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use PriorityRESTMapperWithContext.ResetWithContext instead. +func (m PriorityRESTMapper) Reset() { + MaybeResetRESTMapper(m.Delegate) +} + +// ResourceFor finds all resources, then passes them through the ResourcePriority patterns to find a single matching hit. +func (m PriorityRESTMapperWithContext) ResourceForWithContext(ctx context.Context, partiallySpecifiedResource schema.GroupVersionResource) (schema.GroupVersionResource, error) { + originalGVRs, originalErr := m.Delegate.ResourcesForWithContext(ctx, partiallySpecifiedResource) if originalErr != nil && len(originalGVRs) == 0 { return schema.GroupVersionResource{}, originalErr } @@ -93,8 +191,8 @@ func (m PriorityRESTMapper) ResourceFor(partiallySpecifiedResource schema.GroupV } // KindFor finds all kinds, then passes them through the KindPriority patterns to find a single matching hit. -func (m PriorityRESTMapper) KindFor(partiallySpecifiedResource schema.GroupVersionResource) (schema.GroupVersionKind, error) { - originalGVKs, originalErr := m.Delegate.KindsFor(partiallySpecifiedResource) +func (m PriorityRESTMapperWithContext) KindForWithContext(ctx context.Context, partiallySpecifiedResource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + originalGVKs, originalErr := m.Delegate.KindsForWithContext(ctx, partiallySpecifiedResource) if originalErr != nil && len(originalGVKs) == 0 { return schema.GroupVersionKind{}, originalErr } @@ -156,8 +254,8 @@ func kindMatches(pattern schema.GroupVersionKind, kind schema.GroupVersionKind) return true } -func (m PriorityRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (mapping *RESTMapping, err error) { - mappings, originalErr := m.Delegate.RESTMappings(gk, versions...) +func (m PriorityRESTMapperWithContext) RESTMappingWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) (mapping *RESTMapping, err error) { + mappings, originalErr := m.Delegate.RESTMappingsWithContext(ctx, gk, versions...) if originalErr != nil && len(mappings) == 0 { return nil, originalErr } @@ -209,22 +307,22 @@ func (m PriorityRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds} } -func (m PriorityRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { - return m.Delegate.RESTMappings(gk, versions...) +func (m PriorityRESTMapperWithContext) RESTMappingsWithContext(ctx context.Context, gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { + return m.Delegate.RESTMappingsWithContext(ctx, gk, versions...) } -func (m PriorityRESTMapper) ResourceSingularizer(resource string) (singular string, err error) { - return m.Delegate.ResourceSingularizer(resource) +func (m PriorityRESTMapperWithContext) ResourceSingularizerWithContext(ctx context.Context, resource string) (singular string, err error) { + return m.Delegate.ResourceSingularizerWithContext(ctx, resource) } -func (m PriorityRESTMapper) ResourcesFor(partiallySpecifiedResource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { - return m.Delegate.ResourcesFor(partiallySpecifiedResource) +func (m PriorityRESTMapperWithContext) ResourcesForWithContext(ctx context.Context, partiallySpecifiedResource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + return m.Delegate.ResourcesForWithContext(ctx, partiallySpecifiedResource) } -func (m PriorityRESTMapper) KindsFor(partiallySpecifiedResource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) { - return m.Delegate.KindsFor(partiallySpecifiedResource) +func (m PriorityRESTMapperWithContext) KindsForWithContext(ctx context.Context, partiallySpecifiedResource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) { + return m.Delegate.KindsForWithContext(ctx, partiallySpecifiedResource) } -func (m PriorityRESTMapper) Reset() { - MaybeResetRESTMapper(m.Delegate) +func (m PriorityRESTMapperWithContext) ResetWithContext(ctx context.Context) { + MaybeResetRESTMapperWithContext(ctx, m.Delegate) } diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/restmapper.go b/vendor/k8s.io/apimachinery/pkg/api/meta/restmapper.go index 91cb98ca..d64db33d 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/restmapper.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/restmapper.go @@ -18,6 +18,7 @@ limitations under the License. package meta import ( + "context" "fmt" "sort" "strings" @@ -72,6 +73,8 @@ func (m *DefaultRESTMapper) String() string { } var _ RESTMapper = &DefaultRESTMapper{} +var _ RESTMapperWithContext = &DefaultRESTMapper{} +var _ fmt.Stringer = &DefaultRESTMapper{} // NewDefaultRESTMapper initializes a mapping between Kind and APIVersion // to a resource name and back based on the objects in a runtime.Scheme @@ -179,6 +182,10 @@ func (m *DefaultRESTMapper) ResourceSingularizer(resourceType string) (string, e return singular.Resource, nil } +func (m *DefaultRESTMapper) ResourceSingularizerWithContext(_ context.Context, resourceType string) (string, error) { + return m.ResourceSingularizer(resourceType) +} + // coerceResourceForMatching makes the resource lower case and converts internal versions to unspecified (legacy behavior) func coerceResourceForMatching(resource schema.GroupVersionResource) schema.GroupVersionResource { resource.Resource = strings.ToLower(resource.Resource) @@ -276,6 +283,10 @@ func (m *DefaultRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]s return ret, nil } +func (m *DefaultRESTMapper) ResourcesForWithContext(_ context.Context, input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) { + return m.ResourcesFor(input) +} + func (m *DefaultRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) { resources, err := m.ResourcesFor(resource) if err != nil { @@ -288,6 +299,10 @@ func (m *DefaultRESTMapper) ResourceFor(resource schema.GroupVersionResource) (s return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources} } +func (m *DefaultRESTMapper) ResourceForWithContext(_ context.Context, resource schema.GroupVersionResource) (schema.GroupVersionResource, error) { + return m.ResourceFor(resource) +} + func (m *DefaultRESTMapper) KindsFor(input schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { resource := coerceResourceForMatching(input) @@ -355,6 +370,10 @@ func (m *DefaultRESTMapper) KindsFor(input schema.GroupVersionResource) ([]schem return ret, nil } +func (m *DefaultRESTMapper) KindsForWithContext(_ context.Context, input schema.GroupVersionResource) ([]schema.GroupVersionKind, error) { + return m.KindsFor(input) +} + func (m *DefaultRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { kinds, err := m.KindsFor(resource) if err != nil { @@ -367,6 +386,10 @@ func (m *DefaultRESTMapper) KindFor(resource schema.GroupVersionResource) (schem return schema.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds} } +func (m *DefaultRESTMapper) KindForWithContext(_ context.Context, resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { + return m.KindFor(resource) +} + type kindByPreferredGroupVersion struct { list []schema.GroupVersionKind sortOrder []schema.GroupVersion @@ -461,6 +484,10 @@ func (m *DefaultRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) return mappings[0], nil } +func (m *DefaultRESTMapper) RESTMappingWithContext(_ context.Context, gk schema.GroupKind, versions ...string) (*RESTMapping, error) { + return m.RESTMapping(gk, versions...) +} + // RESTMappings returns the RESTMappings for the provided group kind. If a version search order // is not provided, the search order provided to DefaultRESTMapper will be used. func (m *DefaultRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { @@ -520,10 +547,33 @@ func (m *DefaultRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string return mappings, nil } -// MaybeResetRESTMapper calls Reset() on the mapper if it is a ResettableRESTMapper. +func (m *DefaultRESTMapper) RESTMappingsWithContext(_ context.Context, gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) { + return m.RESTMappings(gk, versions...) +} + +// MaybeResetRESTMapper calls Reset() on the mapper if it is a ResettableRESTMapper or +// ResetWithContext() if it is a ResettableRESTMapperWithContext. +// +// MaybeResetRESTMapperWithContext is a better alternative because it supports contextual logging and cancellation. +// +// Contextual logging: Use MaybeResetRESTMapperWithContext instead. func MaybeResetRESTMapper(mapper RESTMapper) { - m, ok := mapper.(ResettableRESTMapper) - if ok { + maybeReset(context.Background(), mapper) +} + +// MaybeResetRESTMapperWithContext calls Reset() on the mapper if it is a ResettableRESTMapper or +// ResetWithContext() if it is a ResettableRESTMapperWithContext. +func MaybeResetRESTMapperWithContext(ctx context.Context, mapper RESTMapperWithContext) { + maybeReset(ctx, mapper) +} + +func maybeReset(ctx context.Context, mapper any) { + if m, ok := mapper.(ResettableRESTMapperWithContext); ok { + m.ResetWithContext(ctx) + return + } + if m, ok := mapper.(ResettableRESTMapper); ok { m.Reset() + return } } diff --git a/vendor/k8s.io/apimachinery/pkg/api/operation/operation.go b/vendor/k8s.io/apimachinery/pkg/api/operation/operation.go index 86b6ddf3..cccc7e60 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/operation/operation.go +++ b/vendor/k8s.io/apimachinery/pkg/api/operation/operation.go @@ -17,7 +17,6 @@ limitations under the License. package operation import ( - "slices" "strings" ) @@ -31,28 +30,27 @@ type Operation struct { // those into a single "Update" category. Type Type - // Options declare the options enabled for validation. + // Options are the validation options in effect for this operation, mapping option + // name to whether it is enabled. Option names typically match feature gates, but an + // option may be enabled even when its feature gate is off — e.g. when the feature is + // already in use by the object being updated. Set by the resource strategy and + // read-only during validation. // - // Options should be set according to a resource validation strategy before validation - // is performed, and must be treated as read-only during validation. - // - // Options are identified by string names. Option string names may match the name of a feature - // gate, in which case the presence of the name in the set indicates that the feature is - // considered enabled for the resource being validated. Note that a resource may have a - // feature enabled even when the feature gate is disabled. This can happen when feature is - // already in-use by a resource, often because the feature gate was enabled when the - // resource first began using the feature. - // - // Unset options are disabled/false. - Options []string + // Every option a validation tag references must be defined here by the strategy; an + // option that is not defined is a programming error (see HasOption). + Options map[string]bool // Request provides information about the request being validated. Request Request } -// HasOption returns true if the given string is in the Options slice. -func (o Operation) HasOption(option string) bool { - return slices.Contains(o.Options, option) +// HasOption returns whether the named option is enabled and whether it was defined by +// the strategy. Every option a validation tag references must be defined; callers treat +// an undefined option as an internal error (see validate.IfOption) rather than silently +// as disabled. +func (o Operation) HasOption(option string) (enabled, defined bool) { + enabled, defined = o.Options[option] + return } // Request provides information about the request being validated. diff --git a/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go b/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go index f3cd6006..e6b1f1b5 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go +++ b/vendor/k8s.io/apimachinery/pkg/api/resource/quantity.go @@ -878,3 +878,14 @@ func (q *QuantityValue) Set(s string) error { func (q QuantityValue) Type() string { return "quantity" } + +// QuantityPtrEqual compares two Quantity pointers and returns true if they are both nil or point to equal quantities. +func QuantityPtrEqual(a, b *Quantity) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return a.Equal(*b) +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/content/kube.go b/vendor/k8s.io/apimachinery/pkg/api/validate/content/kube.go index 44e82eef..608073f7 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/content/kube.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/content/kube.go @@ -99,3 +99,19 @@ func prefixEach(msgs []string, prefix string) []string { } return msgs } + +// IsPrefixedLabelKey tests whether the value passed is a valid label key with +// a domain prefix. This allows "example.com/key" but not "key". +// If the value is not valid, a list of error strings is returned. Otherwise, +// an empty list (or nil) is returned. +func IsPrefixedLabelKey(value string) []string { + if errs := IsLabelKey(value); len(errs) > 0 { + return errs + } + + segments := strings.Split(value, "/") + if len(segments) != 2 { + return []string{"must include a prefix (e.g. 'example.com/key')"} + } + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/dependentrequired.go b/vendor/k8s.io/apimachinery/pkg/api/validate/dependentrequired.go new file mode 100644 index 00000000..69222c97 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/dependentrequired.go @@ -0,0 +1,83 @@ +/* +Copyright The Kubernetes 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 validate + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/operation" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +// DependentRequired verifies that when triggerIsSet(obj) is true, dependentIsSet(obj) +// is also true; otherwise reports an error at fldPath.Child(dependentName). +// On Update, the check is skipped if neither side's set-ness changed from oldObj, +// so unrelated updates can proceed past a pre-existing violation. +func DependentRequired[T any](_ context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *T, + triggerName string, triggerIsSet ExtractorFn[*T, bool], + dependentName string, dependentIsSet ExtractorFn[*T, bool], +) field.ErrorList { + if obj == nil { + return nil + } + if op.Type == operation.Update && oldObj != nil { + if triggerIsSet(obj) == triggerIsSet(oldObj) && dependentIsSet(obj) == dependentIsSet(oldObj) { + return nil + } + } + if !triggerIsSet(obj) { + return nil + } + if dependentIsSet(obj) { + return nil + } + return field.ErrorList{ + field.Required(fldPath.Child(dependentName), + fmt.Sprintf("must be set when %s is set", triggerName)). + WithOrigin("dependentRequired"), + } +} + +// DependentForbidden verifies that when triggerIsSet(obj) is true, dependentIsSet(obj) +// is false; otherwise reports an error at fldPath.Child(dependentName). +// On Update, the check is skipped if neither side's set-ness changed from oldObj, +// so unrelated updates can proceed past a pre-existing violation. +func DependentForbidden[T any](_ context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *T, + triggerName string, triggerIsSet ExtractorFn[*T, bool], + dependentName string, dependentIsSet ExtractorFn[*T, bool], +) field.ErrorList { + if obj == nil { + return nil + } + if op.Type == operation.Update && oldObj != nil { + if triggerIsSet(obj) == triggerIsSet(oldObj) && dependentIsSet(obj) == dependentIsSet(oldObj) { + return nil + } + } + if !triggerIsSet(obj) { + return nil + } + if !dependentIsSet(obj) { + return nil + } + return field.ErrorList{ + field.Forbidden(fldPath.Child(dependentName), + fmt.Sprintf("may not be set when %s is set", triggerName)). + WithOrigin("dependentForbidden"), + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go b/vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go index 787ae6b0..6f4b3cdd 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/discriminator.go @@ -35,6 +35,9 @@ type DiscriminatedRule[Tfield any, Tdisc comparable] struct { // // It performs ratcheting: if the operation is an Update, and neither the discriminator // nor the value (checked via equiv) have changed, validation is skipped. +// +// The equiv function can be called with nil arguments in the case of nilable +// fields. func Discriminated[Tfield any, Tdisc comparable, Tstruct any](ctx context.Context, op operation.Operation, structPath *field.Path, obj, oldObj *Tstruct, fieldName string, getMemberValue func(*Tstruct) Tfield, getDiscriminator func(*Tstruct) Tdisc, equiv MatchFunc[Tfield], defaultValidation ValidateFunc[Tfield], rules []DiscriminatedRule[Tfield, Tdisc], diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/each.go b/vendor/k8s.io/apimachinery/pkg/api/validate/each.go index c815d6d9..2930c218 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/each.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/each.go @@ -18,6 +18,7 @@ package validate import ( "context" + "slices" "sort" "k8s.io/apimachinery/pkg/api/equality" @@ -29,22 +30,29 @@ import ( // according to some criteria, and returns true if they match. type MatchFunc[T any] func(T, T) bool -// EachSliceVal performs validation on each element of newSlice using the provided validation function. +// EachValSliceVal performs validation on each element of a slice of values +// using the provided validation function. // -// For update operations, the match function finds corresponding values in oldSlice for each -// value in newSlice. This comparison can be either full or partial (e.g., matching only -// specific struct fields that serve as a unique identifier). If match is nil, validation -// proceeds without considering old values, and the equiv function is not used. +// For update operations, the match function finds corresponding values in +// oldSlice for each value in newSlice. This comparison can be either full or +// partial (e.g., matching only specific struct fields that serve as a unique +// identifier). If match is nil, validation proceeds without considering old +// values, and the equiv function is not used. // -// For update operations, the equiv function checks if a new value is equivalent to its -// corresponding old value, enabling validation ratcheting. If equiv is nil but match is -// provided, the match function is assumed to perform full value comparison. +// For update operations, the equiv function checks if a new value is +// equivalent to its corresponding old value, enabling validation ratcheting. +// If equiv is nil but match is provided, the match function is assumed to +// perform full value comparison. +// +// The match and equiv functions will never be called with nil arguments. // // Note: The slice element type must be non-nilable. -func EachSliceVal[T any](ctx context.Context, op operation.Operation, fldPath *field.Path, newSlice, oldSlice []T, - match, equiv MatchFunc[T], validator ValidateFunc[*T]) field.ErrorList { +func EachValSliceVal[T any](ctx context.Context, op operation.Operation, fldPath *field.Path, newSlice, oldSlice []T, + match, equiv MatchFunc[*T], validator ValidateFunc[*T]) field.ErrorList { var errs field.ErrorList - for i, val := range newSlice { + for i := range newSlice { + val := &newSlice[i] + var old *T if match != nil && len(oldSlice) > 0 { old = lookup(oldSlice, val, match) @@ -55,33 +63,90 @@ func EachSliceVal[T any](ctx context.Context, op operation.Operation, fldPath *f // 2. The equiv function confirms the values are equivalent (either directly or semantically) // // The equiv function provides equality comparison when match uses partial comparison. - if op.Type == operation.Update && old != nil && (equiv == nil || equiv(val, *old)) { + if op.Type == operation.Update && old != nil && (equiv == nil || equiv(val, old)) { + continue + } + errs = append(errs, validator(ctx, op, fldPath.Index(i), val, old)...) + } + return errs +} + +// EachPtrSliceVal performs validation on each element of a slice of pointers +// using the provided validation function. +// +// For update operations, the match function finds corresponding values in +// oldSlice for each value in newSlice. This comparison can be either full or +// partial (e.g., matching only specific struct fields that serve as a unique +// identifier). If match is nil, validation proceeds without considering old +// values, and the equiv function is not used. +// +// For update operations, the equiv function checks if a new value is +// equivalent to its corresponding old value, enabling validation ratcheting. +// If equiv is nil but match is provided, the match function is assumed to +// perform full value comparison. +// +// The match and equiv functions will never be called with nil arguments. +func EachPtrSliceVal[T any](ctx context.Context, op operation.Operation, fldPath *field.Path, newSlice, oldSlice []*T, + match, equiv MatchFunc[*T], validator ValidateFunc[*T]) field.ErrorList { + var errs field.ErrorList + for i := range newSlice { + val := newSlice[i] + if val == nil { + // Ignore nil items; they are supposed to have been checked by PtrSliceNoNils. + continue + } + + var old *T + if match != nil && len(oldSlice) > 0 { + old = lookupPointer(oldSlice, val, match) + } + if op.Type == operation.Update && old != nil && (equiv == nil || equiv(val, old)) { continue } - errs = append(errs, validator(ctx, op, fldPath.Index(i), &val, old)...) + errs = append(errs, validator(ctx, op, fldPath.Index(i), val, old)...) } return errs } // lookup returns a pointer to the first element in the list that matches the // target, according to the provided comparison function, or else nil. -func lookup[T any](list []T, target T, match MatchFunc[T]) *T { +func lookup[T any](list []T, target *T, match MatchFunc[*T]) *T { for i := range list { - if match(list[i], target) { + if match(&list[i], target) { return &list[i] } } return nil } +// lookupPointer returns the first non-nil element in the list that matches the +// target, according to the provided comparison function, or else nil. +// Nil elements in the list are skipped. +func lookupPointer[T any](list []*T, target *T, match MatchFunc[*T]) *T { + for i := range list { + if list[i] == nil { + // We can't really do anything about nil entries in the old list, + // just skip them. + continue + } + if match(list[i], target) { + return list[i] + } + } + return nil +} + // EachMapVal validates each value in newMap using the specified validation // function, passing the corresponding old value from oldMap if the key exists in oldMap. // For update operations, it implements validation ratcheting by skipping validation // when the old value exists and the equiv function confirms the values are equivalent. // The value-type of the map is assumed to not be nilable. +// +// The equiv function will never be called with nil arguments. +// // If equiv is nil, value-based ratcheting is disabled and all values will be validated. func EachMapVal[K ~string, V any](ctx context.Context, op operation.Operation, fldPath *field.Path, newMap, oldMap map[K]V, - equiv MatchFunc[V], validator ValidateFunc[*V]) field.ErrorList { + equiv MatchFunc[*V], validator ValidateFunc[*V]) field.ErrorList { var errs field.ErrorList for key, val := range newMap { var old *V @@ -90,7 +155,7 @@ func EachMapVal[K ~string, V any](ctx context.Context, op operation.Operation, f } // If the operation is an update, for validation ratcheting, skip re-validating if the old // value is found and the equiv function confirms the values are equivalent. - if op.Type == operation.Update && old != nil && equiv != nil && equiv(val, *old) { + if op.Type == operation.Update && old != nil && equiv != nil && equiv(&val, old) { continue } errs = append(errs, validator(ctx, op, fldPath.Key(string(key)), &val, old)...) @@ -119,19 +184,20 @@ func EachMapKey[K ~string, T any](ctx context.Context, op operation.Operation, f return errs } -// Unique verifies that each element of newSlice is unique, according to the -// match function. It compares every element of the slice with every other -// element and returns errors for non-unique items. -func Unique[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, newSlice, _ []T, match MatchFunc[T]) field.ErrorList { +// ValSliceUnique verifies that each element of a slice of values is unique, +// according to the match function. It compares every element of the slice with +// every other element and returns errors for non-unique items. +// +// The match function will never be called with nil arguments. +func ValSliceUnique[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, newSlice, _ []T, match MatchFunc[*T]) field.ErrorList { var dups []int - for i, val := range newSlice { + for i := range newSlice { for j := i + 1; j < len(newSlice); j++ { - other := newSlice[j] - if match(val, other) { + if match(&newSlice[i], &newSlice[j]) { if dups == nil { dups = make([]int, 0, len(newSlice)) } - if lookup(dups, j, func(a, b int) bool { return a == b }) == nil { + if !slices.Contains(dups, j) { dups = append(dups, j) } } @@ -152,6 +218,42 @@ func Unique[T any](_ context.Context, _ operation.Operation, fldPath *field.Path return errs } +// PtrSliceUnique verifies that each element of a slice of pointers is unique, +// according to the match function. It compares every element of the slice with +// every other element and returns errors for non-unique items. +// +// The match function will never be called with nil arguments. +func PtrSliceUnique[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, newSlice, _ []*T, match MatchFunc[*T]) field.ErrorList { + var errs field.ErrorList + var dups []int + for i := range newSlice { + if newSlice[i] == nil { + // Ignore nil items; they are supposed to have been checked by PtrSliceNoNils. + continue + } + for j := i + 1; j < len(newSlice); j++ { + if newSlice[j] == nil { + continue + } + if match(newSlice[i], newSlice[j]) { + if dups == nil { + dups = make([]int, 0, len(newSlice)) + } + if !slices.Contains(dups, j) { + dups = append(dups, j) + } + } + } + } + + sort.Ints(dups) + for _, i := range dups { + var val any = newSlice[i] + errs = append(errs, field.Duplicate(fldPath.Index(i), val)) + } + return errs +} + // SemanticDeepEqual is a MatchFunc that uses equality.Semantic.DeepEqual to // compare two values. // This wrapper is needed because MatchFunc requires a function that takes two @@ -163,19 +265,12 @@ func SemanticDeepEqual[T any](a, b T) bool { return equality.Semantic.DeepEqual(a, b) } -// DirectEqual is a MatchFunc that uses the == operator to compare two values. -// It can be used by any other function that needs to compare two values -// directly. -func DirectEqual[T comparable](a, b T) bool { - return a == b -} - -// DirectEqualPtr is a MatchFunc that dereferences two pointers and uses the == +// DirectEqual is a MatchFunc that dereferences two pointers and uses the == // operator to compare the values. If both pointers are nil, it returns true. // If one pointer is nil and the other is not, it returns false. // It can be used by any other function that needs to compare two pointees // directly. -func DirectEqualPtr[T comparable](a, b *T) bool { +func DirectEqual[T comparable](a, b *T) bool { if a == b { return true } @@ -184,3 +279,14 @@ func DirectEqualPtr[T comparable](a, b *T) bool { } return *a == *b } + +// PtrSliceNoNils returns a Required error for each nil element in a slice of +// pointers. +func PtrSliceNoNils[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, newSlice, _ []*T) (errs field.ErrorList) { + for i := range newSlice { + if newSlice[i] == nil { + errs = append(errs, field.Required(fldPath.Index(i), "")) + } + } + return +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/enum.go b/vendor/k8s.io/apimachinery/pkg/api/validate/enum.go index 6e5bcf37..4d8e2c0a 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/enum.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/enum.go @@ -18,6 +18,7 @@ package validate import ( "context" + "fmt" "slices" "k8s.io/apimachinery/pkg/api/operation" @@ -32,24 +33,36 @@ func Enum[T ~string](_ context.Context, op operation.Operation, fldPath *field.P if value == nil { return nil } - if !validValues.Has(*value) || isExcluded(op, exclusions, *value) { - return field.ErrorList{field.NotSupported[T](fldPath, *value, supportedValues(op, validValues, exclusions))} + excluded, err := isExcluded(op, exclusions, *value) + if err != nil { + return field.ErrorList{field.InternalError(fldPath, err)} + } + if !validValues.Has(*value) || excluded { + supported, err := supportedValues(op, validValues, exclusions) + if err != nil { + return field.ErrorList{field.InternalError(fldPath, err)} + } + return field.ErrorList{field.NotSupported[T](fldPath, *value, supported)} } return nil } // supportedValues returns a sorted list of supported values. // Excluded enum values are not included in the list. -func supportedValues[T ~string](op operation.Operation, values sets.Set[T], exclusions []EnumExclusion[T]) []T { +func supportedValues[T ~string](op operation.Operation, values sets.Set[T], exclusions []EnumExclusion[T]) ([]T, error) { res := make([]T, 0, len(values)) for key := range values { - if isExcluded(op, exclusions, key) { + excluded, err := isExcluded(op, exclusions, key) + if err != nil { + return nil, err + } + if excluded { continue } res = append(res, key) } slices.Sort(res) - return res + return res, nil } // EnumExclusion represents a single enum exclusion rule. @@ -64,11 +77,15 @@ type EnumExclusion[T ~string] struct { Option string } -func isExcluded[T ~string](op operation.Operation, exclusions []EnumExclusion[T], value T) bool { +func isExcluded[T ~string](op operation.Operation, exclusions []EnumExclusion[T], value T) (bool, error) { for _, rule := range exclusions { - if rule.Value == value && rule.ExcludeWhen == op.HasOption(rule.Option) { - return true + on, defined := op.HasOption(rule.Option) + if !defined { + return false, fmt.Errorf("undefined validation option %q", rule.Option) + } + if rule.Value == value && rule.ExcludeWhen == on { + return true, nil } } - return false + return false, nil } diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/errors.go b/vendor/k8s.io/apimachinery/pkg/api/validate/errors.go new file mode 100644 index 00000000..a9dc4b01 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/errors.go @@ -0,0 +1,96 @@ +/* +Copyright The Kubernetes 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 validate + +import ( + "context" + "errors" + + "k8s.io/apimachinery/pkg/util/validation/field" +) + +type allDeclarativeEnforcedKeyType struct{} + +var allDeclarativeEnforcedKey = allDeclarativeEnforcedKeyType{} + +// WithAllDeclarativeEnforcedForTest returns a copy of parent context with allDeclarativeEnforcedKey set to true. +// This is used for testing to expose all declarative validation errors and filter all handwritten validation errors +// that are covered by declarative validation, regardless of the feature gate or maturity level. +// +// NOTE: This function is intended for testing purposes only and should not be used in production code. +func WithAllDeclarativeEnforcedForTest(ctx context.Context) context.Context { + return context.WithValue(ctx, allDeclarativeEnforcedKey, true) +} + +// AllDeclarativeEnforced returns true if the context contains allDeclarativeEnforcedKey set to true. +func AllDeclarativeEnforced(ctx context.Context) bool { + if ctx == nil { + return false + } + return ctx.Value(allDeclarativeEnforcedKey) == true +} + +// FilterCoveredHandwrittenErrors removes a CoveredByDeclarative handwritten error when a matching enforced +// beta declarative error exists (matched by type, field, and origin). In AllDeclarativeEnforced +// (testing-only) mode every covered handwritten error is removed. +func FilterCoveredHandwrittenErrors(ctx context.Context, imperativeErrs, enforcedDeclarativeErrs field.ErrorList, betaEnabled bool, rules ...field.NormalizationRule) field.ErrorList { + matcher := field.ErrorMatcher{}.ByType().ByOrigin().RequireOriginWhenInvalid().ByFieldNormalized(rules) + allDeclarativeEnforced := AllDeclarativeEnforced(ctx) + return imperativeErrs.Filter(func(e error) bool { + var fe *field.Error + if !errors.As(e, &fe) || !fe.CoveredByDeclarative { + return false + } + if allDeclarativeEnforced { + return true + } + for _, dErr := range enforcedDeclarativeErrs { + if dErr.IsBeta() && matcher.Matches(fe, dErr) { + return true + } + } + return false + }) +} + +// FilterEnforcedDeclarativeErrors collects the declarative errors that are enforced (i.e. surfaced to the user) in the +// current mode. A declarative error is enforced when any of the following holds: +// - AllDeclarativeEnforced is set (testing): every declarative error is enforced. +// - It is an internal error: always enforced, regardless of lifecycle. +// - It is a beta error and BetaEnabled is true. +// - It is a standard (unprefixed) error: always enforced. +// +// Alpha errors are never enforced; they remain shadowed by handwritten validation. +func FilterEnforcedDeclarativeErrors(ctx context.Context, declarativeErrs field.ErrorList, betaEnabled bool) field.ErrorList { + enforcedDeclarativeErrs := make(field.ErrorList, 0, len(declarativeErrs)) + allDeclarativeEnforced := AllDeclarativeEnforced(ctx) + for _, dvErr := range declarativeErrs { + switch { + case allDeclarativeEnforced: + enforcedDeclarativeErrs = append(enforcedDeclarativeErrs, dvErr) + case dvErr.Type == field.ErrorTypeInternal: + enforcedDeclarativeErrs = append(enforcedDeclarativeErrs, dvErr) + case dvErr.IsBeta(): + if betaEnabled { + enforcedDeclarativeErrs = append(enforcedDeclarativeErrs, dvErr) + } + case !dvErr.IsAlpha(): + enforcedDeclarativeErrs = append(enforcedDeclarativeErrs, dvErr) // Standard + } + } + return enforcedDeclarativeErrs +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/item.go b/vendor/k8s.io/apimachinery/pkg/api/validate/item.go index aba417fa..4ddb2860 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/item.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/item.go @@ -23,36 +23,39 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" ) -// MatchItemFn takes a pointer to an item and returns true if it matches the criteria. -type MatchItemFn[T any] func(*T) bool +// MatchItemFunc takes an item and returns true if it matches the criteria. +type MatchItemFunc[T any] func(T) bool -// SliceItem finds the first item in newList that satisfies the match function, -// and if found, also looks for a matching item in oldList. If the value of the -// item is the same as the previous value, as per the equiv function, then no -// validation is performed. Otherwise, it invokes 'itemValidator' on these items. +// ValSliceItem finds the first item in a list of values which satisfies the +// match function, and if found, also looks for a matching item in oldList. If +// the value of the item is the same as the previous value, as per the equiv +// function, then no validation is performed. Otherwise, it invokes +// 'itemValidator' on these items. // // This function processes only the *first* matching item found in newList. It // assumes that the match functions targets a unique identifier (primary key) // and will match at most one element per list. If this assumption is violated, // changes in list order can lead this function to have inconsistent behavior. // +// The match and equiv functions will never be called with nil arguments. +// // The fldPath passed to itemValidator is indexed to the matched item's // position in newList. // // This function does not validate items that were removed (present in oldList // but not in newList). -func SliceItem[TList ~[]TItem, TItem any]( +func ValSliceItem[TList ~[]TItem, TItem any]( ctx context.Context, op operation.Operation, fldPath *field.Path, newList, oldList TList, - matches MatchItemFn[TItem], - equiv MatchFunc[TItem], + match MatchItemFunc[*TItem], + equiv MatchFunc[*TItem], itemValidator func(ctx context.Context, op operation.Operation, fldPath *field.Path, newObj, oldObj *TItem) field.ErrorList, ) field.ErrorList { var matchedNew, matchedOld *TItem var newIndex int for i := range newList { - if matches(&newList[i]) { + if match(&newList[i]) { matchedNew = &newList[i] newIndex = i break @@ -63,13 +66,73 @@ func SliceItem[TList ~[]TItem, TItem any]( } for i := range oldList { - if matches(&oldList[i]) { + if match(&oldList[i]) { matchedOld = &oldList[i] break } } - if op.Type == operation.Update && matchedOld != nil && equiv(*matchedNew, *matchedOld) { + if op.Type == operation.Update && matchedOld != nil && equiv(matchedNew, matchedOld) { + return nil + } + + return itemValidator(ctx, op, fldPath.Index(newIndex), matchedNew, matchedOld) +} + +// PtrSliceItem finds the first item in a list of pointers which satisfies the +// match function, and if found, also looks for a matching item in oldList. If +// the value of the item is the same as the previous value, as per the equiv +// function, then no validation is performed. Otherwise, it invokes +// 'itemValidator' on these items. +// +// This function processes only the *first* matching item found in newList. It +// assumes that the match functions targets a unique identifier (primary key) +// and will match at most one element per list. If this assumption is violated, +// changes in list order can lead this function to have inconsistent behavior. +// +// The match and equiv functions will never be called with nil arguments. +// +// The fldPath passed to itemValidator is indexed to the matched item's +// position in newList. +// +// This function does not validate items that were removed (present in oldList +// but not in newList). +func PtrSliceItem[TList ~[]*TItem, TItem any]( + ctx context.Context, op operation.Operation, fldPath *field.Path, + newList, oldList TList, + match MatchItemFunc[*TItem], + equiv MatchFunc[*TItem], + itemValidator func(ctx context.Context, op operation.Operation, fldPath *field.Path, newObj, oldObj *TItem) field.ErrorList, +) field.ErrorList { + var matchedNew, matchedOld *TItem + var newIndex int + + for i := range newList { + if newList[i] == nil { + // Ignore nil items; they are supposed to have been checked by PtrSliceNoNils. + continue + } + if match(newList[i]) { + matchedNew = newList[i] + newIndex = i + break + } + } + if matchedNew == nil { + return nil + } + + for i := range oldList { + if oldList[i] == nil { + continue + } + if match(oldList[i]) { + matchedOld = oldList[i] + break + } + } + + if op.Type == operation.Update && matchedOld != nil && equiv(matchedNew, matchedOld) { return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go b/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go index dcc7f518..768546f6 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/limits.go @@ -78,6 +78,18 @@ func MaxItems[T any](_ context.Context, _ operation.Operation, fldPath *field.Pa return nil } +// MaxProperties verifies that the specified map has no more than max keys. +func MaxProperties[K comparable, V any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ map[K]V, max int) field.ErrorList { + if value == nil { + return nil + } + + if len(value) > max { + return field.ErrorList{field.TooMany(fldPath, len(value), max).WithOrigin("maxProperties")} + } + return nil +} + // MinItems verifies that the specified slice is not shorter than min items. func MinItems[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []T, min int) field.ErrorList { if len(value) < min { @@ -86,6 +98,14 @@ func MinItems[T any](_ context.Context, _ operation.Operation, fldPath *field.Pa return nil } +// MinProperties verifies that the specified map is not shorter than min properties. +func MinProperties[K comparable, V any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ map[K]V, min int) field.ErrorList { + if len(value) < min { + return field.ErrorList{field.TooFew(fldPath, len(value), min).WithOrigin("minProperties")} + } + return nil +} + // Minimum verifies that the specified value is greater than or equal to min. func Minimum[T constraints.Integer](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T, min T) field.ErrorList { if value == nil { diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/monotonic.go b/vendor/k8s.io/apimachinery/pkg/api/validate/monotonic.go new file mode 100644 index 00000000..f0526c9f --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/monotonic.go @@ -0,0 +1,43 @@ +/* +Copyright 2025 The Kubernetes 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 validate + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/operation" + "k8s.io/apimachinery/pkg/api/validate/constraints" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +// Monotonic validates that an integer value has not decreased on update. +func Monotonic[T constraints.Integer](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *T) field.ErrorList { + if op.Type != operation.Update { + return nil + } + + if value == nil || oldValue == nil { + return nil + } + + if *value < *oldValue { + return field.ErrorList{field.Invalid(fldPath, *value, fmt.Sprintf("may not be decreased from %v", *oldValue)).WithOrigin("monotonic")} + } + + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/options.go b/vendor/k8s.io/apimachinery/pkg/api/validate/options.go index 44236550..143be3b6 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/options.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/options.go @@ -18,6 +18,7 @@ package validate import ( "context" + "fmt" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/util/validation/field" @@ -25,10 +26,14 @@ import ( // IfOption conditionally evaluates a validation function. If the option and enabled are both true the validator // is called. If the option and enabled are both false the validator is called. Otherwise, the validator is not called. -func IfOption[T any](ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *T, - optionName string, enabled bool, validator func(context.Context, operation.Operation, *field.Path, *T, *T) field.ErrorList, +func IfOption[T any](ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue T, + optionName string, enabled bool, validator func(context.Context, operation.Operation, *field.Path, T, T) field.ErrorList, ) field.ErrorList { - if op.HasOption(optionName) == enabled { + on, defined := op.HasOption(optionName) + if !defined { + return field.ErrorList{field.InternalError(fldPath, fmt.Errorf("undefined validation option %q", optionName))} + } + if on == enabled { return validator(ctx, op, fldPath, value, oldValue) } return nil diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go b/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go index 190fa8db..893f55d7 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/strfmt.go @@ -97,6 +97,28 @@ func LabelKey[T ~string](_ context.Context, op operation.Operation, fldPath *fie return allErrs } +// PrefixedLabelKey verifies that the specified value is a valid label key with +// a domain prefix. +// A prefixed label key is composed of a prefix and a name, separated by a '/'. +// The name part is required and must: +// - be 63 characters or less +// - begin and end with an alphanumeric character ([a-z0-9A-Z]) +// - contain only alphanumeric characters, dashes (-), underscores (_), or dots (.) +// +// The prefix must: +// - be a DNS subdomain +// - be no more than 253 characters +func PrefixedLabelKey[T ~string](_ context.Context, op operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList { + if value == nil { + return nil + } + var allErrs field.ErrorList + for _, msg := range content.IsPrefixedLabelKey((string)(*value)) { + allErrs = append(allErrs, field.Invalid(fldPath, *value, msg).WithOrigin("format=k8s-prefixed-label-key")) + } + return allErrs +} + // LongNameCaseless verifies that the specified value is a valid "long name" // (sometimes known as a "DNS subdomain"), but is case-insensitive. // - must not be empty diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/subfield.go b/vendor/k8s.io/apimachinery/pkg/api/validate/subfield.go index 896f3c3f..7aa48d33 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/subfield.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/subfield.go @@ -31,6 +31,9 @@ type GetFieldFunc[Tstruct any, Tfield any] func(*Tstruct) Tfield // the value of the subfield is the same as the previous value, as per the // equiv function, then no validation is performed. // +// The equiv function can be called with nil arguments in the case of nilable +// fields. +// // The fldPath passed to the validator includes the subfield name. func Subfield[Tstruct any, Tfield any]( ctx context.Context, op operation.Operation, fldPath *field.Path, diff --git a/vendor/k8s.io/apimachinery/pkg/api/validate/update.go b/vendor/k8s.io/apimachinery/pkg/api/validate/update.go index e67ee28d..c258e6d1 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validate/update.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validate/update.go @@ -18,6 +18,8 @@ package validate import ( "context" + "fmt" + "slices" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/operation" @@ -34,11 +36,16 @@ const ( NoUnset // NoModify prevents value changes but allows set/unset transitions NoModify + // NoAddItem prevents adding items to a slice or map + NoAddItem + // NoRemoveItem prevents removing items from a slice or map + NoRemoveItem ) // UpdateValueByCompare verifies update constraints for comparable value types. func UpdateValueByCompare[T comparable](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *T, constraints ...UpdateConstraint) field.ErrorList { - if op.Type != operation.Update { + // nil oldValue means no prior value to compare against (eg: a new item at +k8s:eachVal scope) -> no transition to check. + if op.Type != operation.Update || oldValue == nil { return nil } @@ -101,7 +108,8 @@ func UpdatePointer[T any](_ context.Context, op operation.Operation, fldPath *fi // UpdateValueByReflect verifies update constraints for non-comparable value types using reflection. func UpdateValueByReflect[T any](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *T, constraints ...UpdateConstraint) field.ErrorList { - if op.Type != operation.Update { + // nil oldValue means no prior value to compare against (eg: a new item at +k8s:eachVal scope) -> no transition to check. + if op.Type != operation.Update || oldValue == nil { return nil } @@ -136,7 +144,8 @@ func UpdateValueByReflect[T any](_ context.Context, op operation.Operation, fldP // UpdateStruct verifies update constraints for non-pointer struct types. // Non-pointer structs are always considered "set" and never "unset". func UpdateStruct[T any](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *T, constraints ...UpdateConstraint) field.ErrorList { - if op.Type != operation.Update { + // nil oldValue means no prior value to compare against (eg: a new item at +k8s:eachVal scope) -> no transition to check. + if op.Type != operation.Update || oldValue == nil { return nil } @@ -158,3 +167,142 @@ func UpdateStruct[T any](_ context.Context, op operation.Operation, fldPath *fie return errs } + +// ValSliceUpdate verifies update constraints for slices of values. +// NoAddItem and NoRemoveItem use the match function to find corresponding +// elements between value and oldValue. NoSet and NoUnset treat len == 0 as +// "unset". +// +// The match function will never be called with nil arguments. +func ValSliceUpdate[T any](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue []T, match MatchFunc[*T], constraints ...UpdateConstraint) field.ErrorList { + if op.Type != operation.Update { + return nil + } + + if match == nil && (slices.Contains(constraints, NoAddItem) || slices.Contains(constraints, NoRemoveItem)) { + return field.ErrorList{field.InternalError(fldPath, fmt.Errorf("ValSliceUpdate: NoAddItem/NoRemoveItem require a non-nil match function"))} + } + + var errs field.ErrorList + + for _, constraint := range constraints { + switch constraint { + case NoSet: + if len(oldValue) == 0 && len(value) > 0 { + errs = append(errs, field.Invalid(fldPath, nil, "field cannot be set once created").WithOrigin("update")) + } + case NoUnset: + if len(oldValue) > 0 && len(value) == 0 { + errs = append(errs, field.Invalid(fldPath, nil, "field cannot be cleared once set").WithOrigin("update")) + } + case NoAddItem: + for i := range value { + newItem := &value[i] + if lookup(oldValue, newItem, match) == nil { + errs = append(errs, field.Forbidden(fldPath.Index(i), "item may not be added").WithOrigin("update")) + } + } + case NoRemoveItem: + for i := range oldValue { + oldItem := &oldValue[i] + if lookup(value, oldItem, match) == nil { + errs = append(errs, field.Forbidden(fldPath, "item may not be removed").WithOrigin("update")) + } + } + } + } + + return errs +} + +// PtrSliceUpdate verifies update constraints for slices of pointers. +// NoAddItem and NoRemoveItem use the match function to find corresponding +// elements between value and oldValue. NoSet and NoUnset treat len == 0 as +// "unset". +// +// The match function will never be called with nil arguments. +func PtrSliceUpdate[T any](ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue []*T, match MatchFunc[*T], constraints ...UpdateConstraint) field.ErrorList { + if op.Type != operation.Update { + return nil + } + + if match == nil && (slices.Contains(constraints, NoAddItem) || slices.Contains(constraints, NoRemoveItem)) { + return field.ErrorList{field.InternalError(fldPath, fmt.Errorf("PtrSliceUpdate: NoAddItem/NoRemoveItem require a non-nil match function"))} + } + + var errs field.ErrorList + + for _, constraint := range constraints { + switch constraint { + case NoSet: + if len(oldValue) == 0 && len(value) > 0 { + errs = append(errs, field.Invalid(fldPath, nil, "field cannot be set once created").WithOrigin("update")) + } + case NoUnset: + if len(oldValue) > 0 && len(value) == 0 { + errs = append(errs, field.Invalid(fldPath, nil, "field cannot be cleared once set").WithOrigin("update")) + } + case NoAddItem: + for i := range value { + newItem := value[i] + if newItem == nil { + // Ignore nil items; they are supposed to have been checked by PtrSliceNoNils. + continue + } + if lookupPointer(oldValue, newItem, match) == nil { + errs = append(errs, field.Forbidden(fldPath.Index(i), "item may not be added").WithOrigin("update")) + } + } + case NoRemoveItem: + for i := range oldValue { + oldItem := oldValue[i] + if oldItem == nil { + continue + } + if lookupPointer(value, oldItem, match) == nil { + errs = append(errs, field.Forbidden(fldPath, "item may not be removed").WithOrigin("update")) + } + } + } + } + + return errs +} + +// UpdateMap verifies update constraints for map types. +// NoAddItem and NoRemoveItem compare keys between value and oldValue. NoSet +// and NoUnset treat len == 0 as "unset". +func UpdateMap[K comparable, V any](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue map[K]V, constraints ...UpdateConstraint) field.ErrorList { + if op.Type != operation.Update { + return nil + } + + var errs field.ErrorList + + for _, constraint := range constraints { + switch constraint { + case NoSet: + if len(oldValue) == 0 && len(value) > 0 { + errs = append(errs, field.Invalid(fldPath, nil, "field cannot be set once created").WithOrigin("update")) + } + case NoUnset: + if len(oldValue) > 0 && len(value) == 0 { + errs = append(errs, field.Invalid(fldPath, nil, "field cannot be cleared once set").WithOrigin("update")) + } + case NoAddItem: + for k := range value { + if _, ok := oldValue[k]; !ok { + errs = append(errs, field.Forbidden(fldPath.Key(fmt.Sprintf("%v", k)), "item may not be added").WithOrigin("update")) + } + } + case NoRemoveItem: + for k := range oldValue { + if _, ok := value[k]; !ok { + errs = append(errs, field.Forbidden(fldPath.Key(fmt.Sprintf("%v", k)), "item may not be removed").WithOrigin("update")) + } + } + } + } + + return errs +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go index 9a4f3784..ff86973f 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go +++ b/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go @@ -17,11 +17,14 @@ limitations under the License. package validation import ( + "context" "fmt" "strings" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/operation" + "k8s.io/apimachinery/pkg/api/validate" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" "k8s.io/apimachinery/pkg/runtime/schema" @@ -68,20 +71,23 @@ func ValidateAnnotationsSize(annotations map[string]string) error { func validateOwnerReference(ownerReference metav1.OwnerReference, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - gvk := schema.FromAPIVersionAndKind(ownerReference.APIVersion, ownerReference.Kind) + gv, err := schema.ParseGroupVersion(ownerReference.APIVersion) // gvk.Group is empty for the legacy group. - if len(gvk.Version) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("apiVersion"), ownerReference.APIVersion, "version must not be empty")) + if len(ownerReference.APIVersion) == 0 { + allErrs = append(allErrs, field.Required(fldPath.Child("apiVersion"), "must not be empty").MarkCoveredByDeclarative()) + } else if err != nil || len(gv.Version) == 0 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("apiVersion"), ownerReference.APIVersion, "must be / or ")) } - if len(gvk.Kind) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("kind"), ownerReference.Kind, "must not be empty")) + if len(ownerReference.Kind) == 0 { + allErrs = append(allErrs, field.Required(fldPath.Child("kind"), "must not be empty").MarkCoveredByDeclarative()) } if len(ownerReference.Name) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), ownerReference.Name, "must not be empty")) + allErrs = append(allErrs, field.Required(fldPath.Child("name"), "must not be empty").MarkCoveredByDeclarative()) } if len(ownerReference.UID) == 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("uid"), ownerReference.UID, "must not be empty")) + allErrs = append(allErrs, field.Required(fldPath.Child("uid"), "must not be empty").MarkCoveredByDeclarative()) } + gvk := gv.WithKind(ownerReference.Kind) if _, ok := BannedOwners[gvk]; ok { allErrs = append(allErrs, field.Invalid(fldPath, ownerReference, fmt.Sprintf("%s is disallowed from being an owner", gvk))) } @@ -92,8 +98,8 @@ func validateOwnerReference(ownerReference metav1.OwnerReference, fldPath *field func ValidateOwnerReferences(ownerReferences []metav1.OwnerReference, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} firstControllerName := "" - for _, ref := range ownerReferences { - allErrs = append(allErrs, validateOwnerReference(ref, fldPath)...) + for idx, ref := range ownerReferences { + allErrs = append(allErrs, validateOwnerReference(ref, fldPath.Index(idx))...) if ref.Controller != nil && *ref.Controller { curControllerName := ref.Kind + "/" + ref.Name if firstControllerName != "" { @@ -136,6 +142,25 @@ func ValidateImmutableField(newVal, oldVal interface{}, fldPath *field.Path) fie return allErrs } +// ValidateObjectMetaDeclaratively validates an ObjectMeta instance declaratively and deduplicates handwritten errors. +// betaEnabled controls whether declarative validation rules at the Beta stability level are enforced. +// NOTE: This method should be used in the types for which declarative validation is not enabled yet or cannot be enabled. The types +// for which declarative validation is enabled and valdiation code is generated must use ValidateObjectMeta and ValidateObjectMetaUpdate. +func ValidateObjectMetaDeclaratively(ctx context.Context, op operation.Type, obj, oldObj *metav1.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path, betaEnabled bool) field.ErrorList { + var errs field.ErrorList + switch op { + case operation.Create: + errs = ValidateObjectMeta(obj, requiresNamespace, nameFn, fldPath) + case operation.Update: + errs = ValidateObjectMetaUpdate(obj, oldObj, fldPath) + } + dvErrs := v1validation.Validate_ObjectMeta(ctx, operation.Operation{Type: op}, fldPath, obj, oldObj) + enforcedDVErrs := validate.FilterEnforcedDeclarativeErrors(ctx, dvErrs, betaEnabled) + errs = errs.MarkFromImperative() + errs = validate.FilterCoveredHandwrittenErrors(ctx, errs, enforcedDVErrs, betaEnabled) + return append(errs, enforcedDVErrs...) +} + // ValidateObjectMeta validates an object's metadata on creation. It expects that name generation has already // been performed. func ValidateObjectMeta(objMeta *metav1.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList { @@ -262,12 +287,12 @@ func validateObjectMetaAccessorWithOptsCommon(meta metav1.Object, isNamespaced b } } - allErrs = append(allErrs, ValidateNonnegativeField(meta.GetGeneration(), fldPath.Child("generation"))...) + allErrs = append(allErrs, ValidateNonnegativeField(meta.GetGeneration(), fldPath.Child("generation")).MarkCoveredByDeclarative()...) allErrs = append(allErrs, v1validation.ValidateLabels(meta.GetLabels(), fldPath.Child("labels"))...) allErrs = append(allErrs, ValidateAnnotations(meta.GetAnnotations(), fldPath.Child("annotations"))...) allErrs = append(allErrs, ValidateOwnerReferences(meta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...) allErrs = append(allErrs, ValidateFinalizers(meta.GetFinalizers(), fldPath.Child("finalizers"))...) - allErrs = append(allErrs, v1validation.ValidateManagedFields(meta.GetManagedFields(), fldPath.Child("managedFields"))...) + allErrs = append(allErrs, v1validation.ValidateManagedFields(meta.GetManagedFields(), fldPath.Child("managedFields"), v1validation.CoveredByDeclarative)...) return allErrs } @@ -323,21 +348,22 @@ func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *f } // Generation shouldn't be decremented + allErrs = append(allErrs, ValidateNonnegativeField(newMeta.GetGeneration(), fldPath.Child("generation")).MarkCoveredByDeclarative()...) if newMeta.GetGeneration() < oldMeta.GetGeneration() { allErrs = append(allErrs, field.Invalid(fldPath.Child("generation"), newMeta.GetGeneration(), "must not be decremented")) } allErrs = append(allErrs, ValidateImmutableField(newMeta.GetName(), oldMeta.GetName(), fldPath.Child("name"))...) allErrs = append(allErrs, ValidateImmutableField(newMeta.GetNamespace(), oldMeta.GetNamespace(), fldPath.Child("namespace"))...) - allErrs = append(allErrs, ValidateImmutableField(newMeta.GetUID(), oldMeta.GetUID(), fldPath.Child("uid"))...) - allErrs = append(allErrs, ValidateImmutableField(newMeta.GetCreationTimestamp(), oldMeta.GetCreationTimestamp(), fldPath.Child("creationTimestamp"))...) - allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionTimestamp(), oldMeta.GetDeletionTimestamp(), fldPath.Child("deletionTimestamp"))...) - allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionGracePeriodSeconds(), oldMeta.GetDeletionGracePeriodSeconds(), fldPath.Child("deletionGracePeriodSeconds"))...) + allErrs = append(allErrs, ValidateImmutableField(newMeta.GetUID(), oldMeta.GetUID(), fldPath.Child("uid")).WithOrigin("immutable").MarkCoveredByDeclarative()...) + allErrs = append(allErrs, ValidateImmutableField(newMeta.GetCreationTimestamp(), oldMeta.GetCreationTimestamp(), fldPath.Child("creationTimestamp")).WithOrigin("immutable").MarkCoveredByDeclarative()...) + allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionTimestamp(), oldMeta.GetDeletionTimestamp(), fldPath.Child("deletionTimestamp")).WithOrigin("immutable").MarkCoveredByDeclarative()...) + allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionGracePeriodSeconds(), oldMeta.GetDeletionGracePeriodSeconds(), fldPath.Child("deletionGracePeriodSeconds")).WithOrigin("immutable").MarkCoveredByDeclarative()...) allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.GetLabels(), fldPath.Child("labels"))...) allErrs = append(allErrs, ValidateAnnotations(newMeta.GetAnnotations(), fldPath.Child("annotations"))...) allErrs = append(allErrs, ValidateOwnerReferences(newMeta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...) - allErrs = append(allErrs, v1validation.ValidateManagedFields(newMeta.GetManagedFields(), fldPath.Child("managedFields"))...) + allErrs = append(allErrs, v1validation.ValidateManagedFields(newMeta.GetManagedFields(), fldPath.Child("managedFields"), v1validation.CoveredByDeclarative)...) return allErrs } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto index d03a7331..afc9b250 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto @@ -179,6 +179,9 @@ message ApplyOptions { // // +patchStrategy=merge // // +listType=map // // +listMapKey=type +// // +k8s:alpha(since: "1.37")=+k8s:optional +// // +k8s:alpha(since: "1.37")=+k8s:listType=map +// // +k8s:alpha(since: "1.37")=+k8s:listMapKey=type // Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // // // other fields @@ -193,12 +196,14 @@ message Condition { // +kubebuilder:validation:Required // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` // +kubebuilder:validation:MaxLength=316 + // +k8s:alpha(since: "1.37")=+k8s:required optional string type = 1; // status of the condition, one of True, False, Unknown. // +required // +kubebuilder:validation:Required // +kubebuilder:validation:Enum=True;False;Unknown + // +k8s:alpha(since: "1.37")=+k8s:required optional string status = 2; // observedGeneration represents the .metadata.generation that the condition was set based upon. @@ -206,6 +211,8 @@ message Condition { // with respect to the current state of the instance. // +optional // +kubebuilder:validation:Minimum=0 + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:minimum=0 optional int64 observedGeneration = 3; // lastTransitionTime is the last time the condition transitioned from one status to another. @@ -214,6 +221,7 @@ message Condition { // +kubebuilder:validation:Required // +kubebuilder:validation:Type=string // +kubebuilder:validation:Format=date-time + // +k8s:alpha(since: "1.37")=+k8s:customValidation optional Time lastTransitionTime = 4; // reason contains a programmatic identifier indicating the reason for the condition's last transition. @@ -226,6 +234,8 @@ message Condition { // +kubebuilder:validation:MaxLength=1024 // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Pattern=`^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$` + // +k8s:alpha(since: "1.37")=+k8s:required + // +k8s:alpha(since: "1.37")=+k8s:maxBytes=1024 optional string reason = 5; // message is a human readable message indicating details about the transition. @@ -700,6 +710,7 @@ message ManagedFieldsEntry { // Operation is the type of operation which lead to this ManagedFieldsEntry being created. // The only valid values for this field are 'Apply' and 'Update'. + // +k8s:alpha(since: "1.37")=+k8s:required optional string operation = 2; // APIVersion defines the version of this resource that this field set @@ -802,6 +813,8 @@ message ObjectMeta { // Read-only. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:immutable optional string uid = 5; // An opaque value that represents the internal version of this object that can @@ -820,6 +833,8 @@ message ObjectMeta { // A sequence number representing a specific generation of the desired state. // Populated by the system. Read-only. // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:minimum=0 optional int64 generation = 7; // CreationTimestamp is a timestamp representing the server time when this object was @@ -831,6 +846,7 @@ message ObjectMeta { // Null for lists. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional + // +k8s:alpha(since: "1.37")=+k8s:immutable optional Time creationTimestamp = 8; // DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This @@ -852,6 +868,8 @@ message ObjectMeta { // Read-only. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:immutable optional Time deletionTimestamp = 9; // Number of seconds allowed for this object to gracefully terminate before @@ -859,6 +877,8 @@ message ObjectMeta { // May only be shortened. // Read-only. // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:immutable optional int64 deletionGracePeriodSeconds = 10; // Map of string keys and values that can be used to organize and categorize @@ -884,6 +904,7 @@ message ObjectMeta { // +patchStrategy=merge // +listType=map // +listMapKey=uid + // +k8s:alpha(since:"1.37")=+k8s:optional repeated OwnerReference ownerReferences = 13; // Must be empty before the object is deleted from the registry. Each entry @@ -914,6 +935,7 @@ message ObjectMeta { // // +optional // +listType=atomic + // +k8s:alpha(since: "1.37")=+k8s:optional repeated ManagedFieldsEntry managedFields = 17; } @@ -923,18 +945,22 @@ message ObjectMeta { // +structType=atomic message OwnerReference { // API version of the referent. + // +k8s:alpha(since:"1.37")=+k8s:required optional string apiVersion = 5; // Kind of the referent. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +k8s:alpha(since:"1.37")=+k8s:required optional string kind = 1; // Name of the referent. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + // +k8s:alpha(since:"1.37")=+k8s:required optional string name = 3; // UID of the referent. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + // +k8s:alpha(since:"1.37")=+k8s:required optional string uid = 4; // If true, this reference points to the managing controller. @@ -960,6 +986,7 @@ message PartialObjectMetadata { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional + // +k8s:opaqueType optional ObjectMeta metadata = 1; } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index c8b87f20..f88212e1 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -176,6 +176,8 @@ type ObjectMeta struct { // Read-only. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:immutable UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"` // An opaque value that represents the internal version of this object that can @@ -194,6 +196,8 @@ type ObjectMeta struct { // A sequence number representing a specific generation of the desired state. // Populated by the system. Read-only. // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:minimum=0 Generation int64 `json:"generation,omitempty" protobuf:"varint,7,opt,name=generation"` // CreationTimestamp is a timestamp representing the server time when this object was @@ -205,6 +209,7 @@ type ObjectMeta struct { // Null for lists. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional + // +k8s:alpha(since: "1.37")=+k8s:immutable CreationTimestamp Time `json:"creationTimestamp,omitempty,omitzero" protobuf:"bytes,8,opt,name=creationTimestamp"` // DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This @@ -226,6 +231,8 @@ type ObjectMeta struct { // Read-only. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:immutable DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"` // Number of seconds allowed for this object to gracefully terminate before @@ -233,6 +240,8 @@ type ObjectMeta struct { // May only be shortened. // Read-only. // +optional + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:immutable DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"` // Map of string keys and values that can be used to organize and categorize @@ -258,6 +267,7 @@ type ObjectMeta struct { // +patchStrategy=merge // +listType=map // +listMapKey=uid + // +k8s:alpha(since:"1.37")=+k8s:optional OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"` // Must be empty before the object is deleted from the registry. Each entry @@ -292,6 +302,7 @@ type ObjectMeta struct { // // +optional // +listType=atomic + // +k8s:alpha(since: "1.37")=+k8s:optional ManagedFields []ManagedFieldsEntry `json:"managedFields,omitempty" protobuf:"bytes,17,rep,name=managedFields"` } @@ -314,15 +325,19 @@ const ( // +structType=atomic type OwnerReference struct { // API version of the referent. + // +k8s:alpha(since:"1.37")=+k8s:required APIVersion string `json:"apiVersion" protobuf:"bytes,5,opt,name=apiVersion"` // Kind of the referent. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // +k8s:alpha(since:"1.37")=+k8s:required Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // Name of the referent. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + // +k8s:alpha(since:"1.37")=+k8s:required Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // UID of the referent. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + // +k8s:alpha(since:"1.37")=+k8s:required UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"` // If true, this reference points to the managing controller. // +optional @@ -344,7 +359,7 @@ type OwnerReference struct { // ListOptions is the query options to a standard REST list call. type ListOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // A selector to restrict the list of returned objects by their labels. // Defaults to everything. @@ -517,7 +532,7 @@ const ( // GetOptions is the standard query options to the standard REST get call. type GetOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // resourceVersion sets a constraint on what resource versions a request may be served from. // See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for // details. @@ -557,7 +572,7 @@ const ( // DeleteOptions may be provided when deleting an API object. type DeleteOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // The duration in seconds before the object should be deleted. Value must be non-negative integer. // The value zero indicates delete immediately. If this value is nil, the default grace period for the @@ -629,7 +644,7 @@ const ( // CreateOptions may be provided when creating an API object. type CreateOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // When present, indicates that modifications should not be // persisted. An invalid or unrecognized dryRun directive will @@ -674,7 +689,7 @@ type CreateOptions struct { // PatchOptions may be provided when patching an API object. // PatchOptions is meant to be a superset of UpdateOptions. type PatchOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // When present, indicates that modifications should not be // persisted. An invalid or unrecognized dryRun directive will @@ -726,7 +741,7 @@ type PatchOptions struct { // ApplyOptions is equivalent to PatchOptions. It is provided as a convenience with documentation // that speaks specifically to how the options fields relate to apply. type ApplyOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // When present, indicates that modifications should not be // persisted. An invalid or unrecognized dryRun directive will @@ -759,7 +774,7 @@ func (o ApplyOptions) ToPatchOptions() PatchOptions { // UpdateOptions may be provided when updating an API object. // All fields in UpdateOptions should also be present in PatchOptions. type UpdateOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // When present, indicates that modifications should not be // persisted. An invalid or unrecognized dryRun directive will @@ -811,7 +826,7 @@ type Preconditions struct { // Status is a return value for calls that don't return other objects. type Status struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional @@ -1131,7 +1146,7 @@ const ( // List holds a list of objects, which may not be known by the server. type List struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional @@ -1147,7 +1162,7 @@ type List struct { // +protobuf.options.(gogoproto.goproto_stringer)=false // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type APIVersions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // versions are the api versions that are available. // +listType=atomic Versions []string `json:"versions" protobuf:"bytes,1,rep,name=versions"` @@ -1167,7 +1182,7 @@ type APIVersions struct { // APIGroupList is a list of APIGroup, to allow clients to discover the API at // /apis. type APIGroupList struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // groups is a list of APIGroup. // +listType=atomic Groups []APIGroup `json:"groups" protobuf:"bytes,1,rep,name=groups"` @@ -1178,7 +1193,7 @@ type APIGroupList struct { // APIGroup contains the name, the supported versions, and the preferred version // of a group. type APIGroup struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // name is the name of the group. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` // versions are the versions supported in this group. @@ -1273,7 +1288,7 @@ func (vs Verbs) String() string { // resources supported in a specific group and version, and if the resource // is namespaced. type APIResourceList struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // groupVersion is the group and version this APIResourceList is for. GroupVersion string `json:"groupVersion" protobuf:"bytes,1,opt,name=groupVersion"` // resources contains the name of the resources and if they are namespaced. @@ -1394,6 +1409,7 @@ type ManagedFieldsEntry struct { Manager string `json:"manager,omitempty" protobuf:"bytes,1,opt,name=manager"` // Operation is the type of operation which lead to this ManagedFieldsEntry being created. // The only valid values for this field are 'Apply' and 'Update'. + // +k8s:alpha(since: "1.37")=+k8s:required Operation ManagedFieldsOperationType `json:"operation,omitempty" protobuf:"bytes,2,opt,name=operation,casttype=ManagedFieldsOperationType"` // APIVersion defines the version of this resource that this field set // applies to. The format is "group/version" just like the top-level @@ -1429,6 +1445,7 @@ type ManagedFieldsEntry struct { } // ManagedFieldsOperationType is the type of operation which lead to a ManagedFieldsEntry being created. +// +k8s:alpha(since: "1.37")=+k8s:enum type ManagedFieldsOperationType string const ( @@ -1446,7 +1463,7 @@ const ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +protobuf=false type Table struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional @@ -1537,6 +1554,7 @@ const ( RowCompleted RowConditionType = "Completed" ) +// +k8s:alpha(since: "1.37")=+k8s:enum type ConditionStatus string // These are valid condition statuses. "ConditionTrue" means a resource is in the condition. @@ -1565,7 +1583,7 @@ const ( // +k8s:conversion-gen:explicit-from=net/url.Values // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type TableOptions struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // NoHeaders is only exposed for internal callers. It is not included in our OpenAPI definitions // and may be removed as a field in a future release. @@ -1582,17 +1600,18 @@ type TableOptions struct { // to get access to a particular ObjectMeta schema without knowing the details of the version. // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type PartialObjectMetadata struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional + // +k8s:opaqueType ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` } // PartialObjectMetadataList contains a list of objects containing only their metadata // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type PartialObjectMetadataList struct { - TypeMeta `json:",inline"` + TypeMeta `json:""` // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional @@ -1613,6 +1632,9 @@ type PartialObjectMetadataList struct { // // +patchStrategy=merge // // +listType=map // // +listMapKey=type +// // +k8s:alpha(since: "1.37")=+k8s:optional +// // +k8s:alpha(since: "1.37")=+k8s:listType=map +// // +k8s:alpha(since: "1.37")=+k8s:listMapKey=type // Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` // // // other fields @@ -1627,17 +1649,21 @@ type Condition struct { // +kubebuilder:validation:Required // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` // +kubebuilder:validation:MaxLength=316 + // +k8s:alpha(since: "1.37")=+k8s:required Type string `json:"type" protobuf:"bytes,1,opt,name=type"` // status of the condition, one of True, False, Unknown. // +required // +kubebuilder:validation:Required // +kubebuilder:validation:Enum=True;False;Unknown + // +k8s:alpha(since: "1.37")=+k8s:required Status ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status"` // observedGeneration represents the .metadata.generation that the condition was set based upon. // For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date // with respect to the current state of the instance. // +optional // +kubebuilder:validation:Minimum=0 + // +k8s:alpha(since: "1.37")=+k8s:optional + // +k8s:alpha(since: "1.37")=+k8s:minimum=0 ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"` // lastTransitionTime is the last time the condition transitioned from one status to another. // This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. @@ -1645,6 +1671,7 @@ type Condition struct { // +kubebuilder:validation:Required // +kubebuilder:validation:Type=string // +kubebuilder:validation:Format=date-time + // +k8s:alpha(since: "1.37")=+k8s:customValidation LastTransitionTime Time `json:"lastTransitionTime" protobuf:"bytes,4,opt,name=lastTransitionTime"` // reason contains a programmatic identifier indicating the reason for the condition's last transition. // Producers of specific condition types may define expected values and meanings for this field, @@ -1656,6 +1683,8 @@ type Condition struct { // +kubebuilder:validation:MaxLength=1024 // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:Pattern=`^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$` + // +k8s:alpha(since: "1.37")=+k8s:required + // +k8s:alpha(since: "1.37")=+k8s:maxBytes=1024 Reason string `json:"reason" protobuf:"bytes,5,opt,name=reason"` // message is a human readable message indicating details about the transition. // This may be an empty string. diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go index 59f43b7b..592445d9 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go @@ -523,6 +523,7 @@ func NewJSONFallbackEncoder(encoder runtime.Encoder) runtime.Encoder { } identifier, err := gojson.Marshal(result) if err != nil { + //nolint:logcheck // Should not be reached. klog.Fatalf("Failed marshaling identifier for jsonFallbackEncoder: %v", err) } return &jsonFallbackEncoder{ diff --git a/vendor/gopkg.in/yaml.v3/NOTICE b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/doc.go similarity index 68% rename from vendor/gopkg.in/yaml.v3/NOTICE rename to vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/doc.go index 866d74a7..3b9cb30f 100644 --- a/vendor/gopkg.in/yaml.v3/NOTICE +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/doc.go @@ -1,4 +1,5 @@ -Copyright 2011-2016 Canonical Ltd. +/* +Copyright The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -11,3 +12,10 @@ 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. +*/ + +// +k8s:validation-gen=TypesWithField=TypeMeta +// +k8s:validation-gen-input=k8s.io/apimachinery/pkg/apis/meta/v1 + +// Package validation holds generated validations for meta/v1 types. +package validation diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go index d0ca2001..b9ec3442 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go @@ -17,10 +17,12 @@ limitations under the License. package validation import ( + "context" "fmt" "regexp" "unicode" + "k8s.io/apimachinery/pkg/api/operation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" @@ -266,14 +268,39 @@ func ValidateTableOptions(opts *metav1.TableOptions) field.ErrorList { const MaxSubresourceNameLength = 256 -func ValidateManagedFields(fieldsList []metav1.ManagedFieldsEntry, fldPath *field.Path) field.ErrorList { +// ManagedFieldsValidationOption specifies options for validating managed fields. +type ManagedFieldsValidationOption int + +const ( + // CoveredByDeclarative indicates whether errors should be marked as covered by declarative validation. + CoveredByDeclarative ManagedFieldsValidationOption = iota + 1 +) + +// ValidateManagedFields validates a list of managed fields. +func ValidateManagedFields(fieldsList []metav1.ManagedFieldsEntry, fldPath *field.Path, opts ...ManagedFieldsValidationOption) field.ErrorList { + coveredByDeclarative := false + for _, opt := range opts { + if opt == CoveredByDeclarative { + coveredByDeclarative = true + } + } var allErrs field.ErrorList for i, fields := range fieldsList { fldPath := fldPath.Index(i) switch fields.Operation { + case "": + err := field.Required(fldPath.Child("operation"), "must not be empty") + if coveredByDeclarative { + err = err.MarkCoveredByDeclarative() + } + allErrs = append(allErrs, err) case metav1.ManagedFieldsOperationApply, metav1.ManagedFieldsOperationUpdate: default: - allErrs = append(allErrs, field.Invalid(fldPath.Child("operation"), fields.Operation, "must be `Apply` or `Update`")) + err := field.NotSupported(fldPath.Child("operation"), fields.Operation, []metav1.ManagedFieldsOperationType{metav1.ManagedFieldsOperationApply, metav1.ManagedFieldsOperationUpdate}) + if coveredByDeclarative { + err = err.MarkCoveredByDeclarative() + } + allErrs = append(allErrs, err) } if len(fields.FieldsType) > 0 && fields.FieldsType != "FieldsV1" { allErrs = append(allErrs, field.Invalid(fldPath.Child("fieldsType"), fields.FieldsType, "must be `FieldsV1`")) @@ -293,7 +320,7 @@ func ValidateConditions(conditions []metav1.Condition, fldPath *field.Path) fiel conditionTypeToFirstIndex := map[string]int{} for i, condition := range conditions { if _, ok := conditionTypeToFirstIndex[condition.Type]; ok { - allErrs = append(allErrs, field.Duplicate(fldPath.Index(i).Child("type"), condition.Type)) + allErrs = append(allErrs, field.Duplicate(fldPath.Index(i), condition.Type).MarkCoveredByDeclarative()) } else { conditionTypeToFirstIndex[condition.Type] = i } @@ -316,29 +343,35 @@ func ValidateCondition(condition metav1.Condition, fldPath *field.Path) field.Er var allErrs field.ErrorList // type is set and is a valid format - allErrs = append(allErrs, ValidateLabelName(condition.Type, fldPath.Child("type"))...) + if len(condition.Type) == 0 { + allErrs = append(allErrs, field.Required(fldPath.Child("type"), "is required").MarkCoveredByDeclarative()) + } else { + allErrs = append(allErrs, ValidateLabelName(condition.Type, fldPath.Child("type"))...) + } // status is set and is an accepted value - if !validConditionStatuses.Has(string(condition.Status)) { - allErrs = append(allErrs, field.NotSupported(fldPath.Child("status"), condition.Status, validConditionStatuses.List())) + if len(condition.Status) == 0 { + allErrs = append(allErrs, field.Required(fldPath.Child("status"), "").MarkCoveredByDeclarative()) + } else if !validConditionStatuses.Has(string(condition.Status)) { + allErrs = append(allErrs, field.NotSupported(fldPath.Child("status"), condition.Status, validConditionStatuses.List()).MarkCoveredByDeclarative()) } if condition.ObservedGeneration < 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("observedGeneration"), condition.ObservedGeneration, "must be greater than or equal to zero")) + allErrs = append(allErrs, field.Invalid(fldPath.Child("observedGeneration"), condition.ObservedGeneration, "must be greater than or equal to zero").WithOrigin("minimum").MarkCoveredByDeclarative()) } if condition.LastTransitionTime.IsZero() { - allErrs = append(allErrs, field.Required(fldPath.Child("lastTransitionTime"), "")) + allErrs = append(allErrs, field.Required(fldPath.Child("lastTransitionTime"), "").MarkCoveredByDeclarative()) } if len(condition.Reason) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("reason"), "")) + allErrs = append(allErrs, field.Required(fldPath.Child("reason"), "").MarkCoveredByDeclarative()) } else { - for _, currErr := range isValidConditionReason(condition.Reason) { + for _, currErr := range IsValidConditionReason(condition.Reason) { allErrs = append(allErrs, field.Invalid(fldPath.Child("reason"), condition.Reason, currErr)) } if len(condition.Reason) > maxReasonLen { - allErrs = append(allErrs, field.TooLong(fldPath.Child("reason"), "" /*unused*/, maxReasonLen)) + allErrs = append(allErrs, field.TooLong(fldPath.Child("reason"), "" /*unused*/, maxReasonLen).WithOrigin("maxBytes").MarkCoveredByDeclarative()) } } @@ -354,8 +387,9 @@ const conditionReasonErrMsg string = "a condition reason must start with alphabe var conditionReasonRegexp = regexp.MustCompile("^" + conditionReasonFmt + "$") -// isValidConditionReason tests for a string that conforms to rules for condition reasons. This checks the format, but not the length. -func isValidConditionReason(value string) []string { +// IsValidConditionReason tests for a string that conforms to rules for condition +// reasons. This checks the format, but not the length. +func IsValidConditionReason(value string) []string { if !conditionReasonRegexp.MatchString(value) { return []string{validation.RegexError(conditionReasonErrMsg, conditionReasonFmt, "my_name", "MY_NAME", "MyName", "ReasonA,ReasonB", "ReasonA:ReasonB")} } @@ -370,9 +404,6 @@ func ValidateIgnoreStoreReadError(fldPath *field.Path, options *metav1.DeleteOpt return allErrs } - if len(options.DryRun) > 0 { - allErrs = append(allErrs, field.Invalid(fldPath, true, "cannot be set together with .dryRun")) - } if options.PropagationPolicy != nil { allErrs = append(allErrs, field.Invalid(fldPath, true, "cannot be set together with .propagationPolicy")) } @@ -389,3 +420,14 @@ func ValidateIgnoreStoreReadError(fldPath *field.Path, options *metav1.DeleteOpt return allErrs } + +// ValidateCustom_Condition_LastTransitionTime is wired into the generated +// declarative validation by +k8s:customValidation on Condition.LastTransitionTime. +// It enforces that the field is set, mirroring the handwritten check in +// ValidateCondition. +func ValidateCustom_Condition_LastTransitionTime(ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *metav1.Time) field.ErrorList { + if value.IsZero() { + return field.ErrorList{field.Required(fldPath, "")} + } + return nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/zz_generated.validations.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/zz_generated.validations.go new file mode 100644 index 00000000..f79373a2 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/zz_generated.validations.go @@ -0,0 +1,638 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes 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. +*/ + +// Code generated by validation-gen. DO NOT EDIT. + +package validation + +import ( + context "context" + + equality "k8s.io/apimachinery/pkg/api/equality" + operation "k8s.io/apimachinery/pkg/api/operation" + safe "k8s.io/apimachinery/pkg/api/safe" + validate "k8s.io/apimachinery/pkg/api/validate" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + sets "k8s.io/apimachinery/pkg/util/sets" + field "k8s.io/apimachinery/pkg/util/validation/field" +) + +// Validate_Condition validates an instance of Condition according +// to declarative validation rules in the API schema. +func Validate_Condition( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.Condition) (errs field.ErrorList) { + + { // field v1.Condition.Type + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.Condition) *string { + return &oldObj.Type + }) + errs = append(errs, fn(fldPath.Child("type"), &obj.Type, oldVal, oldObj != nil)...) + } + + { // field v1.Condition.Status + fn := func( + fldPath *field.Path, + obj, oldObj *v1.ConditionStatus, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_ConditionStatus(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.Condition) *v1.ConditionStatus { + return &oldObj.Status + }) + errs = append(errs, fn(fldPath.Child("status"), &obj.Status, oldVal, oldObj != nil)...) + } + + { // field v1.Condition.ObservedGeneration + fn := func( + fldPath *field.Path, + obj, oldObj *int64, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.Minimum(ctx, op, fldPath, obj, oldObj, 0).MarkAlpha(); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.Condition) *int64 { + return &oldObj.ObservedGeneration + }) + errs = append(errs, fn(fldPath.Child("observedGeneration"), &obj.ObservedGeneration, oldVal, oldObj != nil)...) + } + + { // field v1.Condition.LastTransitionTime + fn := func( + fldPath *field.Path, + obj, oldObj *v1.Time, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + // custom validation + if e := ValidateCustom_Condition_LastTransitionTime(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.Condition) *v1.Time { + return &oldObj.LastTransitionTime + }) + errs = append(errs, fn(fldPath.Child("lastTransitionTime"), &obj.LastTransitionTime, oldVal, oldObj != nil)...) + } + + { // field v1.Condition.Reason + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.MaxBytes(ctx, op, fldPath, obj, oldObj, 1024).MarkAlpha(); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.Condition) *string { + return &oldObj.Reason + }) + errs = append(errs, fn(fldPath.Child("reason"), &obj.Reason, oldVal, oldObj != nil)...) + } + + // field v1.Condition.Message has no validation + return errs +} + +var symbolsForConditionStatus = sets.New(v1.ConditionFalse, v1.ConditionTrue, v1.ConditionUnknown) + +// Validate_ConditionStatus validates an instance of ConditionStatus according +// to declarative validation rules in the API schema. +func Validate_ConditionStatus( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.ConditionStatus) (errs field.ErrorList) { + + if e := validate.Enum(ctx, op, fldPath, obj, oldObj, symbolsForConditionStatus, nil).MarkAlpha(); len(e) != 0 { + errs = append(errs, e...) + } + + return errs +} + +// Validate_ManagedFieldsEntry validates an instance of ManagedFieldsEntry according +// to declarative validation rules in the API schema. +func Validate_ManagedFieldsEntry( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.ManagedFieldsEntry) (errs field.ErrorList) { + + // field v1.ManagedFieldsEntry.Manager has no validation + + { // field v1.ManagedFieldsEntry.Operation + fn := func( + fldPath *field.Path, + obj, oldObj *v1.ManagedFieldsOperationType, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_ManagedFieldsOperationType(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ManagedFieldsEntry) *v1.ManagedFieldsOperationType { + return &oldObj.Operation + }) + errs = append(errs, fn(fldPath.Child("operation"), &obj.Operation, oldVal, oldObj != nil)...) + } + + // field v1.ManagedFieldsEntry.APIVersion has no validation + // field v1.ManagedFieldsEntry.Time has no validation + // field v1.ManagedFieldsEntry.FieldsType has no validation + // field v1.ManagedFieldsEntry.FieldsV1 has no validation + // field v1.ManagedFieldsEntry.Subresource has no validation + return errs +} + +var symbolsForManagedFieldsOperationType = sets.New(v1.ManagedFieldsOperationApply, v1.ManagedFieldsOperationUpdate) + +// Validate_ManagedFieldsOperationType validates an instance of ManagedFieldsOperationType according +// to declarative validation rules in the API schema. +func Validate_ManagedFieldsOperationType( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.ManagedFieldsOperationType) (errs field.ErrorList) { + + if e := validate.Enum(ctx, op, fldPath, obj, oldObj, symbolsForManagedFieldsOperationType, nil).MarkAlpha(); len(e) != 0 { + errs = append(errs, e...) + } + + return errs +} + +// Validate_ObjectMeta validates an instance of ObjectMeta according +// to declarative validation rules in the API schema. +func Validate_ObjectMeta( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.ObjectMeta) (errs field.ErrorList) { + + // field v1.ObjectMeta.Name has no validation + // field v1.ObjectMeta.GenerateName has no validation + // field v1.ObjectMeta.Namespace has no validation + // field v1.ObjectMeta.SelfLink has no validation + + { // field v1.ObjectMeta.UID + fn := func( + fldPath *field.Path, + obj, oldObj *types.UID, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Immutable(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ObjectMeta) *types.UID { + return &oldObj.UID + }) + errs = append(errs, fn(fldPath.Child("uid"), &obj.UID, oldVal, oldObj != nil)...) + } + + // field v1.ObjectMeta.ResourceVersion has no validation + + { // field v1.ObjectMeta.Generation + fn := func( + fldPath *field.Path, + obj, oldObj *int64, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.Minimum(ctx, op, fldPath, obj, oldObj, 0).MarkAlpha(); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ObjectMeta) *int64 { + return &oldObj.Generation + }) + errs = append(errs, fn(fldPath.Child("generation"), &obj.Generation, oldVal, oldObj != nil)...) + } + + { // field v1.ObjectMeta.CreationTimestamp + fn := func( + fldPath *field.Path, + obj, oldObj *v1.Time, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.Immutable(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ObjectMeta) *v1.Time { + return &oldObj.CreationTimestamp + }) + errs = append(errs, fn(fldPath.Child("creationTimestamp"), &obj.CreationTimestamp, oldVal, oldObj != nil)...) + } + + { // field v1.ObjectMeta.DeletionTimestamp + fn := func( + fldPath *field.Path, + obj, oldObj *v1.Time, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Immutable(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ObjectMeta) *v1.Time { + return oldObj.DeletionTimestamp + }) + errs = append(errs, fn(fldPath.Child("deletionTimestamp"), obj.DeletionTimestamp, oldVal, oldObj != nil)...) + } + + { // field v1.ObjectMeta.DeletionGracePeriodSeconds + fn := func( + fldPath *field.Path, + obj, oldObj *int64, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Immutable(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ObjectMeta) *int64 { + return oldObj.DeletionGracePeriodSeconds + }) + errs = append(errs, fn(fldPath.Child("deletionGracePeriodSeconds"), obj.DeletionGracePeriodSeconds, oldVal, oldObj != nil)...) + } + + // field v1.ObjectMeta.Labels has no validation + // field v1.ObjectMeta.Annotations has no validation + + { // field v1.ObjectMeta.OwnerReferences + fn := func( + fldPath *field.Path, + obj, oldObj []v1.OwnerReference, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // iterate the list and call the type's validation function + if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_OwnerReference); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ObjectMeta) []v1.OwnerReference { + return oldObj.OwnerReferences + }) + errs = append(errs, fn(fldPath.Child("ownerReferences"), obj.OwnerReferences, oldVal, oldObj != nil)...) + } + + // field v1.ObjectMeta.Finalizers has no validation + + { // field v1.ObjectMeta.ManagedFields + fn := func( + fldPath *field.Path, + obj, oldObj []v1.ManagedFieldsEntry, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if equality.Semantic.DeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // iterate the list and call the type's validation function + if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_ManagedFieldsEntry); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ObjectMeta) []v1.ManagedFieldsEntry { + return oldObj.ManagedFields + }) + errs = append(errs, fn(fldPath.Child("managedFields"), obj.ManagedFields, oldVal, oldObj != nil)...) + } + + return errs +} + +// Validate_OwnerReference validates an instance of OwnerReference according +// to declarative validation rules in the API schema. +func Validate_OwnerReference( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.OwnerReference) (errs field.ErrorList) { + + { // field v1.OwnerReference.APIVersion + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.OwnerReference) *string { + return &oldObj.APIVersion + }) + errs = append(errs, fn(fldPath.Child("apiVersion"), &obj.APIVersion, oldVal, oldObj != nil)...) + } + + { // field v1.OwnerReference.Kind + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.OwnerReference) *string { + return &oldObj.Kind + }) + errs = append(errs, fn(fldPath.Child("kind"), &obj.Kind, oldVal, oldObj != nil)...) + } + + { // field v1.OwnerReference.Name + fn := func( + fldPath *field.Path, + obj, oldObj *string, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.OwnerReference) *string { + return &oldObj.Name + }) + errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) + } + + { // field v1.OwnerReference.UID + fn := func( + fldPath *field.Path, + obj, oldObj *types.UID, + oldValueCorrelated bool) (errs field.ErrorList) { + // don't revalidate unchanged data + if oldValueCorrelated && op.Type == operation.Update { + if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.OwnerReference) *types.UID { + return &oldObj.UID + }) + errs = append(errs, fn(fldPath.Child("uid"), &obj.UID, oldVal, oldObj != nil)...) + } + + // field v1.OwnerReference.Controller has no validation + // field v1.OwnerReference.BlockOwnerDeletion has no validation + return errs +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types.go index 68f261cc..1cda0840 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types.go @@ -62,7 +62,7 @@ type PartialObjectMetadata = v1.PartialObjectMetadata // PartialObjectMetadataList contains a list of objects containing only their metadata. // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type PartialObjectMetadataList struct { - v1.TypeMeta `json:",inline"` + v1.TypeMeta `json:""` // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds // +optional diff --git a/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go b/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go index b0a9246d..5eb25e2e 100644 --- a/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go +++ b/vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go @@ -34,8 +34,8 @@ type Unmarshaler interface { } func jsonTag(field reflect.StructField) (string, bool) { - structTag := field.Tag.Get("json") - if len(structTag) == 0 { + structTag, exists := field.Tag.Lookup("json") + if !exists || len(structTag) == 0 { return "", false } parts := strings.Split(structTag, ",") diff --git a/vendor/k8s.io/apimachinery/pkg/labels/selector.go b/vendor/k8s.io/apimachinery/pkg/labels/selector.go index 031dcd21..f31a890f 100644 --- a/vendor/k8s.io/apimachinery/pkg/labels/selector.go +++ b/vendor/k8s.io/apimachinery/pkg/labels/selector.go @@ -269,13 +269,15 @@ func (r *Requirement) Matches(ls Labels) bool { } lsValue, err := strconv.ParseInt(val, 10, 64) if err != nil { - klog.V(10).Infof("ParseInt failed for value %+v in label %+v, %+v", val, ls, err) + //nolint:logcheck // Extending the API is not worth it for contextual, structured logging of this. + klog.V(10).InfoS("ParseInt failed", "value", val, "label", ls, "err", err) return false } // There should be only one strValue in r.strValues, and can be converted to an integer. if len(r.strValues) != 1 { - klog.V(10).Infof("Invalid values count %+v of requirement %#v, for 'Gt', 'Lt' operators, exactly one value is required", len(r.strValues), r) + //nolint:logcheck // Extending the API is not worth it for contextual, structured logging of this. + klog.V(10).InfoS("Invalid values count: for 'Gt', 'Lt' operators, exactly one value is required", "count", len(r.strValues), "requirement", r) return false } @@ -283,7 +285,8 @@ func (r *Requirement) Matches(ls Labels) bool { for i := range r.strValues { rValue, err = strconv.ParseInt(r.strValues[i], 10, 64) if err != nil { - klog.V(10).Infof("ParseInt failed for value %+v in requirement %#v, for 'Gt', 'Lt' operators, the value must be an integer", r.strValues[i], r) + //nolint:logcheck // Extending the API is not worth it for contextual, structured logging of this. + klog.V(10).InfoS("ParseInt failed: for 'Gt', 'Lt' operators, the value must be an integer", "value", r.strValues[i], "requirement", r, "err", err) return false } } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/codec.go b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go index 73f85286..654835b3 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/codec.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/codec.go @@ -226,6 +226,7 @@ func identifier(e Encoder) Identifier { } identifier, err := json.Marshal(result) if err != nil { + //nolint:logcheck // Should not be reached. klog.Fatalf("Failed marshaling identifier for base64Serializer: %v", err) } return Identifier(identifier) @@ -390,6 +391,7 @@ func (v multiGroupVersioner) Identifier() string { } identifier, err := json.Marshal(result) if err != nil { + //nolint:logcheck // Should not be reached. klog.Fatalf("Failed marshaling Identifier for %#v: %v", v, err) } return string(identifier) diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/conversion.go b/vendor/k8s.io/apimachinery/pkg/runtime/conversion.go index d04d701f..7cef382d 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/conversion.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/conversion.go @@ -20,7 +20,6 @@ package runtime import ( "fmt" - "reflect" "strconv" "strings" @@ -41,18 +40,6 @@ func DefaultMetaV1FieldSelectorConversion(label, value string) (string, string, } } -// JSONKeyMapper uses the struct tags on a conversion to determine the key value for -// the other side. Use when mapping from a map[string]* to a struct or vice versa. -func JSONKeyMapper(key string, sourceTag, destTag reflect.StructTag) (string, string) { - if s := destTag.Get("json"); len(s) > 0 { - return strings.SplitN(s, ",", 2)[0], key - } - if s := sourceTag.Get("json"); len(s) > 0 { - return key, strings.SplitN(s, ",", 2)[0] - } - return key, key -} - func Convert_Slice_string_To_string(in *[]string, out *string, s conversion.Scope) error { if len(*in) == 0 { *out = "" diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go index b1a30095..5aa118f5 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go @@ -251,9 +251,11 @@ func (c *unstructuredConverter) FromUnstructuredWithValidation(u map[string]inte newObj := reflect.New(t.Elem()).Interface() newErr := fromUnstructuredViaJSON(u, newObj) if (err != nil) != (newErr != nil) { + //nolint:logcheck // Should not be reached. klog.Fatalf("FromUnstructured unexpected error for %v: error: %v", u, err) } if err == nil && !c.comparison.DeepEqual(obj, newObj) { + //nolint:logcheck // Should not be reached. klog.Fatalf("FromUnstructured mismatch\nobj1: %#v\nobj2: %#v", obj, newObj) } } @@ -376,8 +378,8 @@ func fieldInfoFromField(structType reflect.Type, field int) *fieldInfo { // Cache miss - we need to compute the field name. info := &fieldInfo{} typeField := structType.Field(field) - jsonTag := typeField.Tag.Get("json") - if len(jsonTag) == 0 { + jsonTag, exists := typeField.Tag.Lookup("json") + if !exists || len(jsonTag) == 0 { if !typeField.Anonymous { // match stdlib behavior for naming fields that don't specify a json tag name info.name = typeField.Name @@ -385,7 +387,10 @@ func fieldInfoFromField(structType reflect.Type, field int) *fieldInfo { } else { items := strings.Split(jsonTag, ",") info.name = items[0] - if len(info.name) == 0 && !typeField.Anonymous { + if isInlinedFromTag(typeField, items[0], items[1:]) { + // match stdlib behavior when controlled by tag + info.name = "" + } else if len(info.name) == 0 && !typeField.Anonymous { // match stdlib behavior for naming fields that don't specify a json tag name info.name = typeField.Name } @@ -596,9 +601,11 @@ func (c *unstructuredConverter) ToUnstructured(obj interface{}) (map[string]inte newUnstr := map[string]interface{}{} newErr := toUnstructuredViaJSON(obj, &newUnstr) if (err != nil) != (newErr != nil) { + //nolint:logcheck // Should not be reached. klog.Fatalf("ToUnstructured unexpected error for %v: error: %v; newErr: %v", obj, err, newErr) } if err == nil && !c.comparison.DeepEqual(u, newUnstr) { + //nolint:logcheck // Should not be reached. klog.Fatalf("ToUnstructured mismatch\nobj1: %#v\nobj2: %#v", u, newUnstr) } } @@ -680,11 +687,11 @@ func toUnstructured(sv, dv reflect.Value) error { dv.Set(reflect.ValueOf(sv.Int())) return nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - uVal := sv.Uint() - if uVal > math.MaxInt64 { - return fmt.Errorf("unsigned value %d does not fit into int64 (overflow)", uVal) + val, err := uintToUnstructuredHelper(sv.Uint()) + if err != nil { + return err } - dv.Set(reflect.ValueOf(int64(uVal))) + dv.Set(reflect.ValueOf(val)) return nil case reflect.Float32, reflect.Float64: dv.Set(reflect.ValueOf(sv.Float())) @@ -846,7 +853,11 @@ func structToUnstructured(sv, dv reflect.Value) error { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: realMap[fieldInfo.name] = fv.Int() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - realMap[fieldInfo.name] = fv.Uint() + val, err := uintToUnstructuredHelper(fv.Uint()) + if err != nil { + return err + } + realMap[fieldInfo.name] = val case reflect.Float32, reflect.Float64: realMap[fieldInfo.name] = fv.Float() default: @@ -867,3 +878,10 @@ func interfaceToUnstructured(sv, dv reflect.Value) error { } return toUnstructured(sv.Elem(), dv) } + +func uintToUnstructuredHelper(uVal uint64) (int64, error) { + if uVal > math.MaxInt64 { + return 0, fmt.Errorf("unsigned value %d does not fit into int64 (overflow)", uVal) + } + return int64(uVal), nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_126.go b/vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_126.go new file mode 100644 index 00000000..686ff6ab --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_126.go @@ -0,0 +1,26 @@ +//go:build !go1.27 + +/* +Copyright The Kubernetes 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 runtime + +import "reflect" + +func isInlinedFromTag(fieldType reflect.StructField, tagName string, tagDirectives []string) bool { + // go <1.27 doesn't honor ",inline" + return false +} diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_127.go b/vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_127.go new file mode 100644 index 00000000..abaa79a2 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/runtime/fieldinfo_127.go @@ -0,0 +1,33 @@ +//go:build go1.27 + +/* +Copyright The Kubernetes 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 runtime + +import ( + "reflect" +) + +func isInlinedFromTag(field reflect.StructField, tagName string, tagDirectives []string) bool { + fieldType := field.Type + if fieldType.Kind() == reflect.Pointer && fieldType.Name() == "" { + // optionally unwrap a single level + fieldType = fieldType.Elem() + } + // TODO: when switching to direct use of json/v2, error on non-struct embedding and use of embed with other directives + return fieldType.Kind() == reflect.Struct && tagName == "" && len(tagDirectives) == 1 && tagDirectives[0] == "embed" +} diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto b/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto index 5f06cc57..93d187d9 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto +++ b/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto @@ -33,7 +33,7 @@ option go_package = "k8s.io/apimachinery/pkg/runtime"; // // Internal package: // // type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` +// runtime.TypeMeta `json:""` // MyPlugin runtime.Object `json:"myPlugin"` // } // @@ -44,7 +44,7 @@ option go_package = "k8s.io/apimachinery/pkg/runtime"; // // External package: // // type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` +// runtime.TypeMeta `json:""` // MyPlugin runtime.RawExtension `json:"myPlugin"` // } // @@ -85,7 +85,7 @@ message RawExtension { // like this: // // type MyAwesomeAPIObject struct { -// runtime.TypeMeta `json:",inline"` +// runtime.TypeMeta `json:""` // ... // other fields // } // diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/helper.go b/vendor/k8s.io/apimachinery/pkg/runtime/helper.go index 395dfdbd..242a3498 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/helper.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/helper.go @@ -285,20 +285,26 @@ func (e *encoderWithAllocator) Identifier() Identifier { return e.encoder.Identifier() } +// The legacy discovery endpoint requires that its response Encoder implement Serializer. +// https://github.com/kubernetes/kubernetes/blob/4a1340bfd58fdb3846d4342c101e0bcb574fbfb1/staging/src/k8s.io/apiserver/pkg/endpoints/discovery/util.go#L101-L107 +var _ Serializer = nondeterministicEncoderToEncoderAdapter{} + type nondeterministicEncoderToEncoderAdapter struct { NondeterministicEncoder + + Decoder } func (e nondeterministicEncoderToEncoderAdapter) Encode(obj Object, w io.Writer) error { return e.EncodeNondeterministic(obj, w) } -// UseNondeterministicEncoding returns an Encoder that encodes objects using the provided Encoder's -// EncodeNondeterministic method if it implements NondeterministicEncoder, otherwise it returns the -// provided Encoder as-is. -func UseNondeterministicEncoding(encoder Encoder) Encoder { - if nondeterministic, ok := encoder.(NondeterministicEncoder); ok { - return nondeterministicEncoderToEncoderAdapter{nondeterministic} +// UseNondeterministicEncoding returns an Encoder that encodes objects using the provided +// Serializer's EncodeNondeterministic method if it implements NondeterministicEncoder, otherwise it +// returns the provided Serializer as-is. +func UseNondeterministicEncoding(serializer Serializer) Encoder { + if nondeterministic, ok := serializer.(NondeterministicEncoder); ok { + return nondeterministicEncoderToEncoderAdapter{NondeterministicEncoder: nondeterministic, Decoder: serializer} } - return encoder + return serializer } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go index e2fbeabd..80662e55 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go @@ -370,7 +370,7 @@ func (s *Scheme) AddValidationFunc(srcType Object, fn func(ctx context.Context, // Validate validates the provided Object according to the generated declarative validation code. // WARNING: This does not validate all objects! The handwritten validation code in validation.go // is not run when this is called. Only the generated zz_generated.validations.go validation code is run. -func (s *Scheme) Validate(ctx context.Context, options []string, object Object, subresources ...string) field.ErrorList { +func (s *Scheme) Validate(ctx context.Context, options map[string]bool, object Object, subresources ...string) field.ErrorList { if fn, ok := s.validationFuncs[reflect.TypeOf(object)]; ok { return fn(ctx, operation.Operation{Type: operation.Create, Request: operation.Request{Subresources: subresources}, Options: options}, object, nil) } @@ -380,13 +380,21 @@ func (s *Scheme) Validate(ctx context.Context, options []string, object Object, // ValidateUpdate validates the provided object and oldObject according to the generated declarative validation code. // WARNING: This does not validate all objects! The handwritten validation code in validation.go // is not run when this is called. Only the generated zz_generated.validations.go validation code is run. -func (s *Scheme) ValidateUpdate(ctx context.Context, options []string, object, oldObject Object, subresources ...string) field.ErrorList { +func (s *Scheme) ValidateUpdate(ctx context.Context, options map[string]bool, object, oldObject Object, subresources ...string) field.ErrorList { if fn, ok := s.validationFuncs[reflect.TypeOf(object)]; ok { return fn(ctx, operation.Operation{Type: operation.Update, Request: operation.Request{Subresources: subresources}, Options: options}, object, oldObject) } return nil } +// HasValidationFunc reports whether a validation function is registered for the +// object's type. Unlike Validate, it distinguishes "no function registered" from +// "function ran and found no errors", which both yield a nil error list. +func (s *Scheme) HasValidationFunc(obj Object) bool { + _, ok := s.validationFuncs[reflect.TypeOf(obj)] + return ok +} + // Convert will attempt to convert in into out. Both must be pointers. For easy // testing of conversion functions. Returns an error if the conversion isn't // possible. You can call this with types that haven't been registered (for example, diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/cbor.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/cbor.go index 118579ec..e5730e3c 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/cbor.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/cbor.go @@ -68,8 +68,9 @@ type Serializer interface { var _ Serializer = &serializer{} type options struct { - strict bool - transcode bool + strict bool + transcode bool + streamingCollectionsEncoding bool } type Option func(*options) @@ -92,6 +93,13 @@ func Transcode(s bool) Option { } } +// StreamingCollectionsEncoding is used for testing purposes only. +func StreamingCollectionsEncoding(s bool) Option { + return func(opts *options) { + opts.streamingCollectionsEncoding = s + } +} + type serializer struct { metaFactory metaFactory creater runtime.ObjectCreater @@ -114,6 +122,7 @@ func newSerializer(metaFactory metaFactory, creater runtime.ObjectCreater, typer typer: typer, } s.options.transcode = true + s.options.streamingCollectionsEncoding = true for _, o := range options { o(&s.options) } @@ -147,15 +156,25 @@ func (s *serializer) EncodeNondeterministic(obj runtime.Object, w io.Writer) err } func (s *serializer) encode(mode modes.EncMode, obj runtime.Object, w io.Writer) error { + if _, err := w.Write(selfDescribedCBOR); err != nil { + return err + } + + if s.options.streamingCollectionsEncoding { + ok, err := streamEncodeCollections(obj, w, mode) + if err != nil { + return err + } + if ok { + return nil + } + } + var v interface{} = obj if u, ok := obj.(runtime.Unstructured); ok { v = u.UnstructuredContent() } - if _, err := w.Write(selfDescribedCBOR); err != nil { - return err - } - return mode.MarshalTo(v, w) } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/collections.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/collections.go new file mode 100644 index 00000000..5aa0fb7c --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/collections.go @@ -0,0 +1,328 @@ +/* +Copyright The Kubernetes 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 cbor + +import ( + "encoding/json" + "fmt" + "io" + "maps" + "math/rand" + "reflect" + "slices" + "sort" + + "k8s.io/apimachinery/pkg/conversion" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes" + + "github.com/fxamacker/cbor/v2" +) + +func streamEncodeCollections(obj runtime.Object, w io.Writer, mode modes.EncMode) (bool, error) { + list, ok := obj.(*unstructured.UnstructuredList) + if ok { + return true, streamingEncodeUnstructuredList(w, list, mode) + } + if _, ok := obj.(cbor.Marshaler); ok { + return false, nil + } + if _, ok := obj.(json.Marshaler); ok { + return false, nil + } + typeMeta, listMeta, items, err := getListMeta(obj) + if err == nil { + return true, streamingEncodeList(w, typeMeta, listMeta, items, mode) + } + return false, nil +} + +// getListMeta implements list extraction logic for cbor stream serialization. +func getListMeta(list runtime.Object) (metav1.TypeMeta, metav1.ListMeta, []interface{}, error) { + listValue, err := conversion.EnforcePtr(list) + if err != nil { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, err + } + listType := listValue.Type() + if listType.NumField() != 3 { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf("expected ListType to have 3 fields") + } + // The streaming encoder reproduces the field names and layout implied by the + // json struct tags (kind, apiVersion, metadata, items). The CBOR encoder, + // however, gives a "cbor" struct tag precedence over "json", so a cbor tag on + // any of these fields could rename a key, change its options (e.g. keyasint), + // or un-inline the embedded TypeMeta -- diverging from the streamed output. + // Refuse to stream such a type and fall back to the general encoder, which + // honors the cbor tag correctly. + for i := 0; i < listType.NumField(); i++ { + if _, ok := listType.Field(i).Tag.Lookup("cbor"); ok { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf("expected list field %d to have no cbor tag", i) + } + } + // TypeMeta + typeMeta, ok := listValue.Field(0).Interface().(metav1.TypeMeta) + if !ok { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf("expected TypeMeta field to have TypeMeta type") + } + if !listType.Field(0).Anonymous { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected TypeMeta json field tag to be embedded`) + } + if jsonTag, jsonTagExists := listType.Field(0).Tag.Lookup("json"); !jsonTagExists { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected TypeMeta json field tag`) + } else if jsonTag != "" && jsonTag != ",inline" { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected TypeMeta json field tag to be "" or ",inline"`) + } + // ListMeta + listMeta, ok := listValue.Field(1).Interface().(metav1.ListMeta) + if !ok { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf("expected ListMeta field to have ListMeta type") + } + if listType.Field(1).Tag.Get("json") != "metadata,omitempty" { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected ListMeta json field tag to be "metadata,omitempty"`) + } + // Items + if listType.Field(2).Tag.Get("json") != "items" { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected Items json field tag to be "items"`) + } + items, err := getListItems(listValue.Field(2)) + if err != nil { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, err + } + return typeMeta, listMeta, items, nil +} + +// getListItems returns the elements of a list's Items field as addressable +// values. Marshaling each element directly (rather than routing through +// meta.ExtractList) preserves the element's own type and custom marshaler, so +// that e.g. a metav1.List whose Items are runtime.RawExtension holding CBOR +// bytes are encoded verbatim by runtime.RawExtension.MarshalCBOR instead of +// being flattened into a runtime.Unknown (which has no MarshalCBOR and would be +// misencoded as a struct or fail JSON transcoding). +// +// A nil Items slice returns a nil result, distinct from an empty non-nil slice, +// so the encoder can emit CBOR null rather than an empty array. +func getListItems(itemsValue reflect.Value) ([]interface{}, error) { + if itemsValue.Kind() != reflect.Slice { + return nil, fmt.Errorf("expected Items field to be a slice, got %s", itemsValue.Kind()) + } + if itemsValue.IsNil() { + return nil, nil + } + items := make([]interface{}, itemsValue.Len()) + for i := range items { + items[i] = itemsValue.Index(i).Addr().Interface() + } + return items, nil +} + +type cborMapEntry struct { + key string + write func() error +} + +func streamingEncodeList(w io.Writer, typeMeta metav1.TypeMeta, listMeta metav1.ListMeta, items []interface{}, mode modes.EncMode) error { + var entries []cborMapEntry + + if typeMeta.Kind != "" { + entries = append(entries, cborMapEntry{ + key: "kind", + write: func() error { + return encodeKeyValuePair(w, "kind", typeMeta.Kind, mode) + }, + }) + } + entries = append(entries, cborMapEntry{ + key: "items", + write: func() error { + if err := mode.MarshalTo("items", w); err != nil { + return err + } + if items == nil { + _, err := w.Write([]byte{0xf6}) // CBOR null + return err + } + if err := writeArrayHead(w, len(items)); err != nil { + return err + } + for _, item := range items { + if err := mode.MarshalTo(item, w); err != nil { + return err + } + } + return nil + }, + }) + entries = append(entries, cborMapEntry{ + key: "metadata", + write: func() error { + return encodeKeyValuePair(w, "metadata", listMeta, mode) + }, + }) + if typeMeta.APIVersion != "" { + entries = append(entries, cborMapEntry{ + key: "apiVersion", + write: func() error { + return encodeKeyValuePair(w, "apiVersion", typeMeta.APIVersion, mode) + }, + }) + } + + // entries is built in a fixed order (kind, items, metadata, apiVersion). + // Unlike streamingEncodeUnstructuredList, whose keys come in Go's randomized + // map-iteration order, there is no inherent randomness here, so for + // nondeterministic modes (SortFastShuffle) we rotate the encoding for-loop + // by a random initial offset. + start := 0 + if !mode.IsDeterministic() && len(entries) > 0 { + start = rand.Intn(len(entries)) + } + + if err := writeMapHead(w, len(entries)); err != nil { + return err + } + + for i := 0; i < len(entries); i++ { + entry := entries[(start+i)%len(entries)] + if err := entry.write(); err != nil { + return err + } + } + return nil +} + +func streamingEncodeUnstructuredList(w io.Writer, list *unstructured.UnstructuredList, mode modes.EncMode) error { + keys := slices.Collect(maps.Keys(list.Object)) + if _, exists := list.Object["items"]; !exists { + keys = append(keys, "items") + } + // keys starts in Go's randomized map-iteration order. For deterministic + // modes (SortBytewiseLexical) we sort it: shorter lengths come first, then + // lexicographic by content. For nondeterministic modes (SortFastShuffle) we + // leave the map-iteration order as-is, which already varies from call to + // call (analogous to what SortFastShuffle does for structs), so no explicit + // shuffling is needed. + if mode.IsDeterministic() { + sort.Slice(keys, func(i, j int) bool { + if len(keys[i]) != len(keys[j]) { + return len(keys[i]) < len(keys[j]) + } + return keys[i] < keys[j] + }) + } + + if err := writeMapHead(w, len(keys)); err != nil { + return err + } + + for _, key := range keys { + if err := mode.MarshalTo(key, w); err != nil { + return err + } + if key == "items" { + if err := writeArrayHead(w, len(list.Items)); err != nil { + return err + } + for _, item := range list.Items { + if err := mode.MarshalTo(item.Object, w); err != nil { + return err + } + } + } else { + if err := mode.MarshalTo(list.Object[key], w); err != nil { + return err + } + } + } + return nil +} + +func encodeKeyValuePair(w io.Writer, key string, value interface{}, mode modes.EncMode) error { + if err := mode.MarshalTo(key, w); err != nil { + return err + } + if err := mode.MarshalTo(value, w); err != nil { + return err + } + return nil +} + +// CBOR major type prefix bytes (the type in the high 3 bits, additional info +// zeroed), following RFC 8949 Section 3.1. +const ( + cborTypeArray byte = 0x80 // major type 4 + cborTypeMap byte = 0xa0 // major type 5 +) + +// writeMapHead writes a CBOR map header for a map with n entries. +func writeMapHead(w io.Writer, n int) error { + return writeCollectionHead(w, cborTypeMap, int64(n)) +} + +// writeArrayHead writes a CBOR array header for an array with n elements. +func writeArrayHead(w io.Writer, n int) error { + return writeCollectionHead(w, cborTypeArray, int64(n)) +} + +// writeCollectionHead writes a CBOR collection (array or map) header encoding +// the number of elements n, following RFC 8949 Section 3 additional info rules: +// +// - base: the prefix byte for the collection type. +// For maps: cborTypeMap (0xa0), for arrays: cborTypeArray (0x80). +// +// The extended form prefixes are derived from base using bitwise OR: +// - base|24: 1-byte length follows (additional info 24) +// - base|25: 2-byte length follows (additional info 25) +// - base|26: 4-byte length follows (additional info 26) +// - base|27: 8-byte length follows (additional info 27) +// +// Encoding table (map example, base=0xa0): +// +// n <= 23: 1 byte — 0xa0|n +// n <= 0xFF: 2 bytes — 0xb8 (0xa0|24), n +// n <= 0xFFFF: 3 bytes — 0xb9 (0xa0|25), n>>8, n +// n <= 0xFFFFFFFF: 5 bytes — 0xba (0xa0|26), n>>24..n +// n > 0xFFFFFFFF: 9 bytes — 0xbb (0xa0|27), n>>56..n +func writeCollectionHead(w io.Writer, base byte, n int64) error { + switch { + case n <= 23: + // Additional info 0–23: length is encoded directly in the low 5 bits. + _, err := w.Write([]byte{base + byte(n)}) + return err + case n <= 0xFF: + // Additional info 24: one additional byte carries the length. + _, err := w.Write([]byte{base | 24, byte(n)}) + return err + case n <= 0xFFFF: + // Additional info 25: two additional bytes carry the length (big-endian). + _, err := w.Write([]byte{base | 25, byte(n >> 8), byte(n)}) + return err + case n <= 0xFFFFFFFF: + // Additional info 26: four additional bytes carry the length (big-endian). + _, err := w.Write([]byte{base | 26, byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)}) + return err + default: + // Additional info 27: eight additional bytes carry the length (big-endian). + _, err := w.Write([]byte{ + base | 27, byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32), byte(n >> 24), byte(n >> 16), + byte(n >> 8), byte(n), + }) + return err + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go index 815dbe66..3287dfd3 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes/encode.go @@ -107,6 +107,7 @@ var encode = EncMode{ } return encode }(), + deterministic: true, } var Encode = EncMode{ @@ -122,6 +123,7 @@ var Encode = EncMode{ } return em }(), + deterministic: true, } var EncodeNondeterministic = EncMode{ @@ -134,16 +136,22 @@ var EncodeNondeterministic = EncMode{ } return em }(), + deterministic: false, } type EncMode struct { - delegate cbor.UserBufferEncMode + delegate cbor.UserBufferEncMode + deterministic bool } func (em EncMode) options() cbor.EncOptions { return em.delegate.EncOptions() } +func (em EncMode) IsDeterministic() bool { + return em.deterministic +} + func (em EncMode) MarshalTo(v interface{}, w io.Writer) error { if buf, ok := w.(*buffer); ok { return em.delegate.MarshalToBuffer(v, &buf.Buffer) diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/collections.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/collections.go index 075163dd..3fa6012d 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/collections.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/collections.go @@ -17,11 +17,10 @@ limitations under the License. package json import ( + "bytes" "encoding/json" "fmt" "io" - "maps" - "slices" "sort" "k8s.io/apimachinery/pkg/api/meta" @@ -35,14 +34,14 @@ import ( func streamEncodeCollections(obj runtime.Object, w io.Writer) (bool, error) { list, ok := obj.(*unstructured.UnstructuredList) if ok { - return true, streamingEncodeUnstructuredList(w, list) + return true, newStreamEncoder(w).encodeUnstructuredList(list) } if _, ok := obj.(json.Marshaler); ok { return false, nil } typeMeta, listMeta, items, err := getListMeta(obj) if err == nil { - return true, streamingEncodeList(w, typeMeta, listMeta, items) + return true, newStreamEncoder(w).encodeList(typeMeta, listMeta, items) } return false, nil } @@ -67,8 +66,13 @@ func getListMeta(list runtime.Object) (metav1.TypeMeta, metav1.ListMeta, []runti if !ok { return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf("expected TypeMeta field to have TypeMeta type") } - if listType.Field(0).Tag.Get("json") != ",inline" { - return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected TypeMeta json field tag to be ",inline"`) + if !listType.Field(0).Anonymous { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected TypeMeta json field tag to be embedded`) + } + if jsonTag, jsonTagExists := listType.Field(0).Tag.Lookup("json"); !jsonTagExists { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected TypeMeta json field tag`) + } else if jsonTag != "" && jsonTag != ",inline" { + return metav1.TypeMeta{}, metav1.ListMeta{}, nil, fmt.Errorf(`expected TypeMeta json field tag to be "" or ",inline"`) } // ListMeta listMeta, ok := listValue.Field(1).Interface().(metav1.ListMeta) @@ -89,45 +93,59 @@ func getListMeta(list runtime.Object) (metav1.TypeMeta, metav1.ListMeta, []runti return typeMeta, listMeta, items, nil } -func streamingEncodeList(w io.Writer, typeMeta metav1.TypeMeta, listMeta metav1.ListMeta, items []runtime.Object) error { +// streamEncoder encodes JSON values to w, reusing an internal buffer across +// values to avoid the fresh output allocation json.Marshal makes per call. +type streamEncoder struct { + w io.Writer + buf bytes.Buffer + json *json.Encoder +} + +func newStreamEncoder(w io.Writer) *streamEncoder { + e := &streamEncoder{w: w} + e.json = json.NewEncoder(&e.buf) + return e +} + +func (e *streamEncoder) encodeList(typeMeta metav1.TypeMeta, listMeta metav1.ListMeta, items []runtime.Object) error { // Start - if _, err := w.Write([]byte(`{`)); err != nil { + if _, err := e.w.Write([]byte(`{`)); err != nil { return err } // TypeMeta if typeMeta.Kind != "" { - if err := encodeKeyValuePair(w, "kind", typeMeta.Kind, []byte(",")); err != nil { + if err := e.encodeKeyValuePair("kind", typeMeta.Kind, []byte(",")); err != nil { return err } } if typeMeta.APIVersion != "" { - if err := encodeKeyValuePair(w, "apiVersion", typeMeta.APIVersion, []byte(",")); err != nil { + if err := e.encodeKeyValuePair("apiVersion", typeMeta.APIVersion, []byte(",")); err != nil { return err } } // ListMeta - if err := encodeKeyValuePair(w, "metadata", listMeta, []byte(",")); err != nil { + if err := e.encodeKeyValuePair("metadata", listMeta, []byte(",")); err != nil { return err } // Items - if err := encodeItemsObjectSlice(w, items); err != nil { + if err := e.encodeItemsObjectSlice(items); err != nil { return err } // End - _, err := w.Write([]byte("}\n")) + _, err := e.w.Write([]byte("}\n")) return err } -func encodeItemsObjectSlice(w io.Writer, items []runtime.Object) (err error) { +func (e *streamEncoder) encodeItemsObjectSlice(items []runtime.Object) (err error) { if items == nil { - err := encodeKeyValuePair(w, "items", nil, nil) + err := e.encodeKeyValuePair("items", nil, nil) return err } - _, err = w.Write([]byte(`"items":[`)) + _, err = e.w.Write([]byte(`"items":[`)) if err != nil { return err } @@ -136,24 +154,27 @@ func encodeItemsObjectSlice(w io.Writer, items []runtime.Object) (err error) { if i == len(items)-1 { suffix = nil } - err := encodeValue(w, item, suffix) + err := e.encodeValue(item, suffix) if err != nil { return err } } - _, err = w.Write([]byte("]")) + _, err = e.w.Write([]byte("]")) if err != nil { return err } return err } -func streamingEncodeUnstructuredList(w io.Writer, list *unstructured.UnstructuredList) error { - _, err := w.Write([]byte(`{`)) +func (e *streamEncoder) encodeUnstructuredList(list *unstructured.UnstructuredList) error { + _, err := e.w.Write([]byte(`{`)) if err != nil { return err } - keys := slices.Collect(maps.Keys(list.Object)) + keys := make([]string, 0, len(list.Object)+1) + for key := range list.Object { + keys = append(keys, key) + } if _, exists := list.Object["items"]; !exists { keys = append(keys, "items") } @@ -165,20 +186,20 @@ func streamingEncodeUnstructuredList(w io.Writer, list *unstructured.Unstructure suffix = nil } if key == "items" { - err = encodeItemsUnstructuredSlice(w, list.Items, suffix) + err = e.encodeItemsUnstructuredSlice(list.Items, suffix) } else { - err = encodeKeyValuePair(w, key, list.Object[key], suffix) + err = e.encodeKeyValuePair(key, list.Object[key], suffix) } if err != nil { return err } } - _, err = w.Write([]byte("}\n")) + _, err = e.w.Write([]byte("}\n")) return err } -func encodeItemsUnstructuredSlice(w io.Writer, items []unstructured.Unstructured, suffix []byte) (err error) { - _, err = w.Write([]byte(`"items":[`)) +func (e *streamEncoder) encodeItemsUnstructuredSlice(items []unstructured.Unstructured, suffix []byte) (err error) { + _, err = e.w.Write([]byte(`"items":[`)) if err != nil { return err } @@ -187,44 +208,42 @@ func encodeItemsUnstructuredSlice(w io.Writer, items []unstructured.Unstructured if i == len(items)-1 { comma = nil } - err := encodeValue(w, item.Object, comma) + err := e.encodeValue(item.Object, comma) if err != nil { return err } } - _, err = w.Write([]byte("]")) + _, err = e.w.Write([]byte("]")) if err != nil { return err } if len(suffix) > 0 { - _, err = w.Write(suffix) + _, err = e.w.Write(suffix) } return err } -func encodeKeyValuePair(w io.Writer, key string, value any, suffix []byte) (err error) { - err = encodeValue(w, key, []byte(":")) +func (e *streamEncoder) encodeKeyValuePair(key string, value any, suffix []byte) (err error) { + err = e.encodeValue(key, []byte(":")) if err != nil { return err } - err = encodeValue(w, value, suffix) + err = e.encodeValue(value, suffix) if err != nil { return err } return err } -func encodeValue(w io.Writer, value any, suffix []byte) error { - data, err := json.Marshal(value) - if err != nil { - return err - } - _, err = w.Write(data) - if err != nil { +func (e *streamEncoder) encodeValue(value any, suffix []byte) error { + e.buf.Reset() + if err := e.json.Encode(value); err != nil { return err } - if len(suffix) > 0 { - _, err = w.Write(suffix) - } + // Encode appends a newline after the value; replace it with the suffix to + // keep the output identical to json.Marshal's. + e.buf.Truncate(e.buf.Len() - 1) + e.buf.Write(suffix) + _, err := e.w.Write(e.buf.Bytes()) return err } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go index 24f66a10..52c81417 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go @@ -70,6 +70,7 @@ func identifier(options SerializerOptions) runtime.Identifier { } identifier, err := json.Marshal(result) if err != nil { + //nolint:logcheck // Should not be reached. klog.Fatalf("Failed marshaling identifier for json Serializer: %v", err) } return runtime.Identifier(identifier) diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/collections.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/collections.go index afac03e9..8db8932f 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/collections.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/collections.go @@ -17,6 +17,7 @@ limitations under the License. package protobuf import ( + "encoding/binary" "errors" "io" "math/bits" @@ -134,15 +135,17 @@ func streamingEncodeUnknownList(w io.Writer, unk runtime.Unknown, listData strea } func streamingEncodeList(w io.Writer, listData streamingListData, memAlloc runtime.MemoryAllocator) (size int, err error) { + // headerScratch escapes via w.Write, so allocate it once per call instead of once per item. + headerScratch := make([]byte, 1+binary.MaxVarintLen64) // ListMeta; 0xa = (1 << 3) | 2; field number: 1, type: 2 (LEN). https://protobuf.dev/programming-guides/encoding/#structure - n, err := doEncodeWithHeader(&listData.listMeta, w, 0xa, listData.listMetaSize, memAlloc) + n, err := doEncodeWithHeader(&listData.listMeta, w, 0xa, listData.listMetaSize, headerScratch, memAlloc) size += n if err != nil { return size, err } // Items; 0x12 = (2 << 3) | 2; field number: 2, type: 2 (LEN). https://protobuf.dev/programming-guides/encoding/#structure for i, item := range listData.items { - n, err := doEncodeWithHeader(item, w, 0x12, listData.itemsSizes[i], memAlloc) + n, err := doEncodeWithHeader(item, w, 0x12, listData.itemsSizes[i], headerScratch, memAlloc) size += n if err != nil { return size, err @@ -151,12 +154,6 @@ func streamingEncodeList(w io.Writer, listData streamingListData, memAlloc runti return size, nil } -func writeVarintGenerated(w io.Writer, v int) (int, error) { - buf := make([]byte, sovGenerated(uint64(v))) - encodeVarintGenerated(buf, len(buf), uint64(v)) - return w.Write(buf) -} - // sovGenerated is copied from `generated.pb.go` returns size of varint. func sovGenerated(v uint64) int { return (bits.Len64(v|1) + 6) / 7 diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go index 67a2d124..93ad95ce 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go @@ -199,6 +199,7 @@ func (s *Serializer) encode(obj runtime.Object, w io.Writer, memAlloc runtime.Me func (s *Serializer) doEncode(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error { if memAlloc == nil { + //nolint:logcheck // Should not be reached in normal operations. klog.Error("a mandatory memory allocator wasn't provided, this might have a negative impact on performance, check invocations of EncodeWithAllocator method, falling back on runtime.SimpleAllocator") memAlloc = &runtime.SimpleAllocator{} } @@ -470,15 +471,12 @@ func (s *RawSerializer) doEncode(obj runtime.Object, w io.Writer, memAlloc runti return err } -func doEncodeWithHeader(obj any, w io.Writer, field byte, precomputedSize int, memAlloc runtime.MemoryAllocator) (size int, err error) { - // Field identifier - n, err := w.Write([]byte{field}) - size += n - if err != nil { - return size, err - } - // Size - n, err = writeVarintGenerated(w, precomputedSize) +func doEncodeWithHeader(obj any, w io.Writer, field byte, precomputedSize int, headerScratch []byte, memAlloc runtime.MemoryAllocator) (size int, err error) { + // Field identifier and size + header := headerScratch[:1+sovGenerated(uint64(precomputedSize))] + header[0] = field + encodeVarintGenerated(header, len(header), uint64(precomputedSize)) + n, err := w.Write(header) size += n if err != nil { return size, err @@ -500,6 +498,7 @@ func doEncodeWithHeader(obj any, w io.Writer, field byte, precomputedSize int, m // precomputedObjSize should not include header bytes (field identifier, size). func doEncode(obj any, w io.Writer, precomputedObjSize *int, memAlloc runtime.MemoryAllocator) (int, error) { if memAlloc == nil { + //nolint:logcheck // Should not be reached in normal operations. klog.Error("a mandatory memory allocator wasn't provided, this might have a negative impact on performance, check invocations of EncodeWithAllocator method, falling back on runtime.SimpleAllocator") memAlloc = &runtime.SimpleAllocator{} } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go index 25f955ed..6c86d5e1 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go @@ -116,6 +116,7 @@ func identifier(encodeGV runtime.GroupVersioner, encoder runtime.Encoder) runtim } identifier, err := json.Marshal(result) if err != nil { + //nolint:logcheck // Should not be reached. klog.Fatalf("Failed marshaling identifier for codec: %v", err) } identifiersMap.Store(result, runtime.Identifier(identifier)) @@ -222,6 +223,7 @@ func (c *codec) doEncode(obj runtime.Object, w io.Writer, memAlloc runtime.Memor return encoder.EncodeWithAllocator(obj, w, memAlloc) } } else { + //nolint:logcheck // Extending the API is not worth it for contextual, structured logging of this. klog.V(6).Infof("a memory allocator was provided but the encoder %s doesn't implement the runtime.EncoderWithAllocator, using regular encoder.Encode method", c.encoder.Identifier()) } } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator.go b/vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator.go index 5bc642bc..0d5a3e70 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator.go @@ -25,7 +25,10 @@ import ( "go/token" "io" "reflect" + "strconv" "strings" + + "k8s.io/apimachinery/pkg/util/errors" ) // Pair of strings. We keed the name of fields and the doc @@ -94,23 +97,29 @@ func fmtRawDoc(rawDoc string) string { // fieldName returns the name of the field as it should appear in JSON format // "-" indicates that this field is not part of the JSON representation -func fieldName(field *ast.Field) string { +func fieldName(field *ast.Field) (string, error) { jsonTag := "" if field.Tag != nil { - jsonTag = reflect.StructTag(field.Tag.Value[1 : len(field.Tag.Value)-1]).Get("json") // Delete first and last quotation - if strings.Contains(jsonTag, "inline") { - return "-" + var jsonTagExists bool + tagValue, err := strconv.Unquote(field.Tag.Value) + if err != nil { + return "", err + } + jsonTag, jsonTagExists = reflect.StructTag(tagValue).Lookup("json") // Delete first and last quotation + // field is embedded, json tag is declared and has an empty name + if field.Names == nil && jsonTagExists && (jsonTag == "" || strings.HasPrefix(jsonTag, ",")) { + return "-", nil } } jsonTag = strings.Split(jsonTag, ",")[0] // This can return "-" if jsonTag == "" { if field.Names != nil { - return field.Names[0].Name + return field.Names[0].Name, nil } - return field.Type.(*ast.Ident).Name + return field.Type.(*ast.Ident).Name, nil } - return jsonTag + return jsonTag, nil } // A buffer of lines that will be written. @@ -171,8 +180,9 @@ func writeMapBody(b *buffer, kubeType []Pair, indent int) { // array. Each type is again represented as an array (we have to use arrays as we // need to be sure for the order of the fields). This function returns fields and // struct definitions that have no documentation as {name, ""}. -func ParseDocumentationFrom(src string) []KubeTypes { +func ParseDocumentationFrom(src string) ([]KubeTypes, error) { var docForTypes []KubeTypes + var errs []error pkg := astFrom(src) @@ -182,7 +192,9 @@ func ParseDocumentationFrom(src string) []KubeTypes { ks = append(ks, Pair{kubType.Name, fmtRawDoc(kubType.Doc)}) for _, field := range structType.Fields.List { - if n := fieldName(field); n != "-" { + if n, err := fieldName(field); err != nil { + errs = append(errs, err) + } else if n != "-" { fieldDoc := fmtRawDoc(field.Doc.Text()) ks = append(ks, Pair{n, fieldDoc}) } @@ -191,7 +203,7 @@ func ParseDocumentationFrom(src string) []KubeTypes { } } - return docForTypes + return docForTypes, errors.NewAggregate(errs) } // WriteSwaggerDocFunc writes a declaration of a function as a string. This function is used in diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/types.go b/vendor/k8s.io/apimachinery/pkg/runtime/types.go index ca7b7cc2..6cded889 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/types.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/types.go @@ -23,7 +23,7 @@ package runtime // like this: // // type MyAwesomeAPIObject struct { -// runtime.TypeMeta `json:",inline"` +// runtime.TypeMeta `json:""` // ... // other fields // } // @@ -59,7 +59,7 @@ const ( // // Internal package: // // type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` +// runtime.TypeMeta `json:""` // MyPlugin runtime.Object `json:"myPlugin"` // } // @@ -70,7 +70,7 @@ const ( // // External package: // // type MyAPIObject struct { -// runtime.TypeMeta `json:",inline"` +// runtime.TypeMeta `json:""` // MyPlugin runtime.RawExtension `json:"myPlugin"` // } // @@ -121,7 +121,7 @@ type RawExtension struct { // +protobuf=true // +k8s:openapi-gen=true type Unknown struct { - TypeMeta `json:",inline" protobuf:"bytes,1,opt,name=typeMeta"` + TypeMeta `json:"" protobuf:"bytes,1,opt,name=typeMeta"` // Raw will hold the complete serialized object which couldn't be matched // with a registered type. Most likely, nothing should be done with this // except for passing it through the system. diff --git a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go index f372ae58..b0ca3803 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go +++ b/vendor/k8s.io/apimachinery/pkg/util/intstr/intstr.go @@ -59,6 +59,7 @@ const ( // Deprecated: use FromInt32 instead. func FromInt(val int) IntOrString { if val > math.MaxInt32 || val < math.MinInt32 { + //nolint:logcheck // Should not be reached. klog.Errorf("value: %d overflows int32\n%s\n", val, debug.Stack()) } return IntOrString{Type: Int, IntVal: int32(val)} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go index ac8d4279..2e2db655 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go @@ -140,24 +140,28 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (o } // UpdateNoErrors is the same as Update, but it will not return -// errors. If an error happens, the object is returned with -// managedFields cleared. +// errors. If an error happens, we preserve the managedFields from +// liveObj. func (f *FieldManager) UpdateNoErrors(liveObj, newObj runtime.Object, manager string) runtime.Object { obj, err := f.Update(liveObj, newObj, manager) if err != nil { - atMostEverySecond.Do(func() { - ns, name := "unknown", "unknown" - if accessor, err := meta.Accessor(newObj); err == nil { - ns = accessor.GetNamespace() - name = accessor.GetName() + // Preserve the managedFields from the live object rather than + // stripping them entirely, to avoid silent data loss when the + // managedFields update fails (e.g. due to an unavailable + // conversion webhook). + // Note: meta.Accessor for liveObj and newObj below never return an error in this code branch, + // because if they would f.Update above would return "newObj, nil". Accordingly, the case + // where one of the accessors returns an error is not handled here. + if liveAccessor, aErr := meta.Accessor(liveObj); aErr == nil { + if newAccessor, aErr := meta.Accessor(newObj); aErr == nil { + atMostEverySecond.Do(func() { + //nolint:logcheck // Should not be reached. + klog.ErrorS(err, "[SHOULD NOT HAPPEN] failed to update managedFields (restored previous managedFields from live object)", "versionKind", + newObj.GetObjectKind().GroupVersionKind(), "namespace", newAccessor.GetNamespace(), "name", newAccessor.GetName()) + }) + newAccessor.SetManagedFields(liveAccessor.GetManagedFields()) } - - klog.ErrorS(err, "[SHOULD NOT HAPPEN] failed to update managedFields", "versionKind", - newObj.GetObjectKind().GroupVersionKind(), "namespace", ns, "name", name) - }) - // Explicitly remove managedFields on failure, so that - // we can't have garbage in it. - RemoveObjectManagedFields(newObj) + } return newObj } return obj diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go index cbefc2eb..40cc90da 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go @@ -109,6 +109,24 @@ func valueToObject(val value.Value) (runtime.Object, error) { } } +// GroupVersionOfTypedValue returns the extracted GroupVersion from the TypeMeta +// fields of a TypedValue, or return false if no TypeMeta fields are found. +func GroupVersionOfTypedValue(object *typed.TypedValue) (schema.GroupVersion, bool) { + val := object.AsValue() + if val == nil || !val.IsMap() { + return schema.GroupVersion{}, false + } + apiVersion, ok := val.AsMap().Get("apiVersion") + if !ok || !apiVersion.IsString() { + return schema.GroupVersion{}, false + } + groupVersion, err := schema.ParseGroupVersion(apiVersion.AsString()) + if err != nil { + return schema.GroupVersion{}, false + } + return groupVersion, true +} + func indexModels( typeParser *typed.Parser, openAPISchemas map[string]*spec.Schema, diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go index 86695e0c..917bdcd7 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go @@ -63,24 +63,23 @@ func newCRDVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema // Convert implements sigs.k8s.io/structured-merge-diff/merge.Converter func (v *versionConverter) Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) { - // Convert the smd typed value to a kubernetes object. - objectToConvert, err := v.typeConverter.TypedToObject(object) - if err != nil { - return object, err - } - - // Parse the target groupVersion. groupVersion, err := schema.ParseGroupVersion(string(version)) if err != nil { return object, err } // If attempting to convert to the same version as we already have, just return it. - fromVersion := objectToConvert.GetObjectKind().GroupVersionKind().GroupVersion() - if fromVersion == groupVersion { + if typedVersion, ok := GroupVersionOfTypedValue(object); ok && typedVersion == groupVersion { return object, nil } + // Convert the smd typed value to a kubernetes object. + objectToConvert, err := v.typeConverter.TypedToObject(object) + if err != nil { + return object, err + } + fromVersion := objectToConvert.GetObjectKind().GroupVersionKind().GroupVersion() + // Convert to internal internalObject, err := v.objectConvertor.ConvertToVersion(objectToConvert, v.hubGetter(fromVersion)) if err != nil { diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go b/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go index 1eeb71ff..1a18b276 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go @@ -46,35 +46,57 @@ type ErrorMatcher struct { requireOriginWhenInvalid bool matchValidationStabilityLevel bool matchSource bool + matchAncestorShortCircuit bool + matchShortCircuit bool // normalizationRules holds the pre-compiled regex patterns for path normalization. normalizationRules []NormalizationRule } +// isChildPath returns true if child is a descendant path of parent. +// It avoids false positives like "spec.containers" being a child of "spec.container" +// by explicitly checking for '.' or '[' path separators. +func isChildPath(parent, child string) bool { + // "" as parent path not supported. It can un-intentionally match with any path. + // theoretically system errors can be matched with any path errors. + if len(parent) == 0 { + return false + } + if len(child) <= len(parent) { + return false + } + if child[:len(parent)] != parent { + return false + } + sep := child[len(parent)] + return sep == '.' || sep == '[' +} + // Matches returns true if the two Error objects match according to the // configured criteria. When field normalization is configured, only the // "got" error's field path is normalized (to bring older API versions up // to the internal/latest format), while "want" is assumed to already be // in the canonical internal API format. func (m ErrorMatcher) Matches(want, got *Error) bool { - if m.matchType && want.Type != got.Type { - return false + gotField := got.Field + if want.Field != gotField { + gotField = m.normalizePath(gotField) } - if m.matchField { - // Try direct match first (common case) - if want.Field != got.Field { - // Fields don't match, try normalization if rules are configured. - // Only normalize "got" - it may be from an older API version that - // needs to be brought up to the internal/latest format that "want" - // is already in. - if want.Field != m.normalizePath(got.Field) { - return false - } + if m.matchAncestorShortCircuit { + if got.ShortCircuit && (isChildPath(gotField, want.Field) || isChildPath(got.Field, want.Field)) { + return true } } + if m.matchType && want.Type != got.Type { + return false + } + if m.matchField && want.Field != gotField { + return false + } if m.matchValue && !reflect.DeepEqual(want.BadValue, got.BadValue) { return false } + if m.matchOrigin { if want.Origin != got.Origin { return false @@ -91,10 +113,12 @@ func (m ErrorMatcher) Matches(want, got *Error) bool { if m.matchValidationStabilityLevel && want.ValidationStabilityLevel != got.ValidationStabilityLevel { return false } - if m.matchSource && want.FromImperative != got.FromImperative { return false } + if m.matchShortCircuit && want.ShortCircuit != got.ShortCircuit { + return false + } return true } @@ -124,47 +148,51 @@ func (m ErrorMatcher) Render(e *Error) string { if m.matchType { comma() - buf.WriteString(fmt.Sprintf("Type=%q", e.Type)) + fmt.Fprintf(&buf, "Type=%q", e.Type) } if m.matchField { comma() if normalized := m.normalizePath(e.Field); normalized != e.Field { - buf.WriteString(fmt.Sprintf("Field=%q (aka %q)", normalized, e.Field)) + fmt.Fprintf(&buf, "Field=%q (aka %q)", normalized, e.Field) } else { - buf.WriteString(fmt.Sprintf("Field=%q", e.Field)) + fmt.Fprintf(&buf, "Field=%q", e.Field) } } if m.matchValue { comma() if s, ok := e.BadValue.(string); ok { - buf.WriteString(fmt.Sprintf("Value=%q", s)) + fmt.Fprintf(&buf, "Value=%q", s) } else { rv := reflect.ValueOf(e.BadValue) if rv.Kind() == reflect.Pointer && !rv.IsNil() { rv = rv.Elem() } if rv.IsValid() && rv.CanInterface() { - buf.WriteString(fmt.Sprintf("Value=%v", rv.Interface())) + fmt.Fprintf(&buf, "Value=%v", rv.Interface()) } else { - buf.WriteString(fmt.Sprintf("Value=%v", e.BadValue)) + fmt.Fprintf(&buf, "Value=%v", e.BadValue) } } } if m.matchOrigin || m.requireOriginWhenInvalid && e.Type == ErrorTypeInvalid { comma() - buf.WriteString(fmt.Sprintf("Origin=%q", e.Origin)) + fmt.Fprintf(&buf, "Origin=%q", e.Origin) } if m.matchDetail != nil { comma() - buf.WriteString(fmt.Sprintf("Detail=%q", e.Detail)) + fmt.Fprintf(&buf, "Detail=%q", e.Detail) } if m.matchValidationStabilityLevel { comma() - buf.WriteString(fmt.Sprintf("ValidationStabilityLevel=%s", e.ValidationStabilityLevel)) + fmt.Fprintf(&buf, "ValidationStabilityLevel=%s", e.ValidationStabilityLevel) } if m.matchSource { comma() - buf.WriteString(fmt.Sprintf("FromImperative=%t", e.FromImperative)) + fmt.Fprintf(&buf, "FromImperative=%t", e.FromImperative) + } + if m.matchShortCircuit { + comma() + fmt.Fprintf(&buf, "ShortCircuit=%t", e.ShortCircuit) } return "{" + buf.String() + "}" } @@ -249,6 +277,18 @@ func (m ErrorMatcher) BySource() ErrorMatcher { return m } +// MatchAncestorShortCircuit returns a derived ErrorMatcher which also matches when the "got" error short-circuited at an ancestor of the "want" error's field path. +func (m ErrorMatcher) MatchAncestorShortCircuit() ErrorMatcher { + m.matchAncestorShortCircuit = true + return m +} + +// MatchShortCircuit returns a derived ErrorMatcher which also matches by the ShortCircuit value. +func (m ErrorMatcher) MatchShortCircuit() ErrorMatcher { + m.matchShortCircuit = true + return m +} + // ByValidationStabilityLevel returns a derived ErrorMatcher which also matches by the validation stability level // value of field errors. func (m ErrorMatcher) ByValidationStabilityLevel() ErrorMatcher { @@ -300,9 +340,13 @@ type TestIntf interface { // "want" error can match multiple "got" errors, and they will all be consumed. // The only exception to this is if the matcher got multiple identical (in every way, // even those not being matched on) errors, which is likely to indicate a bug. +// This doesn't support matchAncestorShortCircuit as it it not needed to be used in the tests. func (m ErrorMatcher) Test(tb TestIntf, want, got ErrorList) { tb.Helper() + if m.matchAncestorShortCircuit { + tb.Errorf("matchAncestorShortCircuit is not supported for test") + } exactly := m.Exactly() // makes a copy // If we ever find an EXACT duplicate error, it's almost certainly a bug diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go index 9357fb30..0d00acb4 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/field/errors.go @@ -59,6 +59,12 @@ type Error struct { // FromImperative denotes these errors are originating from the hand written validations. FromImperative bool + // ShortCircuit denotes that this error prevents further validation of the current field's children. + ShortCircuit bool + + // ShortCircuitedInDeclarative denotes this error is covered by declarative validation. But not returned by declarative validation due to a short circuiting behavior for the current input. + ShortCircuitedInDeclarative bool + // ValidationStabilityLevel denotes the validation stability level of the declarative validation from this error is returned. This should be used in the declarative validations only. ValidationStabilityLevel ValidationStabilityLevel } @@ -545,6 +551,12 @@ func (e *Error) MarkAlpha() *Error { return e } +// MarkShortCircuitedInDV marks that this error is not returned by declarative validations, because DV returns before running the current validation. Handwritten validations still return it. +func (e *Error) MarkShortCircuitedInDV() *Error { + e.ShortCircuitedInDeclarative = true + return e +} + // MarkAlpha marks the errors as alpha validation errors. func (list ErrorList) MarkAlpha() ErrorList { for _, err := range list { @@ -579,6 +591,14 @@ func (list ErrorList) MarkFromImperative() ErrorList { return list } +// MarkShortCircuit marks the errors as short-circuit errors. +func (list ErrorList) MarkShortCircuit() ErrorList { + for _, err := range list { + err.ShortCircuit = true + } + return list +} + // RemoveCoveredByDeclarative returns a new ErrorList containing only the errors that should not be covered by declarative validation. func (list ErrorList) RemoveCoveredByDeclarative() ErrorList { newList := ErrorList{} diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go b/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go index 869fb0aa..95f4e621 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go @@ -105,6 +105,7 @@ func IsValidIP(fldPath *field.Path, value string) field.ErrorList { func GetWarningsForIP(fldPath *field.Path, value string) []string { ip := netutils.ParseIPSloppy(value) if ip == nil { + //nolint:logcheck // Should not be reached. klog.ErrorS(nil, "GetWarningsForIP called on value that was not validated with IsValidIPForLegacyField", "field", fldPath, "value", value) return nil } @@ -211,6 +212,7 @@ func IsValidCIDR(fldPath *field.Path, value string) field.ErrorList { func GetWarningsForCIDR(fldPath *field.Path, value string) []string { ip, ipnet, err := netutils.ParseCIDRSloppy(value) if err != nil { + //nolint:logcheck // Should not be reached. klog.ErrorS(err, "GetWarningsForCIDR called on value that was not validated with IsValidCIDRForLegacyField", "field", fldPath, "value", value) return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go b/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go index 5d58754a..195620b3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go +++ b/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go @@ -100,7 +100,7 @@ func isOptional(m *types.Member) (bool, error) { // If neither +optional nor +required is present in the comments, // infer optional from the json tags. - return strings.Contains(reflect.StructTag(m.Tags).Get("json"), "omitempty"), nil + return hasOmitemptyTag(m), nil } func apiTypeFilterFunc(c *generator.Context, t *types.Type) bool { @@ -222,9 +222,14 @@ func getReferableName(m *types.Member) string { } } +func hasOmitemptyTag(m *types.Member) bool { + jsonTag, _ := reflect.StructTag(m.Tags).Lookup("json") + return strings.HasSuffix(jsonTag, ",omitempty") || strings.Contains(jsonTag, ",omitempty,") +} + func shouldInlineMembers(m *types.Member) bool { - jsonTags := getJsonTags(m) - return len(jsonTags) > 1 && jsonTags[1] == "inline" + jsonTag, jsonTagExists := reflect.StructTag(m.Tags).Lookup("json") + return m.Embedded && jsonTagExists && (jsonTag == "" || strings.HasPrefix(jsonTag, ",")) } type openAPITypeWriter struct { @@ -1032,7 +1037,7 @@ func (g openAPITypeWriter) generateProperty(m *types.Member, parent *types.Type) g.Do("},\n},\n", nil) return nil } - omitEmpty := strings.Contains(reflect.StructTag(m.Tags).Get("json"), "omitempty") + omitEmpty := hasOmitemptyTag(m) if err := g.generateDefault(m.CommentLines, m.Type, omitEmpty, parent); err != nil { return fmt.Errorf("failed to generate default in %v: %v: %v", parent, m.Name, err) } @@ -1124,9 +1129,6 @@ func (g openAPITypeWriter) generateMapProperty(t *types.Type) error { g.Do("Type: []string{\"object\"},\n", nil) g.Do("AdditionalProperties: &spec.SchemaOrBool{\nAllows: true,\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil) - if err := g.generateDefault(t.Elem.CommentLines, t.Elem, false, t.Elem); err != nil { - return err - } typeString, format := openapi.OpenAPITypeFormat(elemType.String()) if typeString != "" { g.generateSimpleProperty(typeString, format) @@ -1161,9 +1163,6 @@ func (g openAPITypeWriter) generateSliceProperty(t *types.Type) error { elemType := resolveAliasAndPtrType(t.Elem) g.Do("Type: []string{\"array\"},\n", nil) g.Do("Items: &spec.SchemaOrArray{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil) - if err := g.generateDefault(t.Elem.CommentLines, t.Elem, false, t.Elem); err != nil { - return err - } typeString, format := openapi.OpenAPITypeFormat(elemType.String()) if typeString != "" { g.generateSimpleProperty(typeString, format) diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/rules/list_type_streaming_tags.go b/vendor/k8s.io/kube-openapi/pkg/generators/rules/list_type_streaming_tags.go index 4f34d42e..ad009901 100644 --- a/vendor/k8s.io/kube-openapi/pkg/generators/rules/list_type_streaming_tags.go +++ b/vendor/k8s.io/kube-openapi/pkg/generators/rules/list_type_streaming_tags.go @@ -62,7 +62,14 @@ func (l *StreamingListTypeJSONTags) Validate(t *types.Type) ([]string, error) { for _, m := range t.Members { switch m.Name { case "TypeMeta": - if reflect.StructTag(m.Tags).Get("json") != ",inline" { + if !m.Embedded { + // field must be embedded to inline + fields = append(fields, "TypeMeta") + } else if jsonTag, jsonTagExists := reflect.StructTag(m.Tags).Lookup("json"); !jsonTagExists { + // field should declare a json tag to indicate it is serialized + fields = append(fields, "TypeMeta") + } else if jsonTag != "" && jsonTag != ",inline" { + // expect a completely empty json tag (preferred) or an empty name segment and only an ,inline directive (previously used) fields = append(fields, "TypeMeta") } case "ListMeta": diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go index 7393bacf..5d8ee9aa 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go @@ -24,7 +24,7 @@ import ( // DeterministicMarshal calls the jsonv2 library with the deterministic // flag in order to have stable marshaling. func DeterministicMarshal(in any) ([]byte, error) { - return jsonv2.MarshalOptions{Deterministic: true}.Marshal(jsonv2.EncodeOptions{}, in) + return jsonv2.Marshal(in, jsonv2.Deterministic(true)) } // JSONRefFromMap populates a json reference object if the map v contains a $ref key. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/README.md b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/README.md index 0349adf6..937c3980 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/README.md +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/README.md @@ -7,17 +7,24 @@ This module hosts an experimental implementation of v2 `encoding/json`. The API is unstable and breaking changes will regularly be made. Do not depend on this in publicly available modules. +Any commits that make breaking API or behavior changes will be marked +with the string "WARNING: " near the top of the commit message. +It is your responsibility to inspect the list of commit changes +when upgrading the module. Not all breaking changes will lead to build failures. + +A [proposal to include this module in Go as `encoding/json/v2` and `encoding/json/jsontext`](https://github.com/golang/go/issues/71497) has been started on the Go Github project on 2025-01-30. Please provide your feedback there. + ## Goals and objectives * **Mostly backwards compatible:** If possible, v2 should aim to be _mostly_ compatible with v1 in terms of both API and default behavior to ease migration. For example, the `Marshal` and `Unmarshal` functions are the most widely used declarations in the v1 package. It seems sensible for equivalent functionality -in v2 to be named the same and have the same signature. +in v2 to be named the same and have a mostly compatible signature. Behaviorally, we should aim for 95% to 99% backwards compatibility. We do not aim for 100% compatibility since we want the freedom to break certain behaviors that are now considered to have been a mistake. -We may provide options that can bring the v2 implementation to 100% compatibility, +Options exist that can bring the v2 implementation to 100% compatibility, but it will not be the default. * **More flexible:** There is a @@ -96,26 +103,32 @@ Syntax deals with the structural representation of JSON (as specified in Semantics deals with the meaning of syntactic data as usable application data. The `Encoder` and `Decoder` types are streaming tokenizers concerned with the -packing or parsing of JSON data. They operate on `Token` and `RawValue` types +packing or parsing of JSON data. They operate on `Token` and `Value` types which represent the common data structures that are representable in JSON. `Encoder` and `Decoder` do not aim to provide any interpretation of the data. -Functions like `Marshal`, `MarshalFull`, `MarshalNext`, `Unmarshal`, -`UnmarshalFull`, and `UnmarshalNext` provide semantic meaning by correlating +Functions like `Marshal`, `MarshalWrite`, `MarshalEncode`, `Unmarshal`, +`UnmarshalRead`, and `UnmarshalDecode` provide semantic meaning by correlating any arbitrary Go type with some JSON representation of that type (as stored in data types like `[]byte`, `io.Writer`, `io.Reader`, `Encoder`, or `Decoder`). ![API overview](api.png) -This diagram provides a high-level overview of the v2 `json` package. +This diagram provides a high-level overview of the v2 `json` and `jsontext` packages. Purple blocks represent types, while blue blocks represent functions or methods. The arrows and their direction represent the approximate flow of data. The bottom half of the diagram contains functionality that is only concerned -with syntax, while the upper half contains functionality that assigns -semantic meaning to syntactic data handled by the bottom half. +with syntax (implemented by the `jsontext` package), +while the upper half contains functionality that assigns +semantic meaning to syntactic data handled by the bottom half +(as implemented by the v2 `json` package). In contrast to v1 `encoding/json`, options are represented as separate types rather than being setter methods on the `Encoder` or `Decoder` types. +Some options affects JSON serialization at the syntactic layer, +while others affect it at the semantic layer. +Some options only affect JSON when decoding, +while others affect JSON while encoding. ## Behavior changes @@ -128,194 +141,35 @@ This table shows an overview of the changes: | v1 | v2 | Details | | -- | -- | ------- | -| JSON object members are unmarshaled into a Go struct using a **case-insensitive name match**. | JSON object members are unmarshaled into a Go struct using a **case-sensitive name match**. | [CaseSensitivity](/diff_test.go#:~:text=TestCaseSensitivity) | -| When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value is an empty Go value**, which is defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string. | When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value would encode as an empty JSON value**, which is defined as a JSON null, or an empty JSON string, object, or array. | [OmitEmptyOption](/diff_test.go#:~:text=TestOmitEmptyOption) | -| The `string` option **does affect** Go bools. | The `string` option **does not affect** Go bools. | [StringOption](/diff_test.go#:~:text=TestStringOption) | -| The `string` option **does not recursively affect** sub-values of the Go field value. | The `string` option **does recursively affect** sub-values of the Go field value. | [StringOption](/diff_test.go#:~:text=TestStringOption) | -| The `string` option **sometimes accepts** a JSON null escaped within a JSON string. | The `string` option **never accepts** a JSON null escaped within a JSON string. | [StringOption](/diff_test.go#:~:text=TestStringOption) | -| A nil Go slice is marshaled as a **JSON null**. | A nil Go slice is marshaled as an **empty JSON array**. | [NilSlicesAndMaps](/diff_test.go#:~:text=TestNilSlicesAndMaps) | -| A nil Go map is marshaled as a **JSON null**. | A nil Go map is marshaled as an **empty JSON object**. | [NilSlicesAndMaps](/diff_test.go#:~:text=TestNilSlicesAndMaps) | -| A Go array may be unmarshaled from a **JSON array of any length**. | A Go array must be unmarshaled from a **JSON array of the same length**. | [Arrays](/diff_test.go#:~:text=Arrays) | -| A Go byte array is represented as a **JSON array of JSON numbers**. | A Go byte array is represented as a **Base64-encoded JSON string**. | [ByteArrays](/diff_test.go#:~:text=TestByteArrays) | -| `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **inconsistently called**. | `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **consistently called**. | [PointerReceiver](/diff_test.go#:~:text=TestPointerReceiver) | -| A Go map is marshaled in a **deterministic order**. | A Go map is marshaled in a **non-deterministic order**. | [MapDeterminism](/diff_test.go#:~:text=TestMapDeterminism) | -| JSON strings are encoded **with HTML-specific characters being escaped**. | JSON strings are encoded **without any characters being escaped** (unless necessary). | [EscapeHTML](/diff_test.go#:~:text=TestEscapeHTML) | -| When marshaling, invalid UTF-8 within a Go string **are silently replaced**. | When marshaling, invalid UTF-8 within a Go string **results in an error**. | [InvalidUTF8](/diff_test.go#:~:text=TestInvalidUTF8) | -| When unmarshaling, invalid UTF-8 within a JSON string **are silently replaced**. | When unmarshaling, invalid UTF-8 within a JSON string **results in an error**. | [InvalidUTF8](/diff_test.go#:~:text=TestInvalidUTF8) | -| When marshaling, **an error does not occur** if the output JSON value contains objects with duplicate names. | When marshaling, **an error does occur** if the output JSON value contains objects with duplicate names. | [DuplicateNames](/diff_test.go#:~:text=TestDuplicateNames) | -| When unmarshaling, **an error does not occur** if the input JSON value contains objects with duplicate names. | When unmarshaling, **an error does occur** if the input JSON value contains objects with duplicate names. | [DuplicateNames](/diff_test.go#:~:text=TestDuplicateNames) | -| Unmarshaling a JSON null into a non-empty Go value **inconsistently clears the value or does nothing**. | Unmarshaling a JSON null into a non-empty Go value **always clears the value**. | [MergeNull](/diff_test.go#:~:text=TestMergeNull) | -| Unmarshaling a JSON value into a non-empty Go value **follows inconsistent and bizarre behavior**. | Unmarshaling a JSON value into a non-empty Go value **always merges if the input is an object, and otherwise replaces**. | [MergeComposite](/diff_test.go#:~:text=TestMergeComposite) | -| A `time.Duration` is represented as a **JSON number containing the decimal number of nanoseconds**. | A `time.Duration` is represented as a **JSON string containing the formatted duration (e.g., "1h2m3.456s")**. | [TimeDurations](/diff_test.go#:~:text=TestTimeDurations) | -| Unmarshaling a JSON number into a Go float beyond its representation **results in an error**. | Unmarshaling a JSON number into a Go float beyond its representation **uses the closest representable value (e.g., ±`math.MaxFloat`)**. | [MaxFloats](/diff_test.go#:~:text=TestMaxFloats) | -| A Go struct with only unexported fields **can be serialized**. | A Go struct with only unexported fields **cannot be serialized**. | [EmptyStructs](/diff_test.go#:~:text=TestEmptyStructs) | -| A Go struct that embeds an unexported struct type **can sometimes be serialized**. | A Go struct that embeds an unexported struct type **cannot be serialized**. | [EmbedUnexported](/diff_test.go#:~:text=TestEmbedUnexported) | - -See [diff_test.go](/diff_test.go) for details about every change. +| JSON object members are unmarshaled into a Go struct using a **case-insensitive name match**. | JSON object members are unmarshaled into a Go struct using a **case-sensitive name match**. | [CaseSensitivity](/v1/diff_test.go#:~:text=TestCaseSensitivity) | +| When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value is an empty Go value**, which is defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string. | When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value would encode as an empty JSON value**, which is defined as a JSON null, or an empty JSON string, object, or array. | [OmitEmptyOption](/v1/diff_test.go#:~:text=TestOmitEmptyOption) | +| The `string` option **does affect** Go strings and bools. | The `string` option **does not affect** Go strings or bools. | [StringOption](/v1/diff_test.go#:~:text=TestStringOption) | +| The `string` option **does not recursively affect** sub-values of the Go field value. | The `string` option **does recursively affect** sub-values of the Go field value. | [StringOption](/v1/diff_test.go#:~:text=TestStringOption) | +| The `string` option **sometimes accepts** a JSON null escaped within a JSON string. | The `string` option **never accepts** a JSON null escaped within a JSON string. | [StringOption](/v1/diff_test.go#:~:text=TestStringOption) | +| A nil Go slice is marshaled as a **JSON null**. | A nil Go slice is marshaled as an **empty JSON array**. | [NilSlicesAndMaps](/v1/diff_test.go#:~:text=TestNilSlicesAndMaps) | +| A nil Go map is marshaled as a **JSON null**. | A nil Go map is marshaled as an **empty JSON object**. | [NilSlicesAndMaps](/v1/diff_test.go#:~:text=TestNilSlicesAndMaps) | +| A Go array may be unmarshaled from a **JSON array of any length**. | A Go array must be unmarshaled from a **JSON array of the same length**. | [Arrays](/v1/diff_test.go#:~:text=Arrays) | +| A Go byte array is represented as a **JSON array of JSON numbers**. | A Go byte array is represented as a **Base64-encoded JSON string**. | [ByteArrays](/v1/diff_test.go#:~:text=TestByteArrays) | +| `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **inconsistently called**. | `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **consistently called**. | [PointerReceiver](/v1/diff_test.go#:~:text=TestPointerReceiver) | +| A Go map is marshaled in a **deterministic order**. | A Go map is marshaled in a **non-deterministic order**. | [MapDeterminism](/v1/diff_test.go#:~:text=TestMapDeterminism) | +| JSON strings are encoded **with HTML-specific characters being escaped**. | JSON strings are encoded **without any characters being escaped** (unless necessary). | [EscapeHTML](/v1/diff_test.go#:~:text=TestEscapeHTML) | +| When marshaling, invalid UTF-8 within a Go string **are silently replaced**. | When marshaling, invalid UTF-8 within a Go string **results in an error**. | [InvalidUTF8](/v1/diff_test.go#:~:text=TestInvalidUTF8) | +| When unmarshaling, invalid UTF-8 within a JSON string **are silently replaced**. | When unmarshaling, invalid UTF-8 within a JSON string **results in an error**. | [InvalidUTF8](/v1/diff_test.go#:~:text=TestInvalidUTF8) | +| When marshaling, **an error does not occur** if the output JSON value contains objects with duplicate names. | When marshaling, **an error does occur** if the output JSON value contains objects with duplicate names. | [DuplicateNames](/v1/diff_test.go#:~:text=TestDuplicateNames) | +| When unmarshaling, **an error does not occur** if the input JSON value contains objects with duplicate names. | When unmarshaling, **an error does occur** if the input JSON value contains objects with duplicate names. | [DuplicateNames](/v1/diff_test.go#:~:text=TestDuplicateNames) | +| Unmarshaling a JSON null into a non-empty Go value **inconsistently clears the value or does nothing**. | Unmarshaling a JSON null into a non-empty Go value **always clears the value**. | [MergeNull](/v1/diff_test.go#:~:text=TestMergeNull) | +| Unmarshaling a JSON value into a non-empty Go value **follows inconsistent and bizarre behavior**. | Unmarshaling a JSON value into a non-empty Go value **always merges if the input is an object, and otherwise replaces**. | [MergeComposite](/v1/diff_test.go#:~:text=TestMergeComposite) | +| A `time.Duration` is represented as a **JSON number containing the decimal number of nanoseconds**. | A `time.Duration` has no default representation in v2 (see [#71631](https://golang.org/issue/71631)) and results in an error. | | +| A Go struct with only unexported fields **can be serialized**. | A Go struct with only unexported fields **cannot be serialized**. | [EmptyStructs](/v1/diff_test.go#:~:text=TestEmptyStructs) | + +See [diff_test.go](/v1/diff_test.go) for details about every change. ## Performance -One of the goals of the v2 module is to be more performant than v1. - -Each of the charts below show the performance across -several different JSON implementations: - -* `JSONv1` is `encoding/json` at `v1.18.2` -* `JSONv2` is `github.com/go-json-experiment/json` at `v0.0.0-20220524042235-dd8be80fc4a7` -* `JSONIterator` is `github.com/json-iterator/go` at `v1.1.12` -* `SegmentJSON` is `github.com/segmentio/encoding/json` at `v0.3.5` -* `GoJSON` is `github.com/goccy/go-json` at `v0.9.7` -* `SonicJSON` is `github.com/bytedance/sonic` at `v1.3.0` - -Benchmarks were run across various datasets: - -* `CanadaGeometry` is a GeoJSON (RFC 7946) representation of Canada. - It contains many JSON arrays of arrays of two-element arrays of numbers. -* `CITMCatalog` contains many JSON objects using numeric names. -* `SyntheaFHIR` is sample JSON data from the healthcare industry. - It contains many nested JSON objects with mostly string values, - where the set of unique string values is relatively small. -* `TwitterStatus` is the JSON response from the Twitter API. - It contains a mix of all different JSON kinds, where string values - are a mix of both single-byte ASCII and multi-byte Unicode. -* `GolangSource` is a simple tree representing the Go source code. - It contains many nested JSON objects, each with the same schema. -* `StringUnicode` contains many strings with multi-byte Unicode runes. - -All of the implementations other than `JSONv1` and `JSONv2` make -extensive use of `unsafe`. As such, we expect those to generally be faster, -but at the cost of memory and type safety. `SonicJSON` goes a step even further -and uses just-in-time compilation to generate machine code specialized -for the Go type being marshaled or unmarshaled. -Also, `SonicJSON` does not validate JSON strings for valid UTF-8, -and so gains a notable performance boost on datasets with multi-byte Unicode. -Benchmarks are performed based on the default marshal and unmarshal behavior -of each package. Note that `JSONv2` aims to be safe and correct by default, -which may not be the most performant strategy. - -`JSONv2` has several semantic changes relative to `JSONv1` that -impacts performance: - -1. When marshaling, `JSONv2` no longer sorts the keys of a Go map. - This will improve performance. -2. When marshaling or unmarshaling, `JSONv2` always checks - to make sure JSON object names are unique. - This will hurt performance, but is more correct. -3. When marshaling or unmarshaling, `JSONv2` always - shallow copies the underlying value for a Go interface and - shallow copies the key and value for entries in a Go map. - This is done to keep the value as addressable so that `JSONv2` can - call methods and functions that operate on a pointer receiver. - This will hurt performance, but is more correct. - -All of the charts are unit-less since the values are normalized -relative to `JSONv1`, which is why `JSONv1` always has a value of 1. -A lower value is better (i.e., runs faster). - -Benchmarks were performed on an AMD Ryzen 9 5900X. - -The code for the benchmarks is located at -https://github.com/go-json-experiment/jsonbench. - -### Marshal Performance - -#### Concrete types - -![Benchmark Marshal Concrete](benchmark-marshal-concrete.png) - -* This compares marshal performance when serializing - [from concrete types](/testdata_test.go). -* The `JSONv1` implementation is close to optimal (without the use of `unsafe`). -* Relative to `JSONv1`, `JSONv2` is generally as fast or slightly faster. -* Relative to `JSONIterator`, `JSONv2` is up to 1.3x faster. -* Relative to `SegmentJSON`, `JSONv2` is up to 1.8x slower. -* Relative to `GoJSON`, `JSONv2` is up to 2.0x slower. -* Relative to `SonicJSON`, `JSONv2` is about 1.8x to 3.2x slower - (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). -* For `JSONv1` and `JSONv2`, marshaling from concrete types is - mostly limited by the performance of Go reflection. - -#### Interface types - -![Benchmark Marshal Interface](benchmark-marshal-interface.png) - -* This compares marshal performance when serializing from - `any`, `map[string]any`, and `[]any` types. -* Relative to `JSONv1`, `JSONv2` is about 1.5x to 4.2x faster. -* Relative to `JSONIterator`, `JSONv2` is about 1.1x to 2.4x faster. -* Relative to `SegmentJSON`, `JSONv2` is about 1.2x to 1.8x faster. -* Relative to `GoJSON`, `JSONv2` is about 1.1x to 2.5x faster. -* Relative to `SonicJSON`, `JSONv2` is up to 1.5x slower - (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). -* `JSONv2` is faster than the alternatives. - One advantange is because it does not sort the keys for a `map[string]any`, - while alternatives (except `SonicJSON` and `JSONIterator`) do sort the keys. - -#### RawValue types - -![Benchmark Marshal Rawvalue](benchmark-marshal-rawvalue.png) - -* This compares performance when marshaling from a `json.RawValue`. - This mostly exercises the underlying encoder and - hides the cost of Go reflection. -* Relative to `JSONv1`, `JSONv2` is about 3.5x to 7.8x faster. -* `JSONIterator` is blazingly fast because - [it does not validate whether the raw value is valid](https://go.dev/play/p/bun9IXQCKRe) - and simply copies it to the output. -* Relative to `SegmentJSON`, `JSONv2` is about 1.5x to 2.7x faster. -* Relative to `GoJSON`, `JSONv2` is up to 2.2x faster. -* Relative to `SonicJSON`, `JSONv2` is up to 1.5x faster. -* Aside from `JSONIterator`, `JSONv2` is generally the fastest. - -### Unmarshal Performance - -#### Concrete types - -![Benchmark Unmarshal Concrete](benchmark-unmarshal-concrete.png) - -* This compares unmarshal performance when deserializing - [into concrete types](/testdata_test.go). -* Relative to `JSONv1`, `JSONv2` is about 1.8x to 5.7x faster. -* Relative to `JSONIterator`, `JSONv2` is about 1.1x to 1.6x slower. -* Relative to `SegmentJSON`, `JSONv2` is up to 2.5x slower. -* Relative to `GoJSON`, `JSONv2` is about 1.4x to 2.1x slower. -* Relative to `SonicJSON`, `JSONv2` is up to 4.0x slower - (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). -* For `JSONv1` and `JSONv2`, unmarshaling into concrete types is - mostly limited by the performance of Go reflection. - -#### Interface types - -![Benchmark Unmarshal Interface](benchmark-unmarshal-interface.png) - -* This compares unmarshal performance when deserializing into - `any`, `map[string]any`, and `[]any` types. -* Relative to `JSONv1`, `JSONv2` is about 1.tx to 4.3x faster. -* Relative to `JSONIterator`, `JSONv2` is up to 1.5x faster. -* Relative to `SegmentJSON`, `JSONv2` is about 1.5 to 3.7x faster. -* Relative to `GoJSON`, `JSONv2` is up to 1.3x faster. -* Relative to `SonicJSON`, `JSONv2` is up to 1.5x slower - (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). -* Aside from `SonicJSON`, `JSONv2` is generally just as fast - or faster than all the alternatives. - -#### RawValue types - -![Benchmark Unmarshal Rawvalue](benchmark-unmarshal-rawvalue.png) - -* This compares performance when unmarshaling into a `json.RawValue`. - This mostly exercises the underlying decoder and - hides away most of the cost of Go reflection. -* Relative to `JSONv1`, `JSONv2` is about 8.3x to 17.0x faster. -* Relative to `JSONIterator`, `JSONv2` is up to 2.0x faster. -* Relative to `SegmentJSON`, `JSONv2` is up to 1.6x faster or 1.7x slower. -* Relative to `GoJSON`, `JSONv2` is up to 1.9x faster or 2.1x slower. -* Relative to `SonicJSON`, `JSONv2` is up to 2.0x faster - (ignoring `StringUnicode` since `SonicJSON` does not validate UTF-8). -* `JSONv1` takes a - [lexical scanning approach](https://talks.golang.org/2011/lex.slide#1), - which performs a virtual function call for every byte of input. - In contrast, `JSONv2` makes heavy use of iterative and linear parsing logic - (with extra complexity to resume parsing when encountering segmented buffers). -* `JSONv2` is comparable to the alternatives that use `unsafe`. - Generally it is faster, but sometimes it is slower. +One of the goals of the v2 module is to be more performant than v1, +but not at the expense of correctness. +In general, v2 is at performance parity with v1 for marshaling, +but dramatically faster for unmarshaling. + +See https://github.com/go-json-experiment/jsonbench for benchmarks +comparing v2 with v1 and a number of other popular JSON implementations. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go index e6c6216f..dbf92432 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go @@ -5,109 +5,65 @@ package json import ( - "errors" + "bytes" + "encoding" "io" "reflect" + "slices" + "strings" "sync" -) - -// MarshalOptions configures how Go data is serialized as JSON data. -// The zero value is equivalent to the default marshal settings. -type MarshalOptions struct { - requireKeyedLiterals - nonComparable - - // Marshalers is a list of type-specific marshalers to use. - Marshalers *Marshalers - - // StringifyNumbers specifies that numeric Go types should be serialized - // as a JSON string containing the equivalent JSON number value. - // - // According to RFC 8259, section 6, a JSON implementation may choose to - // limit the representation of a JSON number to an IEEE 754 binary64 value. - // This may cause decoders to lose precision for int64 and uint64 types. - // Escaping JSON numbers as a JSON string preserves the exact precision. - StringifyNumbers bool - - // DiscardUnknownMembers specifies that marshaling should ignore any - // JSON object members stored in Go struct fields dedicated to storing - // unknown JSON object members. - DiscardUnknownMembers bool - - // Deterministic specifies that the same input value will be serialized - // as the exact same output bytes. Different processes of - // the same program will serialize equal values to the same bytes, - // but different versions of the same program are not guaranteed - // to produce the exact same sequence of bytes. - Deterministic bool + "time" - // formatDepth is the depth at which we respect the format flag. - formatDepth int - // format is custom formatting for the value at the specified depth. - format string -} + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" +) -// Marshal serializes a Go value as a []byte with default options. -// It is a thin wrapper over MarshalOptions.Marshal. -func Marshal(in any) (out []byte, err error) { - return MarshalOptions{}.Marshal(EncodeOptions{}, in) -} +// Reference encoding and time packages to assist pkgsite +// in being able to hotlink references to those packages. +var ( + _ encoding.TextMarshaler + _ encoding.TextAppender + _ encoding.TextUnmarshaler + _ time.Time + _ time.Duration +) -// MarshalFull serializes a Go value into an io.Writer with default options. -// It is a thin wrapper over MarshalOptions.MarshalFull. -func MarshalFull(out io.Writer, in any) error { - return MarshalOptions{}.MarshalFull(EncodeOptions{}, out, in) -} +// export exposes internal functionality of the "jsontext" package. +var export = jsontext.Internal.Export(&internal.AllowInternalUse) // Marshal serializes a Go value as a []byte according to the provided -// marshal and encode options. It does not terminate the output with a newline. -// See MarshalNext for details about the conversion of a Go value into JSON. -func (mo MarshalOptions) Marshal(eo EncodeOptions, in any) (out []byte, err error) { - enc := getBufferedEncoder(eo) - defer putBufferedEncoder(enc) - enc.options.omitTopLevelNewline = true - err = mo.MarshalNext(enc, in) - // TODO(https://go.dev/issue/45038): Use bytes.Clone. - return append([]byte(nil), enc.buf...), err -} - -// MarshalFull serializes a Go value into an io.Writer according to the provided -// marshal and encode options. It does not terminate the output with a newline. -// See MarshalNext for details about the conversion of a Go value into JSON. -func (mo MarshalOptions) MarshalFull(eo EncodeOptions, out io.Writer, in any) error { - enc := getStreamingEncoder(out, eo) - defer putStreamingEncoder(enc) - enc.options.omitTopLevelNewline = true - err := mo.MarshalNext(enc, in) - return err -} - -// MarshalNext encodes a Go value as the next JSON value according to -// the provided marshal options. +// marshal and encode options (while ignoring unmarshal or decode options). +// It does not terminate the output with a newline. // // Type-specific marshal functions and methods take precedence // over the default representation of a value. // Functions or methods that operate on *T are only called when encoding // a value of type T (by taking its address) or a non-nil value of *T. -// MarshalNext ensures that a value is always addressable +// Marshal ensures that a value is always addressable // (by boxing it on the heap if necessary) so that // these functions and methods can be consistently called. For performance, -// it is recommended that MarshalNext be passed a non-nil pointer to the value. +// it is recommended that Marshal be passed a non-nil pointer to the value. // // The input value is encoded as JSON according the following rules: // -// - If any type-specific functions in MarshalOptions.Marshalers match +// - If any type-specific functions in a [WithMarshalers] option match // the value type, then those functions are called to encode the value. -// If all applicable functions return SkipFunc, +// If all applicable functions return [SkipFunc], // then the value is encoded according to subsequent rules. // -// - If the value type implements MarshalerV2, -// then the MarshalNextJSON method is called to encode the value. +// - If the value type implements [MarshalerTo], +// then the MarshalJSONTo method is called to encode the value. // -// - If the value type implements MarshalerV1, +// - If the value type implements [Marshaler], // then the MarshalJSON method is called to encode the value. // -// - If the value type implements encoding.TextMarshaler, +// - If the value type implements [encoding.TextAppender], +// then the AppendText method is called to encode the value and +// subsequently encode its result as a JSON string. +// +// - If the value type implements [encoding.TextMarshaler], // then the MarshalText method is called to encode the value and // subsequently encode its result as a JSON string. // @@ -139,25 +95,25 @@ func (mo MarshalOptions) MarshalFull(eo EncodeOptions, out io.Writer, in any) er // where each byte is recursively JSON-encoded as each JSON array element. // // - A Go integer is encoded as a JSON number without fractions or exponents. -// If MarshalOptions.StringifyNumbers is specified, then the JSON number is -// encoded within a JSON string. It does not support any custom format -// flags. +// If [StringifyNumbers] is specified or encoding a JSON object name, +// then the JSON number is encoded within a JSON string. +// It does not support any custom format flags. // // - A Go float is encoded as a JSON number. -// If MarshalOptions.StringifyNumbers is specified, +// If [StringifyNumbers] is specified or encoding a JSON object name, // then the JSON number is encoded within a JSON string. // If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as // the JSON strings "NaN", "Infinity", and "-Infinity", respectively. -// Otherwise, the presence of non-finite numbers results in a SemanticError. +// Otherwise, the presence of non-finite numbers results in a [SemanticError]. // // - A Go map is encoded as a JSON object, where each Go map key and value // is recursively encoded as a name and value pair in the JSON object. // The Go map key must encode as a JSON string, otherwise this results -// in a SemanticError. When encoding keys, MarshalOptions.StringifyNumbers -// is automatically applied so that numeric keys encode as JSON strings. -// The Go map is traversed in a non-deterministic order. -// For deterministic encoding, consider using RawValue.Canonicalize. +// in a [SemanticError]. The Go map is traversed in a non-deterministic order. +// For deterministic encoding, consider using the [Deterministic] option. // If the format is "emitnull", then a nil map is encoded as a JSON null. +// If the format is "emitempty", then a nil map is encoded as an empty JSON object, +// regardless of whether [FormatNilMapAsNull] is specified. // Otherwise by default, a nil map is encoded as an empty JSON object. // // - A Go struct is encoded as a JSON object. @@ -167,6 +123,8 @@ func (mo MarshalOptions) MarshalFull(eo EncodeOptions, out io.Writer, in any) er // - A Go slice is encoded as a JSON array, where each Go slice element // is recursively JSON-encoded as the elements of the JSON array. // If the format is "emitnull", then a nil slice is encoded as a JSON null. +// If the format is "emitempty", then a nil slice is encoded as an empty JSON array, +// regardless of whether [FormatNilSliceAsNull] is specified. // Otherwise by default, a nil slice is encoded as an empty JSON array. // // - A Go array is encoded as a JSON array, where each Go array element @@ -182,148 +140,144 @@ func (mo MarshalOptions) MarshalFull(eo EncodeOptions, out io.Writer, in any) er // the recursively JSON-encoded representation of the underlying value. // It does not support any custom format flags. // -// - A Go time.Time is encoded as a JSON string containing the timestamp -// formatted in RFC 3339 with nanosecond resolution. +// - A Go [time.Time] is encoded as a JSON string containing the timestamp +// formatted in RFC 3339 with nanosecond precision. // If the format matches one of the format constants declared // in the time package (e.g., RFC1123), then that format is used. -// Otherwise, the format is used as-is with time.Time.Format if non-empty. -// -// - A Go time.Duration is encoded as a JSON string containing the duration -// formatted according to time.Duration.String. -// If the format is "nanos", it is encoded as a JSON number -// containing the number of nanoseconds in the duration. +// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", +// then the timestamp is encoded as a possibly fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds) +// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. +// To avoid a fractional component, round the timestamp to the relevant unit. +// Otherwise, the format is used as-is with [time.Time.Format] if non-empty. +// +// - A Go [time.Duration] currently has no default representation and +// requires an explicit format to be specified. +// If the format is "sec", "milli", "micro", or "nano", +// then the duration is encoded as a possibly fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds). +// To avoid a fractional component, round the duration to the relevant unit. +// If the format is "units", it is encoded as a JSON string formatted using +// [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes). +// If the format is "iso8601", it is encoded as a JSON string using the +// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) +// using only accurate units of hours, minutes, and seconds. // // - All other Go types (e.g., complex numbers, channels, and functions) -// have no default representation and result in a SemanticError. +// have no default representation and result in a [SemanticError]. // -// JSON cannot represent cyclic data structures and -// MarshalNext does not handle them. +// JSON cannot represent cyclic data structures and Marshal does not handle them. // Passing cyclic structures will result in an error. -func (mo MarshalOptions) MarshalNext(out *Encoder, in any) error { +func Marshal(in any, opts ...Options) (out []byte, err error) { + enc := export.GetBufferedEncoder(opts...) + defer export.PutBufferedEncoder(enc) + xe := export.Encoder(enc) + xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1) + err = marshalEncode(enc, in, &xe.Struct) + if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return nil, internal.TransformMarshalError(in, err) + } + return bytes.Clone(xe.Buf), err +} + +// MarshalWrite serializes a Go value into an [io.Writer] according to the provided +// marshal and encode options (while ignoring unmarshal or decode options). +// It does not terminate the output with a newline. +// See [Marshal] for details about the conversion of a Go value into JSON. +func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) { + enc := export.GetStreamingEncoder(out, opts...) + defer export.PutStreamingEncoder(enc) + xe := export.Encoder(enc) + xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1) + err = marshalEncode(enc, in, &xe.Struct) + if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.TransformMarshalError(in, err) + } + return err +} + +// MarshalEncode serializes a Go value into an [jsontext.Encoder] according to +// the provided marshal options (while ignoring unmarshal, encode, or decode options). +// Any marshal-relevant options already specified on the [jsontext.Encoder] +// take lower precedence than the set of options provided by the caller. +// Unlike [Marshal] and [MarshalWrite], encode options are ignored because +// they must have already been specified on the provided [jsontext.Encoder]. +// +// See [Marshal] for details about the conversion of a Go value into JSON. +func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { + xe := export.Encoder(out) + if len(opts) > 0 { + optsOriginal := xe.Struct + defer func() { xe.Struct = optsOriginal }() + xe.Struct.JoinWithoutCoderOptions(opts...) + } + err = marshalEncode(out, in, &xe.Struct) + if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.TransformMarshalError(in, err) + } + return err +} + +func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err error) { v := reflect.ValueOf(in) if !v.IsValid() || (v.Kind() == reflect.Pointer && v.IsNil()) { - return out.WriteToken(Null) + return out.WriteToken(jsontext.Null) } // Shallow copy non-pointer values to obtain an addressable value. // It is beneficial to performance to always pass pointers to avoid this. - if v.Kind() != reflect.Pointer { + forceAddr := v.Kind() != reflect.Pointer + if forceAddr { v2 := reflect.New(v.Type()) v2.Elem().Set(v) v = v2 } - va := addressableValue{v.Elem()} // dereferenced pointer is always addressable + va := addressableValue{v.Elem(), forceAddr} // dereferenced pointer is always addressable t := va.Type() // Lookup and call the marshal function for this type. marshal := lookupArshaler(t).marshal if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, t) + marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t) } - if err := marshal(mo, out, va); err != nil { - if !out.options.AllowDuplicateNames { - out.tokens.invalidateDisabledNamespaces() + if err := marshal(out, va, mo); err != nil { + if !mo.Flags.Get(jsonflags.AllowDuplicateNames) { + export.Encoder(out).Tokens.InvalidateDisabledNamespaces() } return err } return nil } -// UnmarshalOptions configures how JSON data is deserialized as Go data. -// The zero value is equivalent to the default unmarshal settings. -type UnmarshalOptions struct { - requireKeyedLiterals - nonComparable - - // Unmarshalers is a list of type-specific unmarshalers to use. - Unmarshalers *Unmarshalers - - // StringifyNumbers specifies that numeric Go types can be deserialized - // from either a JSON number or a JSON string containing a JSON number - // without any surrounding whitespace. - StringifyNumbers bool - - // RejectUnknownMembers specifies that unknown members should be rejected - // when unmarshaling a JSON object, regardless of whether there is a field - // to store unknown members. - RejectUnknownMembers bool - - // formatDepth is the depth at which we respect the format flag. - formatDepth int - // format is custom formatting for the value at the specified depth. - format string -} - -// Unmarshal deserializes a Go value from a []byte with default options. -// It is a thin wrapper over UnmarshalOptions.Unmarshal. -func Unmarshal(in []byte, out any) error { - return UnmarshalOptions{}.Unmarshal(DecodeOptions{}, in, out) -} - -// UnmarshalFull deserializes a Go value from an io.Reader with default options. -// It is a thin wrapper over UnmarshalOptions.UnmarshalFull. -func UnmarshalFull(in io.Reader, out any) error { - return UnmarshalOptions{}.UnmarshalFull(DecodeOptions{}, in, out) -} - -// Unmarshal deserializes a Go value from a []byte according to the -// provided unmarshal and decode options. The output must be a non-nil pointer. +// Unmarshal decodes a []byte input into a Go value according to the provided +// unmarshal and decode options (while ignoring marshal or encode options). // The input must be a single JSON value with optional whitespace interspersed. -// See UnmarshalNext for details about the conversion of JSON into a Go value. -func (uo UnmarshalOptions) Unmarshal(do DecodeOptions, in []byte, out any) error { - dec := getBufferedDecoder(in, do) - defer putBufferedDecoder(dec) - return uo.unmarshalFull(dec, out) -} - -// UnmarshalFull deserializes a Go value from an io.Reader according to the -// provided unmarshal and decode options. The output must be a non-nil pointer. -// The input must be a single JSON value with optional whitespace interspersed. -// It consumes the entirety of io.Reader until io.EOF is encountered. -// See UnmarshalNext for details about the conversion of JSON into a Go value. -func (uo UnmarshalOptions) UnmarshalFull(do DecodeOptions, in io.Reader, out any) error { - dec := getStreamingDecoder(in, do) - defer putStreamingDecoder(dec) - return uo.unmarshalFull(dec, out) -} -func (uo UnmarshalOptions) unmarshalFull(in *Decoder, out any) error { - switch err := uo.UnmarshalNext(in, out); err { - case nil: - return in.checkEOF() - case io.EOF: - return io.ErrUnexpectedEOF - default: - return err - } -} - -// UnmarshalNext decodes the next JSON value into a Go value according to -// the provided unmarshal options. The output must be a non-nil pointer. +// The output must be a non-nil pointer. // // Type-specific unmarshal functions and methods take precedence // over the default representation of a value. // Functions or methods that operate on *T are only called when decoding // a value of type T (by taking its address) or a non-nil value of *T. -// UnmarshalNext ensures that a value is always addressable +// Unmarshal ensures that a value is always addressable // (by boxing it on the heap if necessary) so that // these functions and methods can be consistently called. // // The input is decoded into the output according the following rules: // -// - If any type-specific functions in UnmarshalOptions.Unmarshalers match +// - If any type-specific functions in a [WithUnmarshalers] option match // the value type, then those functions are called to decode the JSON -// value. If all applicable functions return SkipFunc, +// value. If all applicable functions return [SkipFunc], // then the input is decoded according to subsequent rules. // -// - If the value type implements UnmarshalerV2, -// then the UnmarshalNextJSON method is called to decode the JSON value. +// - If the value type implements [UnmarshalerFrom], +// then the UnmarshalJSONFrom method is called to decode the JSON value. // -// - If the value type implements UnmarshalerV1, +// - If the value type implements [Unmarshaler], // then the UnmarshalJSON method is called to decode the JSON value. // -// - If the value type implements encoding.TextUnmarshaler, +// - If the value type implements [encoding.TextUnmarshaler], // then the input is decoded as a JSON string and // the UnmarshalText method is called with the decoded string value. -// This fails with a SemanticError if the input is not a JSON string. +// This fails with a [SemanticError] if the input is not a JSON string. // // - Otherwise, the JSON value is decoded according to the value's type // as described in detail below. @@ -336,7 +290,7 @@ func (uo UnmarshalOptions) unmarshalFull(in *Decoder, out any) error { // A JSON null may be decoded into every supported Go value where // it is equivalent to storing the zero value of the Go value. // If the input JSON kind is not handled by the current Go value type, -// then this fails with a SemanticError. Unless otherwise specified, +// then this fails with a [SemanticError]. Unless otherwise specified, // the decoded value replaces any pre-existing value. // // The representation of each type is as follows: @@ -359,33 +313,31 @@ func (uo UnmarshalOptions) unmarshalFull(in *Decoder, out any) error { // When decoding into a non-nil []byte, the slice length is reset to zero // and the decoded input is appended to it. // When decoding into a [N]byte, the input must decode to exactly N bytes, -// otherwise it fails with a SemanticError. +// otherwise it fails with a [SemanticError]. // // - A Go integer is decoded from a JSON number. -// It may also be decoded from a JSON string containing a JSON number -// if UnmarshalOptions.StringifyNumbers is specified. -// It fails with a SemanticError if the JSON number +// It must be decoded from a JSON string containing a JSON number +// if [StringifyNumbers] is specified or decoding a JSON object name. +// It fails with a [SemanticError] if the JSON number // has a fractional or exponent component. // It also fails if it overflows the representation of the Go integer type. // It does not support any custom format flags. // // - A Go float is decoded from a JSON number. -// It may also be decoded from a JSON string containing a JSON number -// if UnmarshalOptions.StringifyNumbers is specified. -// The JSON number is parsed as the closest representable Go float value. +// It must be decoded from a JSON string containing a JSON number +// if [StringifyNumbers] is specified or decoding a JSON object name. +// It fails if it overflows the representation of the Go float type. // If the format is "nonfinite", then the JSON strings // "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf. -// Otherwise, the presence of such strings results in a SemanticError. +// Otherwise, the presence of such strings results in a [SemanticError]. // // - A Go map is decoded from a JSON object, // where each JSON object name and value pair is recursively decoded -// as the Go map key and value. When decoding keys, -// UnmarshalOptions.StringifyNumbers is automatically applied so that -// numeric keys can decode from JSON strings. Maps are not cleared. +// as the Go map key and value. Maps are not cleared. // If the Go map is nil, then a new map is allocated to decode into. // If the decoded key matches an existing Go map entry, the entry value // is reused by decoding the JSON object value into it. -// The only supported format is "emitnull" and has no effect when decoding. +// The formats "emitnull" and "emitempty" have no effect when decoding. // // - A Go struct is decoded from a JSON object. // See the “JSON Representation of Go structs” section @@ -395,12 +347,12 @@ func (uo UnmarshalOptions) unmarshalFull(in *Decoder, out any) error { // is recursively decoded and appended to the Go slice. // Before appending into a Go slice, a new slice is allocated if it is nil, // otherwise the slice length is reset to zero. -// The only supported format is "emitnull" and has no effect when decoding. +// The formats "emitnull" and "emitempty" have no effect when decoding. // // - A Go array is decoded from a JSON array, where each JSON array element // is recursively decoded as each corresponding Go array element. // Each Go array element is zeroed before decoding into it. -// It fails with a SemanticError if the JSON array does not contain +// It fails with a [SemanticError] if the JSON array does not contain // the exact same number of elements as the Go array. // It does not support any custom format flags. // @@ -415,59 +367,133 @@ func (uo UnmarshalOptions) unmarshalFull(in *Decoder, out any) error { // Otherwise, a nil interface value of an empty interface type is initialized // with a zero Go bool, string, float64, map[string]any, or []any if the // input is a JSON boolean, string, number, object, or array, respectively. -// If the interface value is still nil, then this fails with a SemanticError +// If the interface value is still nil, then this fails with a [SemanticError] // since decoding could not determine an appropriate Go type to decode into. // For example, unmarshaling into a nil io.Reader fails since // there is no concrete type to populate the interface value with. // Otherwise an underlying value exists and it recursively decodes // the JSON input into it. It does not support any custom format flags. // -// - A Go time.Time is decoded from a JSON string containing the time -// formatted in RFC 3339 with nanosecond resolution. +// - A Go [time.Time] is decoded from a JSON string containing the time +// formatted in RFC 3339 with nanosecond precision. // If the format matches one of the format constants declared in // the time package (e.g., RFC1123), then that format is used for parsing. -// Otherwise, the format is used as-is with time.Time.Parse if non-empty. -// -// - A Go time.Duration is decoded from a JSON string by -// passing the decoded string to time.ParseDuration. -// If the format is "nanos", it is instead decoded from a JSON number -// containing the number of nanoseconds in the duration. +// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", +// then the timestamp is decoded from an optionally fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds) +// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. +// Otherwise, the format is used as-is with [time.Time.Parse] if non-empty. +// +// - A Go [time.Duration] currently has no default representation and +// requires an explicit format to be specified. +// If the format is "sec", "milli", "micro", or "nano", +// then the duration is decoded from an optionally fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds). +// If the format is "units", it is decoded from a JSON string parsed using +// [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes). +// If the format is "iso8601", it is decoded from a JSON string using the +// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) +// accepting only accurate units of hours, minutes, or seconds. // // - All other Go types (e.g., complex numbers, channels, and functions) -// have no default representation and result in a SemanticError. +// have no default representation and result in a [SemanticError]. // // In general, unmarshaling follows merge semantics (similar to RFC 7396) // where the decoded Go value replaces the destination value // for any JSON kind other than an object. // For JSON objects, the input object is merged into the destination value // where matching object members recursively apply merge semantics. -func (uo UnmarshalOptions) UnmarshalNext(in *Decoder, out any) error { +func Unmarshal(in []byte, out any, opts ...Options) (err error) { + dec := export.GetBufferedDecoder(in, opts...) + defer export.PutBufferedDecoder(dec) + xd := export.Decoder(dec) + err = unmarshalDecode(dec, out, &xd.Struct, true) + if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.TransformUnmarshalError(out, err) + } + return err +} + +// UnmarshalRead deserializes a Go value from an [io.Reader] according to the +// provided unmarshal and decode options (while ignoring marshal or encode options). +// The input must be a single JSON value with optional whitespace interspersed. +// It consumes the entirety of [io.Reader] until [io.EOF] is encountered, +// without reporting an error for EOF. The output must be a non-nil pointer. +// See [Unmarshal] for details about the conversion of JSON into a Go value. +func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) { + dec := export.GetStreamingDecoder(in, opts...) + defer export.PutStreamingDecoder(dec) + xd := export.Decoder(dec) + err = unmarshalDecode(dec, out, &xd.Struct, true) + if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.TransformUnmarshalError(out, err) + } + return err +} + +// UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to +// the provided unmarshal options (while ignoring marshal, encode, or decode options). +// Any unmarshal options already specified on the [jsontext.Decoder] +// take lower precedence than the set of options provided by the caller. +// Unlike [Unmarshal] and [UnmarshalRead], decode options are ignored because +// they must have already been specified on the provided [jsontext.Decoder]. +// +// The input may be a stream of one or more JSON values, +// where this only unmarshals the next JSON value in the stream. +// The output must be a non-nil pointer. +// See [Unmarshal] for details about the conversion of JSON into a Go value. +func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error) { + xd := export.Decoder(in) + if len(opts) > 0 { + optsOriginal := xd.Struct + defer func() { xd.Struct = optsOriginal }() + xd.Struct.JoinWithoutCoderOptions(opts...) + } + err = unmarshalDecode(in, out, &xd.Struct, false) + if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.TransformUnmarshalError(out, err) + } + return err +} + +func unmarshalDecode(in *jsontext.Decoder, out any, uo *jsonopts.Struct, last bool) (err error) { v := reflect.ValueOf(out) - if !v.IsValid() || v.Kind() != reflect.Pointer || v.IsNil() { - var t reflect.Type - if v.IsValid() { - t = v.Type() - if t.Kind() == reflect.Pointer { - t = t.Elem() + if v.Kind() != reflect.Pointer || v.IsNil() { + return &SemanticError{action: "unmarshal", GoType: reflect.TypeOf(out), Err: internal.ErrNonNilReference} + } + va := addressableValue{v.Elem(), false} // dereferenced pointer is always addressable + t := va.Type() + + // In legacy semantics, the entirety of the next JSON value + // was validated before attempting to unmarshal it. + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + if err := export.Decoder(in).CheckNextValue(last); err != nil { + if err == io.EOF && last { + offset := in.InputOffset() + int64(len(in.UnreadBuffer())) + return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF} } + return err } - err := errors.New("value must be passed as a non-nil pointer reference") - return &SemanticError{action: "unmarshal", GoType: t, Err: err} } - va := addressableValue{v.Elem()} // dereferenced pointer is always addressable - t := va.Type() // Lookup and call the unmarshal function for this type. unmarshal := lookupArshaler(t).unmarshal if uo.Unmarshalers != nil { - unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t) + unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t) } - if err := unmarshal(uo, in, va); err != nil { - if !in.options.AllowDuplicateNames { - in.tokens.invalidateDisabledNamespaces() + if err := unmarshal(in, va, uo); err != nil { + if !uo.Flags.Get(jsonflags.AllowDuplicateNames) { + export.Decoder(in).Tokens.InvalidateDisabledNamespaces() + } + if err == io.EOF && last { + offset := in.InputOffset() + int64(len(in.UnreadBuffer())) + return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF} } return err } + if last { + return export.Decoder(in).CheckEOF() + } return nil } @@ -477,17 +503,31 @@ func (uo UnmarshalOptions) UnmarshalNext(in *Decoder, out any) error { // There is no compile magic that enforces this property, // but rather the need to construct this type makes it easier to examine each // construction site to ensure that this property is upheld. -type addressableValue struct{ reflect.Value } +type addressableValue struct { + reflect.Value + + // forcedAddr reports whether this value is addressable + // only through the use of [newAddressableValue]. + // This is only used for [jsonflags.CallMethodsWithLegacySemantics]. + forcedAddr bool +} // newAddressableValue constructs a new addressable value of type t. func newAddressableValue(t reflect.Type) addressableValue { - return addressableValue{reflect.New(t).Elem()} + return addressableValue{reflect.New(t).Elem(), true} } +// TODO: Remove *jsonopts.Struct argument from [marshaler] and [unmarshaler]. +// This can be directly accessed on the encoder or decoder. + // All marshal and unmarshal behavior is implemented using these signatures. +// The *jsonopts.Struct argument is guaranteed to identical to or at least +// a strict super-set of the options in Encoder.Struct or Decoder.Struct. +// It is identical for Marshal, Unmarshal, MarshalWrite, and UnmarshalRead. +// It is a super-set for MarshalEncode and UnmarshalDecode. type ( - marshaler = func(MarshalOptions, *Encoder, addressableValue) error - unmarshaler = func(UnmarshalOptions, *Decoder, addressableValue) error + marshaler = func(*jsontext.Encoder, addressableValue, *jsonopts.Struct) error + unmarshaler = func(*jsontext.Decoder, addressableValue, *jsonopts.Struct) error ) type arshaler struct { @@ -511,3 +551,28 @@ func lookupArshaler(t reflect.Type) *arshaler { v, _ := lookupArshalerCache.LoadOrStore(t, fncs) return v.(*arshaler) } + +var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }} + +type stringSlice []string + +// getStrings returns a non-nil pointer to a slice with length n. +func getStrings(n int) *stringSlice { + s := stringsPools.Get().(*stringSlice) + if cap(*s) < n { + *s = make([]string, n) + } + *s = (*s)[:n] + return s +} + +func putStrings(s *stringSlice) { + if cap(*s) > 1<<10 { + *s = nil // avoid pinning arbitrarily large amounts of memory + } + stringsPools.Put(s) +} + +func (ss *stringSlice) Sort() { + slices.SortFunc(*ss, func(x, y string) int { return strings.Compare(x, y) }) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go index c62b1f32..fd034c1a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go @@ -4,47 +4,69 @@ package json -import "reflect" +import ( + "cmp" + "math" + "reflect" + "strconv" -// This files contains an optimized marshal and unmarshal implementation + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" +) + +// This file contains an optimized marshal and unmarshal implementation // for the any type. This type is often used when the Go program has // no knowledge of the JSON schema. This is a common enough occurrence // to justify the complexity of adding logic for this. -func marshalValueAny(mo MarshalOptions, enc *Encoder, val any) error { +// marshalValueAny marshals a Go any as a JSON value. +// This assumes that there are no special formatting directives +// for any possible nested value. +func marshalValueAny(enc *jsontext.Encoder, val any, mo *jsonopts.Struct) error { switch val := val.(type) { case nil: - return enc.WriteToken(Null) + return enc.WriteToken(jsontext.Null) case bool: - return enc.WriteToken(Bool(val)) + return enc.WriteToken(jsontext.Bool(val)) case string: - return enc.WriteToken(String(val)) + return enc.WriteToken(jsontext.String(val)) case float64: - return enc.WriteToken(Float(val)) + if math.IsNaN(val) || math.IsInf(val, 0) { + break // use default logic below + } + return enc.WriteToken(jsontext.Float(val)) case map[string]any: - return marshalObjectAny(mo, enc, val) + return marshalObjectAny(enc, val, mo) case []any: - return marshalArrayAny(mo, enc, val) - default: - v := newAddressableValue(reflect.TypeOf(val)) - v.Set(reflect.ValueOf(val)) - marshal := lookupArshaler(v.Type()).marshal - if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, v.Type()) - } - return marshal(mo, enc, v) + return marshalArrayAny(enc, val, mo) } + + v := newAddressableValue(reflect.TypeOf(val)) + v.Set(reflect.ValueOf(val)) + marshal := lookupArshaler(v.Type()).marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, v.Type()) + } + return marshal(enc, v, mo) } -func unmarshalValueAny(uo UnmarshalOptions, dec *Decoder) (any, error) { +// unmarshalValueAny unmarshals a JSON value as a Go any. +// This assumes that there are no special formatting directives +// for any possible nested value. +// Duplicate names must be rejected since this does not implement merging. +func unmarshalValueAny(dec *jsontext.Decoder, uo *jsonopts.Struct) (any, error) { switch k := dec.PeekKind(); k { case '{': - return unmarshalObjectAny(uo, dec) + return unmarshalObjectAny(dec, uo) case '[': - return unmarshalArrayAny(uo, dec) + return unmarshalArrayAny(dec, uo) default: - var flags valueFlags - val, err := dec.readValue(&flags) + xd := export.Decoder(dec) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { return nil, err } @@ -56,13 +78,19 @@ func unmarshalValueAny(uo UnmarshalOptions, dec *Decoder) (any, error) { case 't': return true, nil case '"': - val = unescapeStringMayCopy(val, flags.isVerbatim()) - if dec.stringCache == nil { - dec.stringCache = new(stringCache) + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + if xd.StringCache == nil { + xd.StringCache = new(stringCache) } - return dec.stringCache.make(val), nil + return makeString(xd.StringCache, val), nil case '0': - fv, _ := parseFloat(val, 64) // ignore error since readValue guarantees val is valid + if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) { + return internal.RawNumberOf(val), nil + } + fv, ok := jsonwire.ParseFloat(val, 64) + if !ok { + return fv, newUnmarshalErrorAfterWithValue(dec, float64Type, strconv.ErrRange) + } return fv, nil default: panic("BUG: invalid kind: " + k.String()) @@ -70,41 +98,49 @@ func unmarshalValueAny(uo UnmarshalOptions, dec *Decoder) (any, error) { } } -func marshalObjectAny(mo MarshalOptions, enc *Encoder, obj map[string]any) error { +// marshalObjectAny marshals a Go map[string]any as a JSON object +// (or as a JSON null if nil and [jsonflags.FormatNilMapAsNull]). +func marshalObjectAny(enc *jsontext.Encoder, obj map[string]any, mo *jsonopts.Struct) error { // Check for cycles. - if enc.tokens.depth() > startDetectingCyclesAfter { + xe := export.Encoder(enc) + if xe.Tokens.Depth() > startDetectingCyclesAfter { v := reflect.ValueOf(obj) - if err := enc.seenPointers.visit(v); err != nil { - return err + if err := visitPointer(&xe.SeenPointers, v); err != nil { + return newMarshalErrorBefore(enc, mapStringAnyType, err) } - defer enc.seenPointers.leave(v) + defer leavePointer(&xe.SeenPointers, v) } - // Optimize for marshaling an empty map without any preceding whitespace. - if len(obj) == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, '{') - enc.buf = append(enc.buf, "{}"...) - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + // Handle empty maps. + if len(obj) == 0 { + if mo.Flags.Get(jsonflags.FormatNilMapAsNull) && obj == nil { + return enc.WriteToken(jsontext.Null) + } + // Optimize for marshaling an empty map without any preceding whitespace. + if !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '{'), "{}"...) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() + } + return nil } - return nil } - if err := enc.WriteToken(ObjectStart); err != nil { + if err := enc.WriteToken(jsontext.BeginObject); err != nil { return err } // A Go map guarantees that each entry has a unique key // The only possibility of duplicates is due to invalid UTF-8. - if !enc.options.AllowInvalidUTF8 { - enc.tokens.last.disableNamespace() + if !mo.Flags.Get(jsonflags.AllowInvalidUTF8) { + xe.Tokens.Last.DisableNamespace() } - if !mo.Deterministic || len(obj) <= 1 { + if !mo.Flags.Get(jsonflags.Deterministic) || len(obj) <= 1 { for name, val := range obj { - if err := enc.WriteToken(String(name)); err != nil { + if err := enc.WriteToken(jsontext.String(name)); err != nil { return err } - if err := marshalValueAny(mo, enc, val); err != nil { + if err := marshalValueAny(enc, val, mo); err != nil { return err } } @@ -117,122 +153,133 @@ func marshalObjectAny(mo MarshalOptions, enc *Encoder, obj map[string]any) error } names.Sort() for _, name := range *names { - if err := enc.WriteToken(String(name)); err != nil { + if err := enc.WriteToken(jsontext.String(name)); err != nil { return err } - if err := marshalValueAny(mo, enc, obj[name]); err != nil { + if err := marshalValueAny(enc, obj[name], mo); err != nil { return err } } putStrings(names) } - if err := enc.WriteToken(ObjectEnd); err != nil { + if err := enc.WriteToken(jsontext.EndObject); err != nil { return err } return nil } -func unmarshalObjectAny(uo UnmarshalOptions, dec *Decoder) (map[string]any, error) { - tok, err := dec.ReadToken() - if err != nil { +// unmarshalObjectAny unmarshals a JSON object as a Go map[string]any. +// It panics if not decoding a JSON object. +func unmarshalObjectAny(dec *jsontext.Decoder, uo *jsonopts.Struct) (map[string]any, error) { + switch tok, err := dec.ReadToken(); { + case err != nil: return nil, err + case tok.Kind() != '{': + panic("BUG: invalid kind: " + tok.Kind().String()) } - k := tok.Kind() - switch k { - case 'n': - return nil, nil - case '{': - obj := make(map[string]any) - // A Go map guarantees that each entry has a unique key - // The only possibility of duplicates is due to invalid UTF-8. - if !dec.options.AllowInvalidUTF8 { - dec.tokens.last.disableNamespace() - } - for dec.PeekKind() != '}' { - tok, err := dec.ReadToken() - if err != nil { - return obj, err - } - name := tok.String() + obj := make(map[string]any) + // A Go map guarantees that each entry has a unique key + // The only possibility of duplicates is due to invalid UTF-8. + if !uo.Flags.Get(jsonflags.AllowInvalidUTF8) { + export.Decoder(dec).Tokens.Last.DisableNamespace() + } + var errUnmarshal error + for dec.PeekKind() != '}' { + tok, err := dec.ReadToken() + if err != nil { + return obj, err + } + name := tok.String() - // Manually check for duplicate names. - if _, ok := obj[name]; ok { - name := dec.previousBuffer() - err := &SyntacticError{str: "duplicate name " + string(name) + " in object"} - return obj, err.withOffset(dec.InputOffset() - int64(len(name))) - } + // Manually check for duplicate names. + if _, ok := obj[name]; ok { + // TODO: Unread the object name. + name := export.Decoder(dec).PreviousTokenOrValue() + err := newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(name)) + return obj, err + } - val, err := unmarshalValueAny(uo, dec) - obj[name] = val - if err != nil { + val, err := unmarshalValueAny(dec, uo) + obj[name] = val + if err != nil { + if isFatalError(err, uo.Flags) { return obj, err } + errUnmarshal = cmp.Or(err, errUnmarshal) } - if _, err := dec.ReadToken(); err != nil { - return obj, err - } - return obj, nil } - return nil, &SemanticError{action: "unmarshal", JSONKind: k, GoType: mapStringAnyType} + if _, err := dec.ReadToken(); err != nil { + return obj, err + } + return obj, errUnmarshal } -func marshalArrayAny(mo MarshalOptions, enc *Encoder, arr []any) error { +// marshalArrayAny marshals a Go []any as a JSON array +// (or as a JSON null if nil and [jsonflags.FormatNilSliceAsNull]). +func marshalArrayAny(enc *jsontext.Encoder, arr []any, mo *jsonopts.Struct) error { // Check for cycles. - if enc.tokens.depth() > startDetectingCyclesAfter { + xe := export.Encoder(enc) + if xe.Tokens.Depth() > startDetectingCyclesAfter { v := reflect.ValueOf(arr) - if err := enc.seenPointers.visit(v); err != nil { - return err + if err := visitPointer(&xe.SeenPointers, v); err != nil { + return newMarshalErrorBefore(enc, sliceAnyType, err) } - defer enc.seenPointers.leave(v) + defer leavePointer(&xe.SeenPointers, v) } - // Optimize for marshaling an empty slice without any preceding whitespace. - if len(arr) == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, '[') - enc.buf = append(enc.buf, "[]"...) - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + // Handle empty slices. + if len(arr) == 0 { + if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && arr == nil { + return enc.WriteToken(jsontext.Null) + } + // Optimize for marshaling an empty slice without any preceding whitespace. + if !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '['), "[]"...) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() + } + return nil } - return nil } - if err := enc.WriteToken(ArrayStart); err != nil { + if err := enc.WriteToken(jsontext.BeginArray); err != nil { return err } for _, val := range arr { - if err := marshalValueAny(mo, enc, val); err != nil { + if err := marshalValueAny(enc, val, mo); err != nil { return err } } - if err := enc.WriteToken(ArrayEnd); err != nil { + if err := enc.WriteToken(jsontext.EndArray); err != nil { return err } return nil } -func unmarshalArrayAny(uo UnmarshalOptions, dec *Decoder) ([]any, error) { - tok, err := dec.ReadToken() - if err != nil { +// unmarshalArrayAny unmarshals a JSON array as a Go []any. +// It panics if not decoding a JSON array. +func unmarshalArrayAny(dec *jsontext.Decoder, uo *jsonopts.Struct) ([]any, error) { + switch tok, err := dec.ReadToken(); { + case err != nil: return nil, err + case tok.Kind() != '[': + panic("BUG: invalid kind: " + tok.Kind().String()) } - k := tok.Kind() - switch k { - case 'n': - return nil, nil - case '[': - arr := []any{} - for dec.PeekKind() != ']' { - val, err := unmarshalValueAny(uo, dec) - arr = append(arr, val) - if err != nil { + arr := []any{} + var errUnmarshal error + for dec.PeekKind() != ']' { + val, err := unmarshalValueAny(dec, uo) + arr = append(arr, val) + if err != nil { + if isFatalError(err, uo.Flags) { return arr, err } + errUnmarshal = cmp.Or(errUnmarshal, err) } - if _, err := dec.ReadToken(); err != nil { - return arr, err - } - return arr, nil } - return nil, &SemanticError{action: "unmarshal", JSONKind: k, GoType: sliceAnyType} + if _, err := dec.ReadToken(); err != nil { + return arr, err + } + return arr, errUnmarshal } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go index fd26eba3..3f21c8d3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go @@ -6,6 +6,8 @@ package json import ( "bytes" + "cmp" + "encoding" "encoding/base32" "encoding/base64" "encoding/hex" @@ -13,9 +15,16 @@ import ( "fmt" "math" "reflect" - "sort" + "slices" "strconv" + "strings" "sync" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // optimizeCommon specifies whether to use optimizations targeted for certain @@ -25,44 +34,56 @@ const optimizeCommon = true var ( // Most natural Go type that correspond with each JSON type. - anyType = reflect.TypeOf((*any)(nil)).Elem() // JSON value - boolType = reflect.TypeOf((*bool)(nil)).Elem() // JSON bool - stringType = reflect.TypeOf((*string)(nil)).Elem() // JSON string - float64Type = reflect.TypeOf((*float64)(nil)).Elem() // JSON number - mapStringAnyType = reflect.TypeOf((*map[string]any)(nil)).Elem() // JSON object - sliceAnyType = reflect.TypeOf((*[]any)(nil)).Elem() // JSON array - - bytesType = reflect.TypeOf((*[]byte)(nil)).Elem() - emptyStructType = reflect.TypeOf((*struct{})(nil)).Elem() + anyType = reflect.TypeFor[any]() // JSON value + boolType = reflect.TypeFor[bool]() // JSON bool + stringType = reflect.TypeFor[string]() // JSON string + float64Type = reflect.TypeFor[float64]() // JSON number + mapStringAnyType = reflect.TypeFor[map[string]any]() // JSON object + sliceAnyType = reflect.TypeFor[[]any]() // JSON array + + bytesType = reflect.TypeFor[[]byte]() + emptyStructType = reflect.TypeFor[struct{}]() ) const startDetectingCyclesAfter = 1000 -type seenPointers map[typedPointer]struct{} +type seenPointers = map[any]struct{} type typedPointer struct { typ reflect.Type ptr any // always stores unsafe.Pointer, but avoids depending on unsafe + len int // remember slice length to avoid false positives } -// visit visits pointer p of type t, reporting an error if seen before. +// visitPointer visits pointer p of type t, reporting an error if seen before. // If successfully visited, then the caller must eventually call leave. -func (m *seenPointers) visit(v reflect.Value) error { - p := typedPointer{v.Type(), v.UnsafePointer()} +func visitPointer(m *seenPointers, v reflect.Value) error { + p := typedPointer{v.Type(), v.UnsafePointer(), sliceLen(v)} if _, ok := (*m)[p]; ok { - return &SemanticError{action: "marshal", GoType: p.typ, Err: errors.New("encountered a cycle")} + return internal.ErrCycle } if *m == nil { - *m = make(map[typedPointer]struct{}) + *m = make(seenPointers) } (*m)[p] = struct{}{} return nil } -func (m *seenPointers) leave(v reflect.Value) { - p := typedPointer{v.Type(), v.UnsafePointer()} +func leavePointer(m *seenPointers, v reflect.Value) { + p := typedPointer{v.Type(), v.UnsafePointer(), sliceLen(v)} delete(*m, p) } +func sliceLen(v reflect.Value) int { + if v.Kind() == reflect.Slice { + return v.Len() + } + return 0 +} + +func len64[Bytes ~[]byte | ~string](in Bytes) int64 { + return int64(len(in)) +} + func makeDefaultArshaler(t reflect.Type) *arshaler { switch t.Kind() { case reflect.Bool: @@ -71,7 +92,7 @@ func makeDefaultArshaler(t reflect.Type) *arshaler { return makeStringArshaler(t) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return makeIntArshaler(t) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return makeUintArshaler(t) case reflect.Float32, reflect.Float64: return makeFloatArshaler(t) @@ -81,13 +102,13 @@ func makeDefaultArshaler(t reflect.Type) *arshaler { return makeStructArshaler(t) case reflect.Slice: fncs := makeSliceArshaler(t) - if t.AssignableTo(bytesType) { + if t.Elem().Kind() == reflect.Uint8 { return makeBytesArshaler(t, fncs) } return fncs case reflect.Array: fncs := makeArrayArshaler(t) - if reflect.SliceOf(t.Elem()).AssignableTo(bytesType) { + if t.Elem().Kind() == reflect.Uint8 { return makeBytesArshaler(t, fncs) } return fncs @@ -102,31 +123,35 @@ func makeDefaultArshaler(t reflect.Type) *arshaler { func makeBoolArshaler(t reflect.Type) *arshaler { var fncs arshaler - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - return newInvalidFormatError("marshal", t, mo.format) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + return newInvalidFormatError(enc, t) } // Optimize for marshaling without preceding whitespace. - if optimizeCommon && !enc.options.multiline && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, 't') - if va.Bool() { - enc.buf = append(enc.buf, "true"...) - } else { - enc.buf = append(enc.buf, "false"...) - } - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = strconv.AppendBool(xe.Tokens.MayAppendDelim(xe.Buf, 't'), va.Bool()) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() } return nil } - return enc.WriteToken(Bool(va.Bool())) + if mo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + if va.Bool() { + return enc.WriteToken(jsontext.String("true")) + } else { + return enc.WriteToken(jsontext.String("false")) + } + } + return enc.WriteToken(jsontext.Bool(va.Bool())) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - return newInvalidFormatError("unmarshal", t, uo.format) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + return newInvalidFormatError(dec, t) } tok, err := dec.ReadToken() if err != nil { @@ -135,187 +160,267 @@ func makeBoolArshaler(t reflect.Type) *arshaler { k := tok.Kind() switch k { case 'n': - va.SetBool(false) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetBool(false) + } return nil case 't', 'f': - va.SetBool(tok.Bool()) - return nil + if !uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + va.SetBool(tok.Bool()) + return nil + } + case '"': + if uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + switch tok.String() { + case "true": + va.SetBool(true) + case "false": + va.SetBool(false) + default: + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && tok.String() == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetBool(false) + } + return nil + } + return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax) + } + return nil + } } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } func makeStringArshaler(t reflect.Type) *arshaler { var fncs arshaler - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - return newInvalidFormatError("marshal", t, mo.format) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + return newInvalidFormatError(enc, t) + } + + // Optimize for marshaling without preceding whitespace. + s := va.String() + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !xe.Tokens.Last.NeedObjectName() { + b := xe.Buf + b = xe.Tokens.MayAppendDelim(b, '"') + b, err := jsonwire.AppendQuote(b, s, &mo.Flags) + if err == nil { + xe.Buf = b + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() + } + return nil + } + // Otherwise, the string contains invalid UTF-8, + // so let the logic below construct the proper error. } - return enc.WriteToken(String(va.String())) + + if mo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + b, err := jsonwire.AppendQuote(nil, s, &mo.Flags) + if err != nil { + return newMarshalErrorBefore(enc, t, &jsontext.SyntacticError{Err: err}) + } + q, err := jsontext.AppendQuote(nil, b) + if err != nil { + panic("BUG: second AppendQuote should never fail: " + err.Error()) + } + return enc.WriteValue(q) + } + return enc.WriteToken(jsontext.String(s)) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - return newInvalidFormatError("unmarshal", t, uo.format) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + return newInvalidFormatError(dec, t) } - var flags valueFlags - val, err := dec.readValue(&flags) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { return err } k := val.Kind() switch k { case 'n': - va.SetString("") + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetString("") + } return nil case '"': - val = unescapeStringMayCopy(val, flags.isVerbatim()) - if dec.stringCache == nil { - dec.stringCache = new(stringCache) + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + if uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + val, err = jsontext.AppendUnquote(nil, val) + if err != nil { + return newUnmarshalErrorAfter(dec, t, err) + } + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetString("") + } + return nil + } + } + if xd.StringCache == nil { + xd.StringCache = new(stringCache) } - str := dec.stringCache.make(val) + str := makeString(xd.StringCache, val) va.SetString(str) return nil } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfter(dec, t, nil) } return &fncs } var ( - encodeBase16 = func(dst, src []byte) { hex.Encode(dst, src) } - encodeBase32 = base32.StdEncoding.Encode - encodeBase32Hex = base32.HexEncoding.Encode - encodeBase64 = base64.StdEncoding.Encode - encodeBase64URL = base64.URLEncoding.Encode - encodedLenBase16 = hex.EncodedLen - encodedLenBase32 = base32.StdEncoding.EncodedLen - encodedLenBase32Hex = base32.HexEncoding.EncodedLen - encodedLenBase64 = base64.StdEncoding.EncodedLen - encodedLenBase64URL = base64.URLEncoding.EncodedLen - decodeBase16 = hex.Decode - decodeBase32 = base32.StdEncoding.Decode - decodeBase32Hex = base32.HexEncoding.Decode - decodeBase64 = base64.StdEncoding.Decode - decodeBase64URL = base64.URLEncoding.Decode - decodedLenBase16 = hex.DecodedLen - decodedLenBase32 = base32.StdEncoding.WithPadding(base32.NoPadding).DecodedLen - decodedLenBase32Hex = base32.HexEncoding.WithPadding(base32.NoPadding).DecodedLen - decodedLenBase64 = base64.StdEncoding.WithPadding(base64.NoPadding).DecodedLen - decodedLenBase64URL = base64.URLEncoding.WithPadding(base64.NoPadding).DecodedLen + appendEncodeBase16 = hex.AppendEncode + appendEncodeBase32 = base32.StdEncoding.AppendEncode + appendEncodeBase32Hex = base32.HexEncoding.AppendEncode + appendEncodeBase64 = base64.StdEncoding.AppendEncode + appendEncodeBase64URL = base64.URLEncoding.AppendEncode + encodedLenBase16 = hex.EncodedLen + encodedLenBase32 = base32.StdEncoding.EncodedLen + encodedLenBase32Hex = base32.HexEncoding.EncodedLen + encodedLenBase64 = base64.StdEncoding.EncodedLen + encodedLenBase64URL = base64.URLEncoding.EncodedLen + appendDecodeBase16 = hex.AppendDecode + appendDecodeBase32 = base32.StdEncoding.AppendDecode + appendDecodeBase32Hex = base32.HexEncoding.AppendDecode + appendDecodeBase64 = base64.StdEncoding.AppendDecode + appendDecodeBase64URL = base64.URLEncoding.AppendDecode ) func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { - // NOTE: This handles both []byte and [N]byte. - marshalDefault := fncs.marshal - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - encode, encodedLen := encodeBase64, encodedLenBase64 - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - switch mo.format { + // NOTE: This handles both []~byte and [N]~byte. + // The v2 default is to treat a []namedByte as equivalent to []T + // since being able to convert []namedByte to []byte relies on + // dubious Go reflection behavior (see https://go.dev/issue/24746). + // For v1 emulation, we use jsonflags.FormatBytesWithLegacySemantics + // to forcibly treat []namedByte as a []byte. + marshalArray := fncs.marshal + isNamedByte := t.Elem().PkgPath() != "" + hasMarshaler := implementsAny(t.Elem(), allMarshalerTypes...) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + if !mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && isNamedByte { + return marshalArray(enc, va, mo) // treat as []T or [N]T + } + xe := export.Encoder(enc) + appendEncode := appendEncodeBase64 + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + switch mo.Format { case "base64": - encode, encodedLen = encodeBase64, encodedLenBase64 + appendEncode = appendEncodeBase64 case "base64url": - encode, encodedLen = encodeBase64URL, encodedLenBase64URL + appendEncode = appendEncodeBase64URL case "base32": - encode, encodedLen = encodeBase32, encodedLenBase32 + appendEncode = appendEncodeBase32 case "base32hex": - encode, encodedLen = encodeBase32Hex, encodedLenBase32Hex + appendEncode = appendEncodeBase32Hex case "base16", "hex": - encode, encodedLen = encodeBase16, encodedLenBase16 + appendEncode = appendEncodeBase16 case "array": - mo.format = "" - return marshalDefault(mo, enc, va) + mo.Format = "" + return marshalArray(enc, va, mo) default: - return newInvalidFormatError("marshal", t, mo.format) + return newInvalidFormatError(enc, t) } + } else if mo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array { + return marshalArray(enc, va, mo) + } else if mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && hasMarshaler { + return marshalArray(enc, va, mo) } - val := enc.UnusedBuffer() - b := va.Bytes() - n := len(`"`) + encodedLen(len(b)) + len(`"`) - if cap(val) < n { - val = make([]byte, n) - } else { - val = val[:n] + if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && va.Kind() == reflect.Slice && va.IsNil() { + // TODO: Provide a "emitempty" format override? + return enc.WriteToken(jsontext.Null) } - val[0] = '"' - encode(val[len(`"`):len(val)-len(`"`)], b) - val[len(val)-1] = '"' - return enc.WriteValue(val) + return xe.AppendRaw('"', true, func(b []byte) ([]byte, error) { + return appendEncode(b, va.Bytes()), nil + }) } - unmarshalDefault := fncs.unmarshal - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - decode, decodedLen, encodedLen := decodeBase64, decodedLenBase64, encodedLenBase64 - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - switch uo.format { + unmarshalArray := fncs.unmarshal + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + if !uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && isNamedByte { + return unmarshalArray(dec, va, uo) // treat as []T or [N]T + } + xd := export.Decoder(dec) + appendDecode, encodedLen := appendDecodeBase64, encodedLenBase64 + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + switch uo.Format { case "base64": - decode, decodedLen, encodedLen = decodeBase64, decodedLenBase64, encodedLenBase64 + appendDecode, encodedLen = appendDecodeBase64, encodedLenBase64 case "base64url": - decode, decodedLen, encodedLen = decodeBase64URL, decodedLenBase64URL, encodedLenBase64URL + appendDecode, encodedLen = appendDecodeBase64URL, encodedLenBase64URL case "base32": - decode, decodedLen, encodedLen = decodeBase32, decodedLenBase32, encodedLenBase32 + appendDecode, encodedLen = appendDecodeBase32, encodedLenBase32 case "base32hex": - decode, decodedLen, encodedLen = decodeBase32Hex, decodedLenBase32Hex, encodedLenBase32Hex + appendDecode, encodedLen = appendDecodeBase32Hex, encodedLenBase32Hex case "base16", "hex": - decode, decodedLen, encodedLen = decodeBase16, decodedLenBase16, encodedLenBase16 + appendDecode, encodedLen = appendDecodeBase16, encodedLenBase16 case "array": - uo.format = "" - return unmarshalDefault(uo, dec, va) + uo.Format = "" + return unmarshalArray(dec, va, uo) default: - return newInvalidFormatError("unmarshal", t, uo.format) + return newInvalidFormatError(dec, t) } + } else if uo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array { + return unmarshalArray(dec, va, uo) + } else if uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && dec.PeekKind() == '[' { + return unmarshalArray(dec, va, uo) } - var flags valueFlags - val, err := dec.readValue(&flags) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { return err } k := val.Kind() switch k { case 'n': - va.Set(reflect.Zero(t)) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) || va.Kind() != reflect.Array { + va.SetZero() + } return nil case '"': - val = unescapeStringMayCopy(val, flags.isVerbatim()) - - // For base64 and base32, decodedLen computes the maximum output size - // when given the original input size. To compute the exact size, - // adjust the input size by excluding trailing padding characters. - // This is unnecessary for base16, but also harmless. - n := len(val) - for n > 0 && val[n-1] == '=' { - n-- - } - n = decodedLen(n) - b := va.Bytes() - if va.Kind() == reflect.Array { - if n != len(b) { - err := fmt.Errorf("decoded base64 length of %d mismatches array length of %d", n, len(b)) - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} - } - } else { - if b == nil || cap(b) < n { - b = make([]byte, n) - } else { - b = b[:n] - } + // NOTE: The v2 default is to strictly comply with RFC 4648. + // Section 3.2 specifies that padding is required. + // Section 3.3 specifies that non-alphabet characters + // (e.g., '\r' or '\n') must be rejected. + // Section 3.5 specifies that unnecessary non-zero bits in + // the last quantum may be rejected. Since this is optional, + // we do not reject such inputs. + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + b, err := appendDecode(va.Bytes()[:0], val) + if err != nil { + return newUnmarshalErrorAfter(dec, t, err) } - n2, err := decode(b, val) - if err == nil && len(val) != encodedLen(n2) { + if len(val) != encodedLen(len(b)) && !uo.Flags.Get(jsonflags.ParseBytesWithLooseRFC4648) { // TODO(https://go.dev/issue/53845): RFC 4648, section 3.3, // specifies that non-alphabet characters must be rejected. // Unfortunately, the "base32" and "base64" packages allow // '\r' and '\n' characters by default. - err = errors.New("illegal data at input byte " + strconv.Itoa(bytes.IndexAny(val, "\r\n"))) - } - if err != nil { - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + i := bytes.IndexAny(val, "\r\n") + err := fmt.Errorf("illegal character %s at offset %d", jsonwire.QuoteRune(val[i:]), i) + return newUnmarshalErrorAfter(dec, t, err) } - if va.Kind() == reflect.Slice { + + if va.Kind() == reflect.Array { + dst := va.Bytes() + clear(dst[copy(dst, b):]) // noop if len(b) <= len(dst) + if len(b) != len(dst) && !uo.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) { + err := fmt.Errorf("decoded length of %d mismatches array length of %d", len(b), len(dst)) + return newUnmarshalErrorAfter(dec, t, err) + } + } else { + if b == nil { + b = []byte{} + } va.SetBytes(b) } return nil } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfter(dec, t, nil) } return fncs } @@ -323,64 +428,77 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { func makeIntArshaler(t reflect.Type) *arshaler { var fncs arshaler bits := t.Bits() - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - return newInvalidFormatError("marshal", t, mo.format) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + return newInvalidFormatError(enc, t) } // Optimize for marshaling without preceding whitespace or string escaping. - if optimizeCommon && !enc.options.multiline && !mo.StringifyNumbers && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, '0') - enc.buf = strconv.AppendInt(enc.buf, va.Int(), 10) - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = strconv.AppendInt(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Int(), 10) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() } return nil } - x := math.Float64frombits(uint64(va.Int())) - return enc.writeNumber(x, rawIntNumber, mo.StringifyNumbers) + k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) { + return strconv.AppendInt(b, va.Int(), 10), nil + }) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - return newInvalidFormatError("unmarshal", t, uo.format) - } - var flags valueFlags - val, err := dec.readValue(&flags) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + return newInvalidFormatError(dec, t) + } + stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { return err } k := val.Kind() switch k { case 'n': - va.SetInt(0) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetInt(0) + } return nil case '"': - if !uo.StringifyNumbers { + if !stringify { break } - val = unescapeStringMayCopy(val, flags.isVerbatim()) + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetInt(0) + } + return nil + } fallthrough case '0': + if stringify && k == '0' { + break + } var negOffset int - neg := val[0] == '-' + neg := len(val) > 0 && val[0] == '-' if neg { negOffset = 1 } - n, ok := parseDecUint(val[negOffset:]) + n, ok := jsonwire.ParseUint(val[negOffset:]) maxInt := uint64(1) << (bits - 1) overflow := (neg && n > maxInt) || (!neg && n > maxInt-1) if !ok { if n != math.MaxUint64 { - err := fmt.Errorf("cannot parse %q as signed integer: %w", val, strconv.ErrSyntax) - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax) } overflow = true } if overflow { - err := fmt.Errorf("cannot parse %q as signed integer: %w", val, strconv.ErrRange) - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange) } if neg { va.SetInt(int64(-n)) @@ -389,7 +507,7 @@ func makeIntArshaler(t reflect.Type) *arshaler { } return nil } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfter(dec, t, nil) } return &fncs } @@ -397,64 +515,77 @@ func makeIntArshaler(t reflect.Type) *arshaler { func makeUintArshaler(t reflect.Type) *arshaler { var fncs arshaler bits := t.Bits() - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - return newInvalidFormatError("marshal", t, mo.format) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + return newInvalidFormatError(enc, t) } // Optimize for marshaling without preceding whitespace or string escaping. - if optimizeCommon && !enc.options.multiline && !mo.StringifyNumbers && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, '0') - enc.buf = strconv.AppendUint(enc.buf, va.Uint(), 10) - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = strconv.AppendUint(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Uint(), 10) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() } return nil } - x := math.Float64frombits(va.Uint()) - return enc.writeNumber(x, rawUintNumber, mo.StringifyNumbers) + k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) { + return strconv.AppendUint(b, va.Uint(), 10), nil + }) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - return newInvalidFormatError("unmarshal", t, uo.format) - } - var flags valueFlags - val, err := dec.readValue(&flags) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + return newInvalidFormatError(dec, t) + } + stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { return err } k := val.Kind() switch k { case 'n': - va.SetUint(0) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetUint(0) + } return nil case '"': - if !uo.StringifyNumbers { + if !stringify { break } - val = unescapeStringMayCopy(val, flags.isVerbatim()) + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetUint(0) + } + return nil + } fallthrough case '0': - n, ok := parseDecUint(val) + if stringify && k == '0' { + break + } + n, ok := jsonwire.ParseUint(val) maxUint := uint64(1) << bits overflow := n > maxUint-1 if !ok { if n != math.MaxUint64 { - err := fmt.Errorf("cannot parse %q as unsigned integer: %w", val, strconv.ErrSyntax) - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax) } overflow = true } if overflow { - err := fmt.Errorf("cannot parse %q as unsigned integer: %w", val, strconv.ErrRange) - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange) } va.SetUint(n) return nil } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfter(dec, t, nil) } return &fncs } @@ -462,59 +593,66 @@ func makeUintArshaler(t reflect.Type) *arshaler { func makeFloatArshaler(t reflect.Type) *arshaler { var fncs arshaler bits := t.Bits() - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) var allowNonFinite bool - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - if mo.format == "nonfinite" { + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + if mo.Format == "nonfinite" { allowNonFinite = true } else { - return newInvalidFormatError("marshal", t, mo.format) + return newInvalidFormatError(enc, t) } } fv := va.Float() if math.IsNaN(fv) || math.IsInf(fv, 0) { if !allowNonFinite { - err := fmt.Errorf("invalid value: %v", fv) - return &SemanticError{action: "marshal", GoType: t, Err: err} + err := fmt.Errorf("unsupported value: %v", fv) + return newMarshalErrorBefore(enc, t, err) } - return enc.WriteToken(Float(fv)) + return enc.WriteToken(jsontext.Float(fv)) } // Optimize for marshaling without preceding whitespace or string escaping. - if optimizeCommon && !enc.options.multiline && !mo.StringifyNumbers && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, '0') - enc.buf = appendNumber(enc.buf, fv, bits) - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = jsonwire.AppendFloat(xe.Tokens.MayAppendDelim(xe.Buf, '0'), fv, bits) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() } return nil } - return enc.writeNumber(fv, bits, mo.StringifyNumbers) + k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) { + return jsonwire.AppendFloat(b, va.Float(), bits), nil + }) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) var allowNonFinite bool - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - if uo.format == "nonfinite" { + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + if uo.Format == "nonfinite" { allowNonFinite = true } else { - return newInvalidFormatError("unmarshal", t, uo.format) + return newInvalidFormatError(dec, t) } } - var flags valueFlags - val, err := dec.readValue(&flags) + stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { return err } k := val.Kind() switch k { case 'n': - va.SetFloat(0) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetFloat(0) + } return nil case '"': - val = unescapeStringMayCopy(val, flags.isVerbatim()) + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) if allowNonFinite { switch string(val) { case "NaN": @@ -528,24 +666,31 @@ func makeFloatArshaler(t reflect.Type) *arshaler { return nil } } - if !uo.StringifyNumbers { + if !stringify { break } - if n, err := consumeNumber(val); n != len(val) || err != nil { - err := fmt.Errorf("cannot parse %q as JSON number: %w", val, strconv.ErrSyntax) - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetFloat(0) + } + return nil + } + if n, err := jsonwire.ConsumeNumber(val); n != len(val) || err != nil { + return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrSyntax) } fallthrough case '0': - // NOTE: Floating-point parsing is by nature a lossy operation. - // We never report an overflow condition since we can always - // round the input to the closest representable finite value. - // For extremely large numbers, the closest value is ±MaxFloat. - fv, _ := parseFloat(val, bits) + if stringify && k == '0' { + break + } + fv, ok := jsonwire.ParseFloat(val, bits) va.SetFloat(fv) + if !ok { + return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange) + } return nil } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfter(dec, t, nil) } return &fncs } @@ -568,54 +713,61 @@ func makeMapArshaler(t reflect.Type) *arshaler { keyFncs = lookupArshaler(t.Key()) valFncs = lookupArshaler(t.Elem()) } - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + nillableLegacyKey := t.Key().Kind() == reflect.Pointer && + implementsAny(t.Key(), textMarshalerType, textAppenderType) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { // Check for cycles. - if enc.tokens.depth() > startDetectingCyclesAfter { - if err := enc.seenPointers.visit(va.Value); err != nil { - return err - } - defer enc.seenPointers.leave(va.Value) - } - - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - if mo.format == "emitnull" { - if va.IsNil() { - return enc.WriteToken(Null) - } - mo.format = "" - } else { - return newInvalidFormatError("marshal", t, mo.format) + xe := export.Encoder(enc) + if xe.Tokens.Depth() > startDetectingCyclesAfter { + if err := visitPointer(&xe.SeenPointers, va.Value); err != nil { + return newMarshalErrorBefore(enc, t, err) + } + defer leavePointer(&xe.SeenPointers, va.Value) + } + + emitNull := mo.Flags.Get(jsonflags.FormatNilMapAsNull) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + switch mo.Format { + case "emitnull": + emitNull = true + mo.Format = "" + case "emitempty": + emitNull = false + mo.Format = "" + default: + return newInvalidFormatError(enc, t) } } - // Optimize for marshaling an empty map without any preceding whitespace. + // Handle empty maps. n := va.Len() - if optimizeCommon && n == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, '{') - enc.buf = append(enc.buf, "{}"...) - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + if n == 0 { + if emitNull && va.IsNil() { + return enc.WriteToken(jsontext.Null) + } + // Optimize for marshaling an empty map without any preceding whitespace. + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '{'), "{}"...) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() + } + return nil } - return nil } once.Do(init) - if err := enc.WriteToken(ObjectStart); err != nil { + if err := enc.WriteToken(jsontext.BeginObject); err != nil { return err } if n > 0 { - // Handle maps with numeric key types by stringifying them. - mko := mo - mko.StringifyNumbers = true - nonDefaultKey := keyFncs.nonDefault marshalKey := keyFncs.marshal marshalVal := valFncs.marshal if mo.Marshalers != nil { var ok bool - marshalKey, ok = mo.Marshalers.lookup(marshalKey, t.Key()) - marshalVal, _ = mo.Marshalers.lookup(marshalVal, t.Elem()) + marshalKey, ok = mo.Marshalers.(*Marshalers).lookup(marshalKey, t.Key()) + marshalVal, _ = mo.Marshalers.(*Marshalers).lookup(marshalVal, t.Elem()) nonDefaultKey = nonDefaultKey || ok } k := newAddressableValue(t.Key()) @@ -624,22 +776,29 @@ func makeMapArshaler(t reflect.Type) *arshaler { // A Go map guarantees that each entry has a unique key. // As such, disable the expensive duplicate name check if we know // that every Go key will serialize as a unique JSON string. - if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), enc.options.AllowInvalidUTF8) { - enc.tokens.last.disableNamespace() + if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), mo.Flags.Get(jsonflags.AllowInvalidUTF8)) { + xe.Tokens.Last.DisableNamespace() } switch { - case !mo.Deterministic || n <= 1: + case !mo.Flags.Get(jsonflags.Deterministic) || n <= 1: for iter := va.Value.MapRange(); iter.Next(); { k.SetIterKey(iter) - if err := marshalKey(mko, enc, k); err != nil { - // TODO: If err is errMissingName, then wrap it as a - // SemanticError since this key type cannot be serialized - // as a JSON string. - return err + err := marshalKey(enc, k, mo) + if err != nil { + if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + errors.Is(err, jsontext.ErrNonStringName) && nillableLegacyKey && k.IsNil() { + err = enc.WriteToken(jsontext.String("")) + } + if err != nil { + if serr, ok := err.(*jsontext.SyntacticError); ok && serr.Err == jsontext.ErrNonStringName { + err = newMarshalErrorBefore(enc, k.Type(), err) + } + return err + } } v.SetIterValue(iter) - if err := marshalVal(mo, enc, v); err != nil { + if err := marshalVal(enc, v, mo); err != nil { return err } } @@ -651,13 +810,13 @@ func makeMapArshaler(t reflect.Type) *arshaler { } names.Sort() for _, name := range *names { - if err := enc.WriteToken(String(name)); err != nil { + if err := enc.WriteToken(jsontext.String(name)); err != nil { return err } // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. k.SetString(name) v.Set(va.MapIndex(k.Value)) - if err := marshalVal(mo, enc, v); err != nil { + if err := marshalVal(enc, v, mo); err != nil { return err } } @@ -666,52 +825,62 @@ func makeMapArshaler(t reflect.Type) *arshaler { type member struct { name string // unquoted name key addressableValue + val addressableValue } members := make([]member, n) keys := reflect.MakeSlice(reflect.SliceOf(t.Key()), n, n) + vals := reflect.MakeSlice(reflect.SliceOf(t.Elem()), n, n) for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ { // Marshal the member name. - k := addressableValue{keys.Index(i)} // indexed slice element is always addressable + k := addressableValue{keys.Index(i), true} // indexed slice element is always addressable k.SetIterKey(iter) - if err := marshalKey(mko, enc, k); err != nil { - // TODO: If err is errMissingName, then wrap it as a - // SemanticError since this key type cannot be serialized - // as a JSON string. - return err + v := addressableValue{vals.Index(i), true} // indexed slice element is always addressable + v.SetIterValue(iter) + err := marshalKey(enc, k, mo) + if err != nil { + if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + errors.Is(err, jsontext.ErrNonStringName) && nillableLegacyKey && k.IsNil() { + err = enc.WriteToken(jsontext.String("")) + } + if err != nil { + if serr, ok := err.(*jsontext.SyntacticError); ok && serr.Err == jsontext.ErrNonStringName { + err = newMarshalErrorBefore(enc, k.Type(), err) + } + return err + } } - name := enc.unwriteOnlyObjectMemberName() - members[i] = member{name, k} + name := xe.UnwriteOnlyObjectMemberName() + members[i] = member{name, k, v} } // TODO: If AllowDuplicateNames is enabled, then sort according // to reflect.Value as well if the names are equal. // See internal/fmtsort. - // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. - sort.Slice(members, func(i, j int) bool { - return lessUTF16(members[i].name, members[j].name) + slices.SortFunc(members, func(x, y member) int { + return strings.Compare(x.name, y.name) }) for _, member := range members { - if err := enc.WriteToken(String(member.name)); err != nil { + if err := enc.WriteToken(jsontext.String(member.name)); err != nil { return err } - // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. - v.Set(va.MapIndex(member.key.Value)) - if err := marshalVal(mo, enc, v); err != nil { + if err := marshalVal(enc, member.val, mo); err != nil { return err } } } } - if err := enc.WriteToken(ObjectEnd); err != nil { + if err := enc.WriteToken(jsontext.EndObject); err != nil { return err } return nil } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - if uo.format == "emitnull" { - uo.format = "" // only relevant for marshaling - } else { - return newInvalidFormatError("unmarshal", t, uo.format) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + switch uo.Format { + case "emitnull", "emitempty": + uo.Format = "" // only relevant for marshaling + default: + return newInvalidFormatError(dec, t) } } tok, err := dec.ReadToken() @@ -721,7 +890,7 @@ func makeMapArshaler(t reflect.Type) *arshaler { k := tok.Kind() switch k { case 'n': - va.Set(reflect.Zero(t)) + va.SetZero() return nil case '{': once.Do(init) @@ -729,17 +898,13 @@ func makeMapArshaler(t reflect.Type) *arshaler { va.Set(reflect.MakeMap(t)) } - // Handle maps with numeric key types by stringifying them. - uko := uo - uko.StringifyNumbers = true - nonDefaultKey := keyFncs.nonDefault unmarshalKey := keyFncs.unmarshal unmarshalVal := valFncs.unmarshal if uo.Unmarshalers != nil { var ok bool - unmarshalKey, ok = uo.Unmarshalers.lookup(unmarshalKey, t.Key()) - unmarshalVal, _ = uo.Unmarshalers.lookup(unmarshalVal, t.Elem()) + unmarshalKey, ok = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshalKey, t.Key()) + unmarshalVal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshalVal, t.Elem()) nonDefaultKey = nonDefaultKey || ok } k := newAddressableValue(t.Key()) @@ -751,8 +916,8 @@ func makeMapArshaler(t reflect.Type) *arshaler { // will be rejected as duplicates since they semantically refer // to the same Go value. This is an unusual interaction // between syntax and semantics, but is more correct. - if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), dec.options.AllowInvalidUTF8) { - dec.tokens.last.disableNamespace() + if !nonDefaultKey && mapKeyWithUniqueRepresentation(k.Kind(), uo.Flags.Get(jsonflags.AllowInvalidUTF8)) { + xd.Tokens.Last.DisableNamespace() } // In the rare case where the map is not already empty, @@ -760,46 +925,72 @@ func makeMapArshaler(t reflect.Type) *arshaler { // since existing presence alone is insufficient to indicate // whether the input had a duplicate name. var seen reflect.Value - if !dec.options.AllowDuplicateNames && va.Len() > 0 { + if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && va.Len() > 0 { seen = reflect.MakeMap(reflect.MapOf(k.Type(), emptyStructType)) } + var errUnmarshal error for dec.PeekKind() != '}' { - k.Set(reflect.Zero(t.Key())) - if err := unmarshalKey(uko, dec, k); err != nil { - return err + // Unmarshal the map entry key. + k.SetZero() + err := unmarshalKey(dec, k, uo) + if err != nil { + if isFatalError(err, uo.Flags) { + return err + } + if err := dec.SkipValue(); err != nil { + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) + continue } if k.Kind() == reflect.Interface && !k.IsNil() && !k.Elem().Type().Comparable() { - err := fmt.Errorf("invalid incomparable key type %v", k.Elem().Type()) - return &SemanticError{action: "unmarshal", GoType: t, Err: err} + err := newUnmarshalErrorAfter(dec, t, fmt.Errorf("invalid incomparable key type %v", k.Elem().Type())) + if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err + } + if err2 := dec.SkipValue(); err2 != nil { + return err2 + } + errUnmarshal = cmp.Or(errUnmarshal, err) + continue } + // Check if a pre-existing map entry value exists for this key. if v2 := va.MapIndex(k.Value); v2.IsValid() { - if !dec.options.AllowDuplicateNames && (!seen.IsValid() || seen.MapIndex(k.Value).IsValid()) { + if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && (!seen.IsValid() || seen.MapIndex(k.Value).IsValid()) { // TODO: Unread the object name. - name := dec.previousBuffer() - err := &SyntacticError{str: "duplicate name " + string(name) + " in object"} - return err.withOffset(dec.InputOffset() - int64(len(name))) + name := xd.PreviousTokenOrValue() + return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(name)) + } + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + v.Set(v2) + } else { + v.SetZero() } - v.Set(v2) } else { - v.Set(reflect.Zero(v.Type())) + v.SetZero() } - err := unmarshalVal(uo, dec, v) + + // Unmarshal the map entry value. + err = unmarshalVal(dec, v, uo) va.SetMapIndex(k.Value, v.Value) if seen.IsValid() { seen.SetMapIndex(k.Value, reflect.Zero(emptyStructType)) } if err != nil { - return err + if isFatalError(err, uo.Flags) { + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) } } if _, err := dec.ReadToken(); err != nil { return err } - return nil + return errUnmarshal } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -812,7 +1003,7 @@ func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool switch k { case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return true case reflect.String: // For strings, we have to be careful since names with invalid UTF-8 @@ -825,6 +1016,8 @@ func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool } } +var errNilField = errors.New("cannot set embedded pointer to unexported struct type") + func makeStructArshaler(t reflect.Type) *arshaler { // NOTE: The logic below disables namespaces for tracking duplicate names // and does the tracking locally with an efficient bit-set based on which @@ -839,27 +1032,26 @@ func makeStructArshaler(t reflect.Type) *arshaler { init := func() { fields, errInit = makeStructFields(t) } - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - return newInvalidFormatError("marshal", t, mo.format) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + return newInvalidFormatError(enc, t) } once.Do(init) - if errInit != nil { - err := *errInit // shallow copy SemanticError - err.action = "marshal" - return &err + if errInit != nil && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, errInit.GoType, errInit.Err) } - if err := enc.WriteToken(ObjectStart); err != nil { + if err := enc.WriteToken(jsontext.BeginObject); err != nil { return err } var seenIdxs uintSet prevIdx := -1 - enc.tokens.last.disableNamespace() // we manually ensure unique names below + xe.Tokens.Last.DisableNamespace() // we manually ensure unique names below for i := range fields.flattened { f := &fields.flattened[i] - v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable - if len(f.index) > 1 { - v = v.fieldByIndex(f.index[1:], false) + v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable + if len(f.index) > 0 { + v = v.fieldByIndex(f.index, false) if !v.IsValid() { continue // implies a nil inlined field } @@ -867,7 +1059,13 @@ func makeStructArshaler(t reflect.Type) *arshaler { // OmitZero skips the field if the Go value is zero, // which we can determine up front without calling the marshaler. - if f.omitzero && ((f.isZero == nil && v.IsZero()) || (f.isZero != nil && f.isZero(v))) { + if (f.omitzero || mo.Flags.Get(jsonflags.OmitZeroStructFields)) && + ((f.isZero == nil && v.IsZero()) || (f.isZero != nil && f.isZero(v))) { + continue + } + + // Check for the legacy definition of omitempty. + if f.omitempty && mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) && isLegacyEmpty(v) { continue } @@ -875,14 +1073,15 @@ func makeStructArshaler(t reflect.Type) *arshaler { nonDefault := f.fncs.nonDefault if mo.Marshalers != nil { var ok bool - marshal, ok = mo.Marshalers.lookup(marshal, f.typ) + marshal, ok = mo.Marshalers.(*Marshalers).lookup(marshal, f.typ) nonDefault = nonDefault || ok } // OmitEmpty skips the field if the marshaled JSON value is empty, // which we can know up front if there are no custom marshalers, // otherwise we must marshal the value and unwrite it if empty. - if f.omitempty && !nonDefault && f.isEmpty != nil && f.isEmpty(v) { + if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) && + !nonDefault && f.isEmpty != nil && f.isEmpty(v) { continue // fast path for omitempty } @@ -898,50 +1097,60 @@ func makeStructArshaler(t reflect.Type) *arshaler { // 5. There is no possibility of an error occurring. if optimizeCommon { // Append any delimiters or optional whitespace. - if enc.tokens.last.length() > 0 { - enc.buf = append(enc.buf, ',') + b := xe.Buf + if xe.Tokens.Last.Length() > 0 { + b = append(b, ',') + if mo.Flags.Get(jsonflags.SpaceAfterComma) { + b = append(b, ' ') + } } - if enc.options.multiline { - enc.buf = enc.appendIndent(enc.buf, enc.tokens.needIndent('"')) + if mo.Flags.Get(jsonflags.Multiline) { + b = xe.AppendIndent(b, xe.Tokens.NeedIndent('"')) } // Append the token to the output and to the state machine. - n0 := len(enc.buf) // offset before calling appendString - if enc.options.EscapeRune == nil { - enc.buf = append(enc.buf, f.quotedName...) + n0 := len(b) // offset before calling AppendQuote + if !f.nameNeedEscape { + b = append(b, f.quotedName...) } else { - enc.buf, _ = appendString(enc.buf, f.name, false, enc.options.EscapeRune) - } - if !enc.options.AllowDuplicateNames { - enc.names.replaceLastQuotedOffset(n0) + b, _ = jsonwire.AppendQuote(b, f.name, &mo.Flags) } - enc.tokens.last.increment() + xe.Buf = b + xe.Names.ReplaceLastQuotedOffset(n0) + xe.Tokens.Last.Increment() } else { - if err := enc.WriteToken(String(f.name)); err != nil { + if err := enc.WriteToken(jsontext.String(f.name)); err != nil { return err } } // Write the object member value. - mo2 := mo + flagsOriginal := mo.Flags if f.string { - mo2.StringifyNumbers = true + if !mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + mo.Flags.Set(jsonflags.StringifyNumbers | 1) + } else if canLegacyStringify(f.typ) { + mo.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1) + } } if f.format != "" { - mo2.formatDepth = enc.tokens.depth() - mo2.format = f.format + mo.FormatDepth = xe.Tokens.Depth() + mo.Format = f.format } - if err := marshal(mo2, enc, v); err != nil { + err := marshal(enc, v, mo) + mo.Flags = flagsOriginal + mo.Format = "" + if err != nil { return err } // Try unwriting the member if empty (slow path for omitempty). - if f.omitempty { + if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) { var prevName *string if prevIdx >= 0 { prevName = &fields.flattened[prevIdx].name } - if enc.unwriteEmptyObjectMember(prevName) { + if xe.UnwriteEmptyObjectMember(prevName) { continue } } @@ -949,23 +1158,23 @@ func makeStructArshaler(t reflect.Type) *arshaler { // Remember the previous written object member. // The set of seen fields only needs to be updated to detect // duplicate names with those from the inlined fallback. - if !enc.options.AllowDuplicateNames && fields.inlinedFallback != nil { + if !mo.Flags.Get(jsonflags.AllowDuplicateNames) && fields.inlinedFallback != nil { seenIdxs.insert(uint(f.id)) } prevIdx = f.id } - if fields.inlinedFallback != nil && !(mo.DiscardUnknownMembers && fields.inlinedFallback.unknown) { + if fields.inlinedFallback != nil && !(mo.Flags.Get(jsonflags.DiscardUnknownMembers) && fields.inlinedFallback.unknown) { var insertUnquotedName func([]byte) bool - if !enc.options.AllowDuplicateNames { + if !mo.Flags.Get(jsonflags.AllowDuplicateNames) { insertUnquotedName = func(name []byte) bool { // Check that the name from inlined fallback does not match // one of the previously marshaled names from known fields. - if foldedFields := fields.byFoldedName[string(foldName(name))]; len(foldedFields) > 0 { + if foldedFields := fields.lookupByFoldedName(name); len(foldedFields) > 0 { if f := fields.byActualName[string(name)]; f != nil { return seenIdxs.insert(uint(f.id)) } for _, f := range foldedFields { - if f.nocase { + if f.matchFoldedName(name, &mo.Flags) { return seenIdxs.insert(uint(f.id)) } } @@ -973,21 +1182,22 @@ func makeStructArshaler(t reflect.Type) *arshaler { // Check that the name does not match any other name // previously marshaled from the inlined fallback. - return enc.namespaces.last().insertUnquoted(name) + return xe.Namespaces.Last().InsertUnquoted(name) } } - if err := marshalInlinedFallbackAll(mo, enc, va, fields.inlinedFallback, insertUnquotedName); err != nil { + if err := marshalInlinedFallbackAll(enc, va, mo, fields.inlinedFallback, insertUnquotedName); err != nil { return err } } - if err := enc.WriteToken(ObjectEnd); err != nil { + if err := enc.WriteToken(jsontext.EndObject); err != nil { return err } return nil } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - return newInvalidFormatError("unmarshal", t, uo.format) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + return newInvalidFormatError(dec, t) } tok, err := dec.ReadToken() if err != nil { @@ -996,41 +1206,45 @@ func makeStructArshaler(t reflect.Type) *arshaler { k := tok.Kind() switch k { case 'n': - va.Set(reflect.Zero(t)) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetZero() + } return nil case '{': once.Do(init) - if errInit != nil { - err := *errInit // shallow copy SemanticError - err.action = "unmarshal" - return &err + if errInit != nil && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorAfter(dec, errInit.GoType, errInit.Err) } var seenIdxs uintSet - dec.tokens.last.disableNamespace() + xd.Tokens.Last.DisableNamespace() + var errUnmarshal error for dec.PeekKind() != '}' { // Process the object member name. - var flags valueFlags - val, err := dec.readValue(&flags) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { return err } - name := unescapeStringMayCopy(val, flags.isVerbatim()) + name := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) f := fields.byActualName[string(name)] if f == nil { - for _, f2 := range fields.byFoldedName[string(foldName(name))] { - if f2.nocase { + for _, f2 := range fields.lookupByFoldedName(name) { + if f2.matchFoldedName(name, &uo.Flags) { f = f2 break } } if f == nil { - if uo.RejectUnknownMembers && (fields.inlinedFallback == nil || fields.inlinedFallback.unknown) { - return &SemanticError{action: "unmarshal", GoType: t, Err: fmt.Errorf("unknown name %s", val)} + if uo.Flags.Get(jsonflags.RejectUnknownMembers) && (fields.inlinedFallback == nil || fields.inlinedFallback.unknown) { + err := newUnmarshalErrorAfter(dec, t, ErrUnknownName) + if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) } - if !dec.options.AllowDuplicateNames && !dec.namespaces.last().insertUnquoted(name) { + if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && !xd.Namespaces.Last().InsertUnquoted(name) { // TODO: Unread the object name. - err := &SyntacticError{str: "duplicate name " + string(val) + " in object"} - return err.withOffset(dec.InputOffset() - int64(len(val))) + return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val)) } if fields.inlinedFallback == nil { @@ -1040,46 +1254,68 @@ func makeStructArshaler(t reflect.Type) *arshaler { } } else { // Marshal into value capable of storing arbitrary object members. - if err := unmarshalInlinedFallbackNext(uo, dec, va, fields.inlinedFallback, val, name); err != nil { - return err + if err := unmarshalInlinedFallbackNext(dec, va, uo, fields.inlinedFallback, val, name); err != nil { + if isFatalError(err, uo.Flags) { + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) } } continue } } - if !dec.options.AllowDuplicateNames && !seenIdxs.insert(uint(f.id)) { + if !uo.Flags.Get(jsonflags.AllowDuplicateNames) && !seenIdxs.insert(uint(f.id)) { // TODO: Unread the object name. - err := &SyntacticError{str: "duplicate name " + string(val) + " in object"} - return err.withOffset(dec.InputOffset() - int64(len(val))) + return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val)) } // Process the object member value. unmarshal := f.fncs.unmarshal if uo.Unmarshalers != nil { - unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, f.typ) + unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, f.typ) } - uo2 := uo + flagsOriginal := uo.Flags if f.string { - uo2.StringifyNumbers = true + if !uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + uo.Flags.Set(jsonflags.StringifyNumbers | 1) + } else if canLegacyStringify(f.typ) { + uo.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1) + } } if f.format != "" { - uo2.formatDepth = dec.tokens.depth() - uo2.format = f.format + uo.FormatDepth = xd.Tokens.Depth() + uo.Format = f.format } - v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable - if len(f.index) > 1 { - v = v.fieldByIndex(f.index[1:], true) + v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable + if len(f.index) > 0 { + v = v.fieldByIndex(f.index, true) + if !v.IsValid() { + err := newUnmarshalErrorBefore(dec, t, errNilField) + if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) + unmarshal = func(dec *jsontext.Decoder, _ addressableValue, _ *jsonopts.Struct) error { + return dec.SkipValue() + } + } } - if err := unmarshal(uo2, dec, v); err != nil { - return err + err = unmarshal(dec, v, uo) + uo.Flags = flagsOriginal + uo.Format = "" + if err != nil { + if isFatalError(err, uo.Flags) { + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) } } if _, err := dec.ReadToken(); err != nil { return err } - return nil + return errUnmarshal } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -1090,7 +1326,7 @@ func (va addressableValue) fieldByIndex(index []int, mayAlloc bool) addressableV if !va.IsValid() { return va } - va = addressableValue{va.Field(i)} // addressable if struct value is addressable + va = addressableValue{va.Field(i), va.forcedAddr} // addressable if struct value is addressable } return va } @@ -1098,16 +1334,55 @@ func (va addressableValue) fieldByIndex(index []int, mayAlloc bool) addressableV func (va addressableValue) indirect(mayAlloc bool) addressableValue { if va.Kind() == reflect.Pointer { if va.IsNil() { - if !mayAlloc { + if !mayAlloc || !va.CanSet() { return addressableValue{} } va.Set(reflect.New(va.Type().Elem())) } - va = addressableValue{va.Elem()} // dereferenced pointer is always addressable + va = addressableValue{va.Elem(), false} // dereferenced pointer is always addressable } return va } +// isLegacyEmpty reports whether a value is empty according to the v1 definition. +func isLegacyEmpty(v addressableValue) bool { + // Equivalent to encoding/json.isEmptyValue@v1.21.0. + switch v.Kind() { + case reflect.Bool: + return v.Bool() == false + 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.String, reflect.Map, reflect.Slice, reflect.Array: + return v.Len() == 0 + case reflect.Pointer, reflect.Interface: + return v.IsNil() + } + return false +} + +// canLegacyStringify reports whether t can be stringified according to v1, +// where t is a bool, string, or number (or unnamed pointer to such). +// In v1, the `string` option does not apply recursively to nested types within +// a composite Go type (e.g., an array, slice, struct, map, or interface). +func canLegacyStringify(t reflect.Type) bool { + // Based on encoding/json.typeFields#L1126-L1143@v1.23.0 + if t.Name() == "" && t.Kind() == reflect.Ptr { + t = t.Elem() + } + switch t.Kind() { + case reflect.Bool, reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64: + return true + } + return false +} + func makeSliceArshaler(t reflect.Type) *arshaler { var fncs arshaler var ( @@ -1117,64 +1392,75 @@ func makeSliceArshaler(t reflect.Type) *arshaler { init := func() { valFncs = lookupArshaler(t.Elem()) } - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { // Check for cycles. - if enc.tokens.depth() > startDetectingCyclesAfter { - if err := enc.seenPointers.visit(va.Value); err != nil { - return err - } - defer enc.seenPointers.leave(va.Value) - } - - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - if mo.format == "emitnull" { - if va.IsNil() { - return enc.WriteToken(Null) - } - mo.format = "" - } else { - return newInvalidFormatError("marshal", t, mo.format) + xe := export.Encoder(enc) + if xe.Tokens.Depth() > startDetectingCyclesAfter { + if err := visitPointer(&xe.SeenPointers, va.Value); err != nil { + return newMarshalErrorBefore(enc, t, err) + } + defer leavePointer(&xe.SeenPointers, va.Value) + } + + emitNull := mo.Flags.Get(jsonflags.FormatNilSliceAsNull) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + switch mo.Format { + case "emitnull": + emitNull = true + mo.Format = "" + case "emitempty": + emitNull = false + mo.Format = "" + default: + return newInvalidFormatError(enc, t) } } - // Optimize for marshaling an empty slice without any preceding whitespace. + // Handle empty slices. n := va.Len() - if optimizeCommon && n == 0 && !enc.options.multiline && !enc.tokens.last.needObjectName() { - enc.buf = enc.tokens.mayAppendDelim(enc.buf, '[') - enc.buf = append(enc.buf, "[]"...) - enc.tokens.last.increment() - if enc.needFlush() { - return enc.flush() + if n == 0 { + if emitNull && va.IsNil() { + return enc.WriteToken(jsontext.Null) + } + // Optimize for marshaling an empty slice without any preceding whitespace. + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() { + xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '['), "[]"...) + xe.Tokens.Last.Increment() + if xe.NeedFlush() { + return xe.Flush() + } + return nil } - return nil } once.Do(init) - if err := enc.WriteToken(ArrayStart); err != nil { + if err := enc.WriteToken(jsontext.BeginArray); err != nil { return err } marshal := valFncs.marshal if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, t.Elem()) + marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem()) } - for i := 0; i < n; i++ { - v := addressableValue{va.Index(i)} // indexed slice element is always addressable - if err := marshal(mo, enc, v); err != nil { + for i := range n { + v := addressableValue{va.Index(i), false} // indexed slice element is always addressable + if err := marshal(enc, v, mo); err != nil { return err } } - if err := enc.WriteToken(ArrayEnd); err != nil { + if err := enc.WriteToken(jsontext.EndArray); err != nil { return err } return nil } emptySlice := reflect.MakeSlice(t, 0, 0) - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - if uo.format == "emitnull" { - uo.format = "" // only relevant for marshaling - } else { - return newInvalidFormatError("unmarshal", t, uo.format) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + switch uo.Format { + case "emitnull", "emitempty": + uo.Format = "" // only relevant for marshaling + default: + return newInvalidFormatError(dec, t) } } @@ -1185,13 +1471,13 @@ func makeSliceArshaler(t reflect.Type) *arshaler { k := tok.Kind() switch k { case 'n': - va.Set(reflect.Zero(t)) + va.SetZero() return nil case '[': once.Do(init) unmarshal := valFncs.unmarshal if uo.Unmarshalers != nil { - unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t.Elem()) + unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem()) } mustZero := true // we do not know the cleanliness of unused capacity cap := va.Cap() @@ -1199,22 +1485,25 @@ func makeSliceArshaler(t reflect.Type) *arshaler { va.SetLen(cap) } var i int + var errUnmarshal error for dec.PeekKind() != ']' { if i == cap { - // TODO(https://go.dev/issue/48000): Use reflect.Value.Append. - va.Set(reflect.Append(va.Value, reflect.Zero(t.Elem()))) + va.Value.Grow(1) cap = va.Cap() va.SetLen(cap) - mustZero = false // append guarantees that unused capacity is zero-initialized + mustZero = false // reflect.Value.Grow ensures new capacity is zero-initialized } - v := addressableValue{va.Index(i)} // indexed slice element is always addressable + v := addressableValue{va.Index(i), false} // indexed slice element is always addressable i++ - if mustZero { - v.Set(reflect.Zero(t.Elem())) + if mustZero && !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + v.SetZero() } - if err := unmarshal(uo, dec, v); err != nil { - va.SetLen(i) - return err + if err := unmarshal(dec, v, uo); err != nil { + if isFatalError(err, uo.Flags) { + va.SetLen(i) + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) } } if i == 0 { @@ -1225,13 +1514,16 @@ func makeSliceArshaler(t reflect.Type) *arshaler { if _, err := dec.ReadToken(); err != nil { return err } - return nil + return errUnmarshal } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } +var errArrayUnderflow = errors.New("too few array elements") +var errArrayOverflow = errors.New("too many array elements") + func makeArrayArshaler(t reflect.Type) *arshaler { var fncs arshaler var ( @@ -1242,32 +1534,34 @@ func makeArrayArshaler(t reflect.Type) *arshaler { valFncs = lookupArshaler(t.Elem()) } n := t.Len() - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - return newInvalidFormatError("marshal", t, mo.format) + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + return newInvalidFormatError(enc, t) } once.Do(init) - if err := enc.WriteToken(ArrayStart); err != nil { + if err := enc.WriteToken(jsontext.BeginArray); err != nil { return err } marshal := valFncs.marshal if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, t.Elem()) + marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem()) } - for i := 0; i < n; i++ { - v := addressableValue{va.Index(i)} // indexed array element is addressable if array is addressable - if err := marshal(mo, enc, v); err != nil { + for i := range n { + v := addressableValue{va.Index(i), va.forcedAddr} // indexed array element is addressable if array is addressable + if err := marshal(enc, v, mo); err != nil { return err } } - if err := enc.WriteToken(ArrayEnd); err != nil { + if err := enc.WriteToken(jsontext.EndArray); err != nil { return err } return nil } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - return newInvalidFormatError("unmarshal", t, uo.format) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + return newInvalidFormatError(dec, t) } tok, err := dec.ReadToken() if err != nil { @@ -1276,37 +1570,51 @@ func makeArrayArshaler(t reflect.Type) *arshaler { k := tok.Kind() switch k { case 'n': - va.Set(reflect.Zero(t)) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetZero() + } return nil case '[': once.Do(init) unmarshal := valFncs.unmarshal if uo.Unmarshalers != nil { - unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t.Elem()) + unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem()) } var i int + var errUnmarshal error for dec.PeekKind() != ']' { if i >= n { - err := errors.New("too many array elements") - return &SemanticError{action: "unmarshal", GoType: t, Err: err} + if err := dec.SkipValue(); err != nil { + return err + } + err = errArrayOverflow + continue } - v := addressableValue{va.Index(i)} // indexed array element is addressable if array is addressable - v.Set(reflect.Zero(v.Type())) - if err := unmarshal(uo, dec, v); err != nil { - return err + v := addressableValue{va.Index(i), va.forcedAddr} // indexed array element is addressable if array is addressable + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + v.SetZero() + } + if err := unmarshal(dec, v, uo); err != nil { + if isFatalError(err, uo.Flags) { + return err + } + errUnmarshal = cmp.Or(errUnmarshal, err) } i++ } + for ; i < n; i++ { + va.Index(i).SetZero() + err = errArrayUnderflow + } if _, err := dec.ReadToken(); err != nil { return err } - if i < n { - err := errors.New("too few array elements") - return &SemanticError{action: "unmarshal", GoType: t, Err: err} + if err != nil && !uo.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) { + return newUnmarshalErrorAfter(dec, t, err) } - return nil + return errUnmarshal } - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -1320,46 +1628,62 @@ func makePointerArshaler(t reflect.Type) *arshaler { init := func() { valFncs = lookupArshaler(t.Elem()) } - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { // Check for cycles. - if enc.tokens.depth() > startDetectingCyclesAfter { - if err := enc.seenPointers.visit(va.Value); err != nil { - return err + xe := export.Encoder(enc) + if xe.Tokens.Depth() > startDetectingCyclesAfter { + if err := visitPointer(&xe.SeenPointers, va.Value); err != nil { + return newMarshalErrorBefore(enc, t, err) } - defer enc.seenPointers.leave(va.Value) + defer leavePointer(&xe.SeenPointers, va.Value) } - // NOTE: MarshalOptions.format is forwarded to underlying marshal. + // NOTE: Struct.Format is forwarded to underlying marshal. if va.IsNil() { - return enc.WriteToken(Null) + return enc.WriteToken(jsontext.Null) } once.Do(init) marshal := valFncs.marshal if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, t.Elem()) + marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t.Elem()) } - v := addressableValue{va.Elem()} // dereferenced pointer is always addressable - return marshal(mo, enc, v) + v := addressableValue{va.Elem(), false} // dereferenced pointer is always addressable + return marshal(enc, v, mo) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - // NOTE: UnmarshalOptions.format is forwarded to underlying unmarshal. + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + // NOTE: Struct.Format is forwarded to underlying unmarshal. if dec.PeekKind() == 'n' { if _, err := dec.ReadToken(); err != nil { return err } - va.Set(reflect.Zero(t)) + va.SetZero() return nil } once.Do(init) unmarshal := valFncs.unmarshal if uo.Unmarshalers != nil { - unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t.Elem()) + unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t.Elem()) } if va.IsNil() { va.Set(reflect.New(t.Elem())) } - v := addressableValue{va.Elem()} // dereferenced pointer is always addressable - return unmarshal(uo, dec, v) + v := addressableValue{va.Elem(), false} // dereferenced pointer is always addressable + if err := unmarshal(dec, v, uo); err != nil { + return err + } + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && + uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) { + // A JSON null quoted within a JSON string should take effect + // within the pointer value, rather than the indirect value. + // + // TODO: This does not correctly handle escaped nulls + // (e.g., "\u006e\u0075\u006c\u006c"), but is good enough + // for such an esoteric use case of the `string` option. + if string(export.Decoder(dec).PreviousTokenOrValue()) == `"null"` { + va.SetZero() + } + } + return nil } return &fncs } @@ -1370,34 +1694,82 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { // store them back into the interface afterwards. var fncs arshaler - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - return newInvalidFormatError("marshal", t, mo.format) + var whichMarshaler reflect.Type + for _, iface := range allMarshalerTypes { + if t.Implements(iface) { + whichMarshaler = t + break + } + } + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + return newInvalidFormatError(enc, t) } if va.IsNil() { - return enc.WriteToken(Null) + return enc.WriteToken(jsontext.Null) + } else if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && whichMarshaler != nil { + // The marshaler for a pointer never calls the method on a nil receiver. + // Wrap the nil pointer within a struct type so that marshal + // instead appears on a value receiver and may be called. + if va.Elem().Kind() == reflect.Pointer && va.Elem().IsNil() { + v2 := newAddressableValue(whichMarshaler) + switch whichMarshaler { + case jsonMarshalerToType: + v2.Set(reflect.ValueOf(struct{ MarshalerTo }{va.Elem().Interface().(MarshalerTo)})) + case jsonMarshalerType: + v2.Set(reflect.ValueOf(struct{ Marshaler }{va.Elem().Interface().(Marshaler)})) + case textAppenderType: + v2.Set(reflect.ValueOf(struct{ encoding.TextAppender }{va.Elem().Interface().(encoding.TextAppender)})) + case textMarshalerType: + v2.Set(reflect.ValueOf(struct{ encoding.TextMarshaler }{va.Elem().Interface().(encoding.TextMarshaler)})) + } + va = v2 + } } v := newAddressableValue(va.Elem().Type()) v.Set(va.Elem()) marshal := lookupArshaler(v.Type()).marshal if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, v.Type()) + marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, v.Type()) } // Optimize for the any type if there are no special options. - if optimizeCommon && t == anyType && !mo.StringifyNumbers && mo.format == "" && (mo.Marshalers == nil || !mo.Marshalers.fromAny) { - return marshalValueAny(mo, enc, va.Elem().Interface()) + if optimizeCommon && + t == anyType && !mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) && mo.Format == "" && + (mo.Marshalers == nil || !mo.Marshalers.(*Marshalers).fromAny) { + return marshalValueAny(enc, va.Elem().Interface(), mo) } - return marshal(mo, enc, v) + return marshal(enc, v, mo) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - return newInvalidFormatError("unmarshal", t, uo.format) + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + return newInvalidFormatError(dec, t) + } + if uo.Flags.Get(jsonflags.MergeWithLegacySemantics) && !va.IsNil() { + // Legacy merge behavior is difficult to explain. + // In general, it only merges for non-nil pointer kinds. + // As a special case, unmarshaling a JSON null into a pointer + // sets a concrete nil pointer of the underlying type + // (rather than setting the interface value itself to nil). + e := va.Elem() + if e.Kind() == reflect.Pointer && !e.IsNil() { + if dec.PeekKind() == 'n' && e.Elem().Kind() == reflect.Pointer { + if _, err := dec.ReadToken(); err != nil { + return err + } + va.Elem().Elem().SetZero() + return nil + } + } else { + va.SetZero() + } } if dec.PeekKind() == 'n' { if _, err := dec.ReadToken(); err != nil { return err } - va.Set(reflect.Zero(t)) + va.SetZero() return nil } var v addressableValue @@ -1407,8 +1779,10 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { // are always unmarshaled into an any value as Go strings. // Duplicate name check must be enforced since unmarshalValueAny // does not implement merge semantics. - if optimizeCommon && t == anyType && uo.format == "" && (uo.Unmarshalers == nil || !uo.Unmarshalers.fromAny) && !dec.options.AllowDuplicateNames { - v, err := unmarshalValueAny(uo, dec) + if optimizeCommon && + t == anyType && !uo.Flags.Get(jsonflags.AllowDuplicateNames) && uo.Format == "" && + (uo.Unmarshalers == nil || !uo.Unmarshalers.(*Unmarshalers).fromAny) { + v, err := unmarshalValueAny(dec, uo) // We must check for nil interface values up front. // See https://go.dev/issue/52310. if v != nil { @@ -1419,8 +1793,7 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { k := dec.PeekKind() if !isAnyType(t) { - err := errors.New("cannot derive concrete type for non-empty interface") - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + return newUnmarshalErrorBeforeWithSkipping(dec, t, internal.ErrNilInterface) } switch k { case 'f', 't': @@ -1428,7 +1801,11 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { case '"': v = newAddressableValue(stringType) case '0': - v = newAddressableValue(float64Type) + if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) { + v = addressableValue{reflect.ValueOf(internal.NewRawNumber()).Elem(), true} + } else { + v = newAddressableValue(float64Type) + } case '{': v = newAddressableValue(mapStringAnyType) case '[': @@ -1450,9 +1827,9 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { } unmarshal := lookupArshaler(v.Type()).unmarshal if uo.Unmarshalers != nil { - unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, v.Type()) + unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, v.Type()) } - err := unmarshal(uo, dec, v) + err := unmarshal(dec, v, uo) va.Set(v.Value) return err } @@ -1470,16 +1847,62 @@ func isAnyType(t reflect.Type) bool { func makeInvalidArshaler(t reflect.Type) *arshaler { var fncs arshaler - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - return &SemanticError{action: "marshal", GoType: t} + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + return newMarshalErrorBefore(enc, t, nil) } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - return &SemanticError{action: "unmarshal", GoType: t} + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + return newUnmarshalErrorBefore(dec, t, nil) } return &fncs } -func newInvalidFormatError(action string, t reflect.Type, format string) error { - err := fmt.Errorf("invalid format flag: %q", format) - return &SemanticError{action: action, GoType: t, Err: err} +func stringOrNumberKind(isString bool) jsontext.Kind { + if isString { + return '"' + } else { + return '0' + } +} + +type uintSet64 uint64 + +func (s uintSet64) has(i uint) bool { return s&(1< 0 } +func (s *uintSet64) set(i uint) { *s |= 1 << i } + +// uintSet is a set of unsigned integers. +// It is optimized for most integers being close to zero. +type uintSet struct { + lo uintSet64 + hi []uintSet64 +} + +// has reports whether i is in the set. +func (s *uintSet) has(i uint) bool { + if i < 64 { + return s.lo.has(i) + } else { + i -= 64 + iHi, iLo := int(i/64), i%64 + return iHi < len(s.hi) && s.hi[iHi].has(iLo) + } +} + +// insert inserts i into the set and reports whether it was the first insertion. +func (s *uintSet) insert(i uint) bool { + // TODO: Make this inlinable at least for the lower 64-bit case. + if i < 64 { + has := s.lo.has(i) + s.lo.set(i) + return !has + } else { + i -= 64 + iHi, iLo := int(i/64), i%64 + if iHi >= len(s.hi) { + s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...) + s.hi = s.hi[:cap(s.hi)] + } + has := s.hi[iHi].has(iLo) + s.hi[iHi].set(iLo) + return !has + } } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go index 8a4e7008..50dca26b 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.go @@ -9,62 +9,75 @@ import ( "fmt" "reflect" "sync" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) -// SkipFunc may be returned by MarshalFuncV2 and UnmarshalFuncV2 functions. +// SkipFunc may be returned by [MarshalToFunc] and [UnmarshalFromFunc] functions. // // Any function that returns SkipFunc must not cause observable side effects -// on the provided Encoder or Decoder. For example, it is permissible to call -// Decoder.PeekKind, but not permissible to call Decoder.ReadToken or -// Encoder.WriteToken since such methods mutate the state. -const SkipFunc = jsonError("skip function") +// on the provided [jsontext.Encoder] or [jsontext.Decoder]. +// For example, it is permissible to call [jsontext.Decoder.PeekKind], +// but not permissible to call [jsontext.Decoder.ReadToken] or +// [jsontext.Encoder.WriteToken] since such methods mutate the state. +var SkipFunc = errors.New("json: skip function") + +var errSkipMutation = errors.New("must not read or write any tokens when skipping") +var errNonSingularValue = errors.New("must read or write exactly one value") // Marshalers is a list of functions that may override the marshal behavior -// of specific types. Populate MarshalOptions.Marshalers to use it. +// of specific types. Populate [WithMarshalers] to use it with +// [Marshal], [MarshalWrite], or [MarshalEncode]. // A nil *Marshalers is equivalent to an empty list. +// There are no exported fields or methods on Marshalers. type Marshalers = typedMarshalers -// NewMarshalers constructs a flattened list of marshal functions. +// JoinMarshalers constructs a flattened list of marshal functions. // If multiple functions in the list are applicable for a value of a given type, // then those earlier in the list take precedence over those that come later. -// If a function returns SkipFunc, then the next applicable function is called, +// If a function returns [SkipFunc], then the next applicable function is called, // otherwise the default marshaling behavior is used. // // For example: // -// m1 := NewMarshalers(f1, f2) -// m2 := NewMarshalers(f0, m1, f3) // equivalent to m3 -// m3 := NewMarshalers(f0, f1, f2, f3) // equivalent to m2 -func NewMarshalers(ms ...*Marshalers) *Marshalers { +// m1 := JoinMarshalers(f1, f2) +// m2 := JoinMarshalers(f0, m1, f3) // equivalent to m3 +// m3 := JoinMarshalers(f0, f1, f2, f3) // equivalent to m2 +func JoinMarshalers(ms ...*Marshalers) *Marshalers { return newMarshalers(ms...) } // Unmarshalers is a list of functions that may override the unmarshal behavior -// of specific types. Populate UnmarshalOptions.Unmarshalers to use it. +// of specific types. Populate [WithUnmarshalers] to use it with +// [Unmarshal], [UnmarshalRead], or [UnmarshalDecode]. // A nil *Unmarshalers is equivalent to an empty list. +// There are no exported fields or methods on Unmarshalers. type Unmarshalers = typedUnmarshalers -// NewUnmarshalers constructs a flattened list of unmarshal functions. +// JoinUnmarshalers constructs a flattened list of unmarshal functions. // If multiple functions in the list are applicable for a value of a given type, // then those earlier in the list take precedence over those that come later. -// If a function returns SkipFunc, then the next applicable function is called, +// If a function returns [SkipFunc], then the next applicable function is called, // otherwise the default unmarshaling behavior is used. // // For example: // -// u1 := NewUnmarshalers(f1, f2) -// u2 := NewUnmarshalers(f0, u1, f3) // equivalent to u3 -// u3 := NewUnmarshalers(f0, f1, f2, f3) // equivalent to u2 -func NewUnmarshalers(us ...*Unmarshalers) *Unmarshalers { +// u1 := JoinUnmarshalers(f1, f2) +// u2 := JoinUnmarshalers(f0, u1, f3) // equivalent to u3 +// u3 := JoinUnmarshalers(f0, f1, f2, f3) // equivalent to u2 +func JoinUnmarshalers(us ...*Unmarshalers) *Unmarshalers { return newUnmarshalers(us...) } -type typedMarshalers = typedArshalers[MarshalOptions, Encoder] -type typedUnmarshalers = typedArshalers[UnmarshalOptions, Decoder] -type typedArshalers[Options, Coder any] struct { +type typedMarshalers = typedArshalers[jsontext.Encoder] +type typedUnmarshalers = typedArshalers[jsontext.Decoder] +type typedArshalers[Coder any] struct { nonComparable - fncVals []typedArshaler[Options, Coder] + fncVals []typedArshaler[Coder] fncCache sync.Map // map[reflect.Type]arshaler // fromAny reports whether any of Go types used to represent arbitrary JSON @@ -78,18 +91,18 @@ type typedArshalers[Options, Coder any] struct { // if this is true. fromAny bool } -type typedMarshaler = typedArshaler[MarshalOptions, Encoder] -type typedUnmarshaler = typedArshaler[UnmarshalOptions, Decoder] -type typedArshaler[Options, Coder any] struct { +type typedMarshaler = typedArshaler[jsontext.Encoder] +type typedUnmarshaler = typedArshaler[jsontext.Decoder] +type typedArshaler[Coder any] struct { typ reflect.Type - fnc func(Options, *Coder, addressableValue) error + fnc func(*Coder, addressableValue, *jsonopts.Struct) error maySkip bool } func newMarshalers(ms ...*Marshalers) *Marshalers { return newTypedArshalers(ms...) } func newUnmarshalers(us ...*Unmarshalers) *Unmarshalers { return newTypedArshalers(us...) } -func newTypedArshalers[Options, Coder any](as ...*typedArshalers[Options, Coder]) *typedArshalers[Options, Coder] { - var a typedArshalers[Options, Coder] +func newTypedArshalers[Coder any](as ...*typedArshalers[Coder]) *typedArshalers[Coder] { + var a typedArshalers[Coder] for _, a2 := range as { if a2 != nil { a.fncVals = append(a.fncVals, a2.fncVals...) @@ -102,7 +115,7 @@ func newTypedArshalers[Options, Coder any](as ...*typedArshalers[Options, Coder] return &a } -func (a *typedArshalers[Options, Coder]) lookup(fnc func(Options, *Coder, addressableValue) error, t reflect.Type) (func(Options, *Coder, addressableValue) error, bool) { +func (a *typedArshalers[Coder]) lookup(fnc func(*Coder, addressableValue, *jsonopts.Struct) error, t reflect.Type) (func(*Coder, addressableValue, *jsonopts.Struct) error, bool) { if a == nil { return fnc, false } @@ -110,12 +123,12 @@ func (a *typedArshalers[Options, Coder]) lookup(fnc func(Options, *Coder, addres if v == nil { return fnc, false } - return v.(func(Options, *Coder, addressableValue) error), true + return v.(func(*Coder, addressableValue, *jsonopts.Struct) error), true } // Collect a list of arshalers that can be called for this type. // This list may be longer than 1 since some arshalers can be skipped. - var fncs []func(Options, *Coder, addressableValue) error + var fncs []func(*Coder, addressableValue, *jsonopts.Struct) error for _, fncVal := range a.fncVals { if !castableTo(t, fncVal.typ) { continue @@ -133,21 +146,21 @@ func (a *typedArshalers[Options, Coder]) lookup(fnc func(Options, *Coder, addres // Construct an arshaler that may call every applicable arshaler. fncDefault := fnc - fnc = func(o Options, c *Coder, v addressableValue) error { + fnc = func(c *Coder, v addressableValue, o *jsonopts.Struct) error { for _, fnc := range fncs { - if err := fnc(o, c, v); err != SkipFunc { + if err := fnc(c, v, o); err != SkipFunc { return err // may be nil or non-nil } } - return fncDefault(o, c, v) + return fncDefault(c, v, o) } // Use the first stored so duplicate work can be garbage collected. v, _ := a.fncCache.LoadOrStore(t, fnc) - return v.(func(Options, *Coder, addressableValue) error), true + return v.(func(*Coder, addressableValue, *jsonopts.Struct) error), true } -// MarshalFuncV1 constructs a type-specific marshaler that +// MarshalFunc constructs a type-specific marshaler that // specifies how to marshal values of type T. // T can be any type except a named pointer. // The function is always provided with a non-nil pointer value @@ -155,22 +168,30 @@ func (a *typedArshalers[Options, Coder]) lookup(fnc func(Options, *Coder, addres // // The function must marshal exactly one JSON value. // The value of T must not be retained outside the function call. -// It may not return SkipFunc. -func MarshalFuncV1[T any](fn func(T) ([]byte, error)) *Marshalers { - t := reflect.TypeOf((*T)(nil)).Elem() +// It may not return [SkipFunc]. +func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers { + t := reflect.TypeFor[T]() assertCastableTo(t, true) typFnc := typedMarshaler{ typ: t, - fnc: func(mo MarshalOptions, enc *Encoder, va addressableValue) error { + fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { val, err := fn(va.castTo(t).Interface().(T)) if err != nil { err = wrapSkipFunc(err, "marshal function of type func(T) ([]byte, error)") - // TODO: Avoid wrapping semantic errors. - return &SemanticError{action: "marshal", GoType: t, Err: err} + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalFunc") // unlike unmarshal, always wrapped + } + err = newMarshalErrorBefore(enc, t, err) + return collapseSemanticErrors(err) } if err := enc.WriteValue(val); err != nil { - // TODO: Avoid wrapping semantic or I/O errors. - return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err} + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalFunc") // unlike unmarshal, always wrapped + } + if isSyntacticError(err) { + err = newMarshalErrorBefore(enc, t, err) + } + return err } return nil }, @@ -178,39 +199,47 @@ func MarshalFuncV1[T any](fn func(T) ([]byte, error)) *Marshalers { return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)} } -// MarshalFuncV2 constructs a type-specific marshaler that +// MarshalToFunc constructs a type-specific marshaler that // specifies how to marshal values of type T. // T can be any type except a named pointer. // The function is always provided with a non-nil pointer value // if T is an interface or pointer type. // // The function must marshal exactly one JSON value by calling write methods -// on the provided encoder. It may return SkipFunc such that marshaling can +// on the provided encoder. It may return [SkipFunc] such that marshaling can // move on to the next marshal function. However, no mutable method calls may -// be called on the encoder if SkipFunc is returned. -// The pointer to Encoder and the value of T must not be retained -// outside the function call. -func MarshalFuncV2[T any](fn func(MarshalOptions, *Encoder, T) error) *Marshalers { - t := reflect.TypeOf((*T)(nil)).Elem() +// be called on the encoder if [SkipFunc] is returned. +// The pointer to [jsontext.Encoder] and the value of T +// must not be retained outside the function call. +func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers { + t := reflect.TypeFor[T]() assertCastableTo(t, true) typFnc := typedMarshaler{ typ: t, - fnc: func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - prevDepth, prevLength := enc.tokens.depthLength() - err := fn(mo, enc, va.castTo(t).Interface().(T)) - currDepth, currLength := enc.tokens.depthLength() + fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + prevDepth, prevLength := xe.Tokens.DepthLength() + xe.Flags.Set(jsonflags.WithinArshalCall | 1) + err := fn(enc, va.castTo(t).Interface().(T)) + xe.Flags.Set(jsonflags.WithinArshalCall | 0) + currDepth, currLength := xe.Tokens.DepthLength() if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { - err = errors.New("must write exactly one JSON value") + err = errNonSingularValue } if err != nil { if err == SkipFunc { if prevDepth == currDepth && prevLength == currLength { return SkipFunc } - err = errors.New("must not write any JSON tokens when skipping") + err = errSkipMutation + } + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalToFunc") // unlike unmarshal, always wrapped } - // TODO: Avoid wrapping semantic or I/O errors. - return &SemanticError{action: "marshal", GoType: t, Err: err} + if !export.IsIOError(err) { + err = newSemanticErrorWithPosition(enc, t, prevDepth, prevLength, err) + } + return err } return nil }, @@ -219,7 +248,7 @@ func MarshalFuncV2[T any](fn func(MarshalOptions, *Encoder, T) error) *Marshaler return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)} } -// UnmarshalFuncV1 constructs a type-specific unmarshaler that +// UnmarshalFunc constructs a type-specific unmarshaler that // specifies how to unmarshal values of type T. // T must be an unnamed pointer or an interface type. // The function is always provided with a non-nil pointer value. @@ -227,13 +256,13 @@ func MarshalFuncV2[T any](fn func(MarshalOptions, *Encoder, T) error) *Marshaler // The function must unmarshal exactly one JSON value. // The input []byte must not be mutated. // The input []byte and value T must not be retained outside the function call. -// It may not return SkipFunc. -func UnmarshalFuncV1[T any](fn func([]byte, T) error) *Unmarshalers { - t := reflect.TypeOf((*T)(nil)).Elem() +// It may not return [SkipFunc]. +func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers { + t := reflect.TypeFor[T]() assertCastableTo(t, false) typFnc := typedUnmarshaler{ typ: t, - fnc: func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + fnc: func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { val, err := dec.ReadValue() if err != nil { return err // must be a syntactic or I/O error @@ -241,8 +270,11 @@ func UnmarshalFuncV1[T any](fn func([]byte, T) error) *Unmarshalers { err = fn(val, va.castTo(t).Interface().(T)) if err != nil { err = wrapSkipFunc(err, "unmarshal function of type func([]byte, T) error") - // TODO: Avoid wrapping semantic, syntactic, or I/O errors. - return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err // unlike marshal, never wrapped + } + err = newUnmarshalErrorAfter(dec, t, err) + return collapseSemanticErrors(err) } return nil }, @@ -250,38 +282,49 @@ func UnmarshalFuncV1[T any](fn func([]byte, T) error) *Unmarshalers { return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)} } -// UnmarshalFuncV2 constructs a type-specific unmarshaler that +// UnmarshalFromFunc constructs a type-specific unmarshaler that // specifies how to unmarshal values of type T. // T must be an unnamed pointer or an interface type. // The function is always provided with a non-nil pointer value. // // The function must unmarshal exactly one JSON value by calling read methods -// on the provided decoder. It may return SkipFunc such that unmarshaling can +// on the provided decoder. It may return [SkipFunc] such that unmarshaling can // move on to the next unmarshal function. However, no mutable method calls may -// be called on the decoder if SkipFunc is returned. -// The pointer to Decoder and the value of T must not be retained -// outside the function call. -func UnmarshalFuncV2[T any](fn func(UnmarshalOptions, *Decoder, T) error) *Unmarshalers { - t := reflect.TypeOf((*T)(nil)).Elem() +// be called on the decoder if [SkipFunc] is returned. +// The pointer to [jsontext.Decoder] and the value of T +// must not be retained outside the function call. +func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers { + t := reflect.TypeFor[T]() assertCastableTo(t, false) typFnc := typedUnmarshaler{ typ: t, - fnc: func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - prevDepth, prevLength := dec.tokens.depthLength() - err := fn(uo, dec, va.castTo(t).Interface().(T)) - currDepth, currLength := dec.tokens.depthLength() + fnc: func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + prevDepth, prevLength := xd.Tokens.DepthLength() + xd.Flags.Set(jsonflags.WithinArshalCall | 1) + err := fn(dec, va.castTo(t).Interface().(T)) + xd.Flags.Set(jsonflags.WithinArshalCall | 0) + currDepth, currLength := xd.Tokens.DepthLength() if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { - err = errors.New("must read exactly one JSON value") + err = errNonSingularValue } if err != nil { if err == SkipFunc { if prevDepth == currDepth && prevLength == currLength { return SkipFunc } - err = errors.New("must not read any JSON tokens when skipping") + err = errSkipMutation + } + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + if err2 := xd.SkipUntil(prevDepth, prevLength+1); err2 != nil { + return err2 + } + return err // unlike marshal, never wrapped + } + if !isSyntacticError(err) && !export.IsIOError(err) { + err = newSemanticErrorWithPosition(dec, t, prevDepth, prevLength, err) } - // TODO: Avoid wrapping semantic, syntactic, or I/O errors. - return &SemanticError{action: "unmarshal", GoType: t, Err: err} + return err } return nil }, diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go index 258a9824..4509b87e 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go @@ -7,7 +7,13 @@ package json import ( "bytes" "errors" + "io" "reflect" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // This package supports "inlining" a Go struct field, where the contents @@ -18,18 +24,20 @@ import ( // nested struct are virtually hoisted up to the parent struct using rules // similar to how Go embedding works (but operating within the JSON namespace). // -// However, inlined fields may also be of a Go map type with a string key -// or a RawValue. Such inlined fields are called "fallback" fields since they +// However, inlined fields may also be of a Go map type with a string key or +// a jsontext.Value. Such inlined fields are called "fallback" fields since they // represent any arbitrary JSON object member. Explicitly named fields take // precedence over the inlined fallback. Only one inlined fallback is allowed. -var rawValueType = reflect.TypeOf((*RawValue)(nil)).Elem() +var errRawInlinedNotObject = errors.New("inlined raw value must be a JSON object") + +var jsontextValueType = reflect.TypeFor[jsontext.Value]() // marshalInlinedFallbackAll marshals all the members in an inlined fallback. -func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableValue, f *structField, insertUnquotedName func([]byte) bool) error { - v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable - if len(f.index) > 1 { - v = v.fieldByIndex(f.index[1:], false) +func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct, f *structField, insertUnquotedName func([]byte) bool) error { + v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable + if len(f.index) > 0 { + v = v.fieldByIndex(f.index, false) if !v.IsValid() { return nil // implies a nil inlined field } @@ -39,34 +47,39 @@ func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableVa return nil } - if v.Type() == rawValueType { - b := v.Interface().(RawValue) + if v.Type() == jsontextValueType { + // TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo. + b := *v.Addr().Interface().(*jsontext.Value) if len(b) == 0 { // TODO: Should this be nil? What if it were all whitespace? return nil } - dec := getBufferedDecoder(b, DecodeOptions{AllowDuplicateNames: true, AllowInvalidUTF8: true}) - defer putBufferedDecoder(dec) + dec := export.GetBufferedDecoder(b) + defer export.PutBufferedDecoder(dec) + xd := export.Decoder(dec) + xd.Flags.Set(jsonflags.AllowDuplicateNames | jsonflags.AllowInvalidUTF8 | 1) tok, err := dec.ReadToken() if err != nil { - return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return newMarshalErrorBefore(enc, v.Type(), err) } if tok.Kind() != '{' { - err := errors.New("inlined raw value must be a JSON object") - return &SemanticError{action: "marshal", JSONKind: tok.Kind(), GoType: rawValueType, Err: err} + return newMarshalErrorBefore(enc, v.Type(), errRawInlinedNotObject) } for dec.PeekKind() != '}' { // Parse the JSON object name. - var flags valueFlags - val, err := dec.readValue(&flags) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { - return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + return newMarshalErrorBefore(enc, v.Type(), err) } if insertUnquotedName != nil { - name := unescapeStringMayCopy(val, flags.isVerbatim()) + name := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) if !insertUnquotedName(name) { - return &SyntacticError{str: "duplicate name " + string(val) + " in object"} + return newDuplicateNameError(enc.StackPointer().Parent(), val, enc.OutputOffset()) } } if err := enc.WriteValue(val); err != nil { @@ -74,55 +87,55 @@ func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableVa } // Parse the JSON object value. - val, err = dec.readValue(&flags) + val, err = xd.ReadValue(&flags) if err != nil { - return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + return newMarshalErrorBefore(enc, v.Type(), err) } if err := enc.WriteValue(val); err != nil { return err } } if _, err := dec.ReadToken(); err != nil { - return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + return newMarshalErrorBefore(enc, v.Type(), err) } - if err := dec.checkEOF(); err != nil { - return &SemanticError{action: "marshal", GoType: rawValueType, Err: err} + if err := xd.CheckEOF(); err != nil { + return newMarshalErrorBefore(enc, v.Type(), err) } return nil } else { - m := v // must be a map[string]V + m := v // must be a map[~string]V n := m.Len() if n == 0 { return nil } - mk := newAddressableValue(stringType) + mk := newAddressableValue(m.Type().Key()) mv := newAddressableValue(m.Type().Elem()) marshalKey := func(mk addressableValue) error { - b, err := appendString(enc.UnusedBuffer(), mk.String(), !enc.options.AllowInvalidUTF8, nil) + b, err := jsonwire.AppendQuote(enc.AvailableBuffer(), mk.String(), &mo.Flags) if err != nil { - return err + return newMarshalErrorBefore(enc, m.Type().Key(), err) } if insertUnquotedName != nil { isVerbatim := bytes.IndexByte(b, '\\') < 0 - name := unescapeStringMayCopy(b, isVerbatim) + name := jsonwire.UnquoteMayCopy(b, isVerbatim) if !insertUnquotedName(name) { - return &SyntacticError{str: "duplicate name " + string(b) + " in object"} + return newDuplicateNameError(enc.StackPointer().Parent(), b, enc.OutputOffset()) } } return enc.WriteValue(b) } marshalVal := f.fncs.marshal if mo.Marshalers != nil { - marshalVal, _ = mo.Marshalers.lookup(marshalVal, mv.Type()) + marshalVal, _ = mo.Marshalers.(*Marshalers).lookup(marshalVal, mv.Type()) } - if !mo.Deterministic || n <= 1 { + if !mo.Flags.Get(jsonflags.Deterministic) || n <= 1 { for iter := m.MapRange(); iter.Next(); { mk.SetIterKey(iter) if err := marshalKey(mk); err != nil { return err } mv.Set(iter.Value()) - if err := marshalVal(mo, enc, mv); err != nil { + if err := marshalVal(enc, mv, mo); err != nil { return err } } @@ -140,7 +153,7 @@ func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableVa } // TODO(https://go.dev/issue/57061): Use mv.SetMapIndexOf. mv.Set(m.MapIndex(mk.Value)) - if err := marshalVal(mo, enc, mv); err != nil { + if err := marshalVal(enc, mv, mo); err != nil { return err } } @@ -151,59 +164,61 @@ func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableVa } // unmarshalInlinedFallbackNext unmarshals only the next member in an inlined fallback. -func unmarshalInlinedFallbackNext(uo UnmarshalOptions, dec *Decoder, va addressableValue, f *structField, quotedName, unquotedName []byte) error { - v := addressableValue{va.Field(f.index[0])} // addressable if struct value is addressable - if len(f.index) > 1 { - v = v.fieldByIndex(f.index[1:], true) +func unmarshalInlinedFallbackNext(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct, f *structField, quotedName, unquotedName []byte) error { + v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable + if len(f.index) > 0 { + v = v.fieldByIndex(f.index, true) } v = v.indirect(true) - if v.Type() == rawValueType { - b := v.Addr().Interface().(*RawValue) + if v.Type() == jsontextValueType { + b := v.Addr().Interface().(*jsontext.Value) if len(*b) == 0 { // TODO: Should this be nil? What if it were all whitespace? *b = append(*b, '{') } else { - *b = trimSuffixWhitespace(*b) - if hasSuffixByte(*b, '}') { + *b = jsonwire.TrimSuffixWhitespace(*b) + if jsonwire.HasSuffixByte(*b, '}') { // TODO: When merging into an object for the first time, // should we verify that it is valid? - *b = trimSuffixByte(*b, '}') - *b = trimSuffixWhitespace(*b) - if !hasSuffixByte(*b, ',') && !hasSuffixByte(*b, '{') { + *b = jsonwire.TrimSuffixByte(*b, '}') + *b = jsonwire.TrimSuffixWhitespace(*b) + if !jsonwire.HasSuffixByte(*b, ',') && !jsonwire.HasSuffixByte(*b, '{') { *b = append(*b, ',') } } else { - err := errors.New("inlined raw value must be a JSON object") - return &SemanticError{action: "unmarshal", GoType: rawValueType, Err: err} + return newUnmarshalErrorAfterWithSkipping(dec, v.Type(), errRawInlinedNotObject) } } *b = append(*b, quotedName...) *b = append(*b, ':') - rawValue, err := dec.ReadValue() + val, err := dec.ReadValue() if err != nil { return err } - *b = append(*b, rawValue...) + *b = append(*b, val...) *b = append(*b, '}') return nil } else { name := string(unquotedName) // TODO: Intern this? - m := v // must be a map[string]V + m := v // must be a map[~string]V if m.IsNil() { m.Set(reflect.MakeMap(m.Type())) } mk := reflect.ValueOf(name) - mv := newAddressableValue(v.Type().Elem()) // TODO: Cache across calls? + if mkt := m.Type().Key(); mkt != stringType { + mk = mk.Convert(mkt) + } + mv := newAddressableValue(m.Type().Elem()) // TODO: Cache across calls? if v2 := m.MapIndex(mk); v2.IsValid() { mv.Set(v2) } unmarshal := f.fncs.unmarshal if uo.Unmarshalers != nil { - unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, mv.Type()) + unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, mv.Type()) } - err := unmarshal(uo, dec, mv) + err := unmarshal(dec, mv, uo) m.SetMapIndex(mk, mv.Value) if err != nil { return err diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go index 20899c86..42d6ee87 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go @@ -8,47 +8,60 @@ import ( "encoding" "errors" "reflect" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) +var errNonStringValue = errors.New("JSON value must be string type") + // Interfaces for custom serialization. var ( - jsonMarshalerV1Type = reflect.TypeOf((*MarshalerV1)(nil)).Elem() - jsonMarshalerV2Type = reflect.TypeOf((*MarshalerV2)(nil)).Elem() - jsonUnmarshalerV1Type = reflect.TypeOf((*UnmarshalerV1)(nil)).Elem() - jsonUnmarshalerV2Type = reflect.TypeOf((*UnmarshalerV2)(nil)).Elem() - textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + jsonMarshalerType = reflect.TypeFor[Marshaler]() + jsonMarshalerToType = reflect.TypeFor[MarshalerTo]() + jsonUnmarshalerType = reflect.TypeFor[Unmarshaler]() + jsonUnmarshalerFromType = reflect.TypeFor[UnmarshalerFrom]() + textAppenderType = reflect.TypeFor[encoding.TextAppender]() + textMarshalerType = reflect.TypeFor[encoding.TextMarshaler]() + textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]() + + allMarshalerTypes = []reflect.Type{jsonMarshalerToType, jsonMarshalerType, textAppenderType, textMarshalerType} + allUnmarshalerTypes = []reflect.Type{jsonUnmarshalerFromType, jsonUnmarshalerType, textUnmarshalerType} + allMethodTypes = append(allMarshalerTypes, allUnmarshalerTypes...) ) -// MarshalerV1 is implemented by types that can marshal themselves. -// It is recommended that types implement MarshalerV2 unless the implementation +// Marshaler is implemented by types that can marshal themselves. +// It is recommended that types implement [MarshalerTo] unless the implementation // is trying to avoid a hard dependency on the "jsontext" package. // // It is recommended that implementations return a buffer that is safe // for the caller to retain and potentially mutate. -type MarshalerV1 interface { +type Marshaler interface { MarshalJSON() ([]byte, error) } -// MarshalerV2 is implemented by types that can marshal themselves. -// It is recommended that types implement MarshalerV2 instead of MarshalerV1 +// MarshalerTo is implemented by types that can marshal themselves. +// It is recommended that types implement MarshalerTo instead of [Marshaler] // since this is both more performant and flexible. -// If a type implements both MarshalerV1 and MarshalerV2, -// then MarshalerV2 takes precedence. In such a case, both implementations +// If a type implements both Marshaler and MarshalerTo, +// then MarshalerTo takes precedence. In such a case, both implementations // should aim to have equivalent behavior for the default marshal options. // // The implementation must write only one JSON value to the Encoder and -// must not retain the pointer to Encoder. -type MarshalerV2 interface { - MarshalNextJSON(MarshalOptions, *Encoder) error +// must not retain the pointer to [jsontext.Encoder]. +type MarshalerTo interface { + MarshalJSONTo(*jsontext.Encoder) error - // TODO: Should users call the MarshalOptions.MarshalNext method or + // TODO: Should users call the MarshalEncode function or // should/can they call this method directly? Does it matter? } -// UnmarshalerV1 is implemented by types that can unmarshal themselves. -// It is recommended that types implement UnmarshalerV2 unless -// the implementation is trying to avoid a hard dependency on this package. +// Unmarshaler is implemented by types that can unmarshal themselves. +// It is recommended that types implement [UnmarshalerFrom] unless the implementation +// is trying to avoid a hard dependency on the "jsontext" package. // // The input can be assumed to be a valid encoding of a JSON value // if called from unmarshal functionality in this package. @@ -57,26 +70,26 @@ type MarshalerV2 interface { // unmarshaling into a pre-populated value. // // Implementations must not retain or mutate the input []byte. -type UnmarshalerV1 interface { +type Unmarshaler interface { UnmarshalJSON([]byte) error } -// UnmarshalerV2 is implemented by types that can unmarshal themselves. -// It is recommended that types implement UnmarshalerV2 instead of UnmarshalerV1 +// UnmarshalerFrom is implemented by types that can unmarshal themselves. +// It is recommended that types implement UnmarshalerFrom instead of [Unmarshaler] // since this is both more performant and flexible. -// If a type implements both UnmarshalerV1 and UnmarshalerV2, -// then UnmarshalerV2 takes precedence. In such a case, both implementations +// If a type implements both Unmarshaler and UnmarshalerFrom, +// then UnmarshalerFrom takes precedence. In such a case, both implementations // should aim to have equivalent behavior for the default unmarshal options. // // The implementation must read only one JSON value from the Decoder. -// It is recommended that UnmarshalNextJSON implement merge semantics when +// It is recommended that UnmarshalJSONFrom implement merge semantics when // unmarshaling into a pre-populated value. // -// Implementations must not retain the pointer to Decoder. -type UnmarshalerV2 interface { - UnmarshalNextJSON(UnmarshalOptions, *Decoder) error +// Implementations must not retain the pointer to [jsontext.Decoder]. +type UnmarshalerFrom interface { + UnmarshalJSONFrom(*jsontext.Decoder) error - // TODO: Should users call the UnmarshalOptions.UnmarshalNext method or + // TODO: Should users call the UnmarshalDecode function or // should/can they call this method directly? Does it matter? } @@ -88,114 +101,205 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { return fncs } - // Handle custom marshaler. - switch which, needAddr := implementsWhich(t, jsonMarshalerV2Type, jsonMarshalerV1Type, textMarshalerType); which { - case jsonMarshalerV2Type: + if needAddr, ok := implements(t, textMarshalerType); ok { fncs.nonDefault = true - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - prevDepth, prevLength := enc.tokens.depthLength() - err := va.addrWhen(needAddr).Interface().(MarshalerV2).MarshalNextJSON(mo, enc) - currDepth, currLength := enc.tokens.depthLength() - if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil { - err = errors.New("must write exactly one JSON value") + prevMarshal := fncs.marshal + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + (needAddr && va.forcedAddr) { + return prevMarshal(enc, va, mo) } - if err != nil { + marshaler := va.Addr().Interface().(encoding.TextMarshaler) + if err := export.Encoder(enc).AppendRaw('"', false, func(b []byte) ([]byte, error) { + b2, err := marshaler.MarshalText() + return append(b, b2...), err + }); err != nil { err = wrapSkipFunc(err, "marshal method") - // TODO: Avoid wrapping semantic or I/O errors. - return &SemanticError{action: "marshal", GoType: t, Err: err} + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalText") // unlike unmarshal, always wrapped + } + if !isSemanticError(err) && !export.IsIOError(err) { + err = newMarshalErrorBefore(enc, t, err) + } + return err } return nil } - case jsonMarshalerV1Type: + } + + if needAddr, ok := implements(t, textAppenderType); ok { fncs.nonDefault = true - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - marshaler := va.addrWhen(needAddr).Interface().(MarshalerV1) - val, err := marshaler.MarshalJSON() - if err != nil { - err = wrapSkipFunc(err, "marshal method") - // TODO: Avoid wrapping semantic errors. - return &SemanticError{action: "marshal", GoType: t, Err: err} + prevMarshal := fncs.marshal + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) (err error) { + if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + (needAddr && va.forcedAddr) { + return prevMarshal(enc, va, mo) } - if err := enc.WriteValue(val); err != nil { - // TODO: Avoid wrapping semantic or I/O errors. - return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err} + appender := va.Addr().Interface().(encoding.TextAppender) + if err := export.Encoder(enc).AppendRaw('"', false, appender.AppendText); err != nil { + err = wrapSkipFunc(err, "append method") + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "AppendText") // unlike unmarshal, always wrapped + } + if !isSemanticError(err) && !export.IsIOError(err) { + err = newMarshalErrorBefore(enc, t, err) + } + return err } return nil } - case textMarshalerType: + } + + if needAddr, ok := implements(t, jsonMarshalerType); ok { fncs.nonDefault = true - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - marshaler := va.addrWhen(needAddr).Interface().(encoding.TextMarshaler) - s, err := marshaler.MarshalText() - if err != nil { - err = wrapSkipFunc(err, "marshal method") - // TODO: Avoid wrapping semantic errors. - return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err} + prevMarshal := fncs.marshal + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + ((needAddr && va.forcedAddr) || export.Encoder(enc).Tokens.Last.NeedObjectName()) { + return prevMarshal(enc, va, mo) } - val := enc.UnusedBuffer() - val, err = appendString(val, string(s), true, nil) + marshaler := va.Addr().Interface().(Marshaler) + val, err := marshaler.MarshalJSON() if err != nil { - return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err} + err = wrapSkipFunc(err, "marshal method") + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSON") // unlike unmarshal, always wrapped + } + err = newMarshalErrorBefore(enc, t, err) + return collapseSemanticErrors(err) } if err := enc.WriteValue(val); err != nil { - // TODO: Avoid wrapping syntactic or I/O errors. - return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err} + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSON") // unlike unmarshal, always wrapped + } + if isSyntacticError(err) { + err = newMarshalErrorBefore(enc, t, err) + } + return err } return nil } } - // Handle custom unmarshaler. - switch which, needAddr := implementsWhich(t, jsonUnmarshalerV2Type, jsonUnmarshalerV1Type, textUnmarshalerType); which { - case jsonUnmarshalerV2Type: + if needAddr, ok := implements(t, jsonMarshalerToType); ok { fncs.nonDefault = true - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - prevDepth, prevLength := dec.tokens.depthLength() - err := va.addrWhen(needAddr).Interface().(UnmarshalerV2).UnmarshalNextJSON(uo, dec) - currDepth, currLength := dec.tokens.depthLength() + prevMarshal := fncs.marshal + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + if mo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + ((needAddr && va.forcedAddr) || export.Encoder(enc).Tokens.Last.NeedObjectName()) { + return prevMarshal(enc, va, mo) + } + xe := export.Encoder(enc) + prevDepth, prevLength := xe.Tokens.DepthLength() + xe.Flags.Set(jsonflags.WithinArshalCall | 1) + err := va.Addr().Interface().(MarshalerTo).MarshalJSONTo(enc) + xe.Flags.Set(jsonflags.WithinArshalCall | 0) + currDepth, currLength := xe.Tokens.DepthLength() if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil { - err = errors.New("must read exactly one JSON value") + err = errNonSingularValue + } + if err != nil { + err = wrapSkipFunc(err, "marshal method") + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSONTo") // unlike unmarshal, always wrapped + } + if !export.IsIOError(err) { + err = newSemanticErrorWithPosition(enc, t, prevDepth, prevLength, err) + } + return err } + return nil + } + } + + if _, ok := implements(t, textUnmarshalerType); ok { + fncs.nonDefault = true + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + var flags jsonwire.ValueFlags + val, err := xd.ReadValue(&flags) if err != nil { + return err // must be a syntactic or I/O error + } + if val.Kind() == 'n' { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetZero() + } + return nil + } + if val.Kind() != '"' { + return newUnmarshalErrorAfter(dec, t, errNonStringValue) + } + s := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + unmarshaler := va.Addr().Interface().(encoding.TextUnmarshaler) + if err := unmarshaler.UnmarshalText(s); err != nil { err = wrapSkipFunc(err, "unmarshal method") - // TODO: Avoid wrapping semantic, syntactic, or I/O errors. - return &SemanticError{action: "unmarshal", GoType: t, Err: err} + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err // unlike marshal, never wrapped + } + if !isSemanticError(err) && !isSyntacticError(err) && !export.IsIOError(err) { + err = newUnmarshalErrorAfter(dec, t, err) + } + return err } return nil } - case jsonUnmarshalerV1Type: + } + + if _, ok := implements(t, jsonUnmarshalerType); ok { fncs.nonDefault = true - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { + prevUnmarshal := fncs.unmarshal + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + if uo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + export.Decoder(dec).Tokens.Last.NeedObjectName() { + return prevUnmarshal(dec, va, uo) + } val, err := dec.ReadValue() if err != nil { return err // must be a syntactic or I/O error } - unmarshaler := va.addrWhen(needAddr).Interface().(UnmarshalerV1) + unmarshaler := va.Addr().Interface().(Unmarshaler) if err := unmarshaler.UnmarshalJSON(val); err != nil { err = wrapSkipFunc(err, "unmarshal method") - // TODO: Avoid wrapping semantic, syntactic, or I/O errors. - return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err // unlike marshal, never wrapped + } + err = newUnmarshalErrorAfter(dec, t, err) + return collapseSemanticErrors(err) } return nil } - case textUnmarshalerType: + } + + if _, ok := implements(t, jsonUnmarshalerFromType); ok { fncs.nonDefault = true - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - var flags valueFlags - val, err := dec.readValue(&flags) - if err != nil { - return err // must be a syntactic or I/O error + prevUnmarshal := fncs.unmarshal + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + if uo.Flags.Get(jsonflags.CallMethodsWithLegacySemantics) && + export.Decoder(dec).Tokens.Last.NeedObjectName() { + return prevUnmarshal(dec, va, uo) } - if val.Kind() != '"' { - err = errors.New("JSON value must be string type") - return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + xd := export.Decoder(dec) + prevDepth, prevLength := xd.Tokens.DepthLength() + xd.Flags.Set(jsonflags.WithinArshalCall | 1) + err := va.Addr().Interface().(UnmarshalerFrom).UnmarshalJSONFrom(dec) + xd.Flags.Set(jsonflags.WithinArshalCall | 0) + currDepth, currLength := xd.Tokens.DepthLength() + if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil { + err = errNonSingularValue } - s := unescapeStringMayCopy(val, flags.isVerbatim()) - unmarshaler := va.addrWhen(needAddr).Interface().(encoding.TextUnmarshaler) - if err := unmarshaler.UnmarshalText(s); err != nil { + if err != nil { err = wrapSkipFunc(err, "unmarshal method") - // TODO: Avoid wrapping semantic, syntactic, or I/O errors. - return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + if err2 := xd.SkipUntil(prevDepth, prevLength+1); err2 != nil { + return err2 + } + return err // unlike marshal, never wrapped + } + if !isSyntacticError(err) && !export.IsIOError(err) { + err = newSemanticErrorWithPosition(dec, t, prevDepth, prevLength, err) + } + return err } return nil } @@ -204,26 +308,28 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { return fncs } -// implementsWhich is like t.Implements(ifaceType) for a list of interfaces, +// implementsAny is like t.Implements(ifaceType) for a list of interfaces, // but checks whether either t or reflect.PointerTo(t) implements the interface. -// It returns the first interface type that matches and whether a value of t -// needs to be addressed first before it implements the interface. -func implementsWhich(t reflect.Type, ifaceTypes ...reflect.Type) (which reflect.Type, needAddr bool) { +func implementsAny(t reflect.Type, ifaceTypes ...reflect.Type) bool { for _, ifaceType := range ifaceTypes { - switch { - case t.Implements(ifaceType): - return ifaceType, false - case reflect.PointerTo(t).Implements(ifaceType): - return ifaceType, true + if _, ok := implements(t, ifaceType); ok { + return true } } - return nil, false + return false } -// addrWhen returns va.Addr if addr is specified, otherwise it returns itself. -func (va addressableValue) addrWhen(addr bool) reflect.Value { - if addr { - return va.Addr() +// implements is like t.Implements(ifaceType) but checks whether +// either t or reflect.PointerTo(t) implements the interface. +// It also reports whether the value needs to be addressed +// in order to satisfy the interface. +func implements(t, ifaceType reflect.Type) (needAddr, ok bool) { + switch { + case t.Implements(ifaceType): + return false, true + case reflect.PointerTo(t).Implements(ifaceType): + return true, true + default: + return false, false } - return va.Value } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go index fc8d5b00..30dd584d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go @@ -5,20 +5,31 @@ package json import ( + "bytes" + "cmp" "errors" "fmt" + "math" + "math/bits" "reflect" + "strconv" "strings" "time" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) var ( - timeDurationType = reflect.TypeOf((*time.Duration)(nil)).Elem() - timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem() + timeDurationType = reflect.TypeFor[time.Duration]() + timeTimeType = reflect.TypeFor[time.Time]() ) func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { - // Ideally, time types would implement MarshalerV2 and UnmarshalerV2, + // Ideally, time types would implement MarshalerTo and UnmarshalerFrom, // but that would incur a dependency on package json from package time. // Given how widely used time is, it is more acceptable that we incur a // dependency on time from json. @@ -29,213 +40,736 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { switch t { case timeDurationType: fncs.nonDefault = true - marshalNanos := fncs.marshal - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - if mo.format == "nanos" { - mo.format = "" - return marshalNanos(mo, enc, va) - } else { - return newInvalidFormatError("marshal", t, mo.format) + marshalNano := fncs.marshal + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { + xe := export.Encoder(enc) + var m durationArshaler + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + if !m.initFormat(mo.Format) { + return newInvalidFormatError(enc, t) } + } else if mo.Flags.Get(jsonflags.FormatDurationAsNano) { + return marshalNano(enc, va, mo) + } else { + // TODO(https://go.dev/issue/71631): Decide on default duration representation. + return newMarshalErrorBefore(enc, t, errors.New("no default representation (see https://go.dev/issue/71631); specify an explicit format")) } - td := va.Interface().(time.Duration) - b := enc.UnusedBuffer() - b = append(b, '"') - b = append(b, td.String()...) // never contains special characters - b = append(b, '"') - return enc.WriteValue(b) - } - unmarshalNanos := fncs.unmarshal - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - // TODO: Should there be a flag that specifies that we can unmarshal - // from either form since there would be no ambiguity? - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - if uo.format == "nanos" { - uo.format = "" - return unmarshalNanos(uo, dec, va) - } else { - return newInvalidFormatError("unmarshal", t, uo.format) + // TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo. + m.td = *va.Addr().Interface().(*time.Duration) + k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + if err := xe.AppendRaw(k, true, m.appendMarshal); err != nil { + if !isSyntacticError(err) && !export.IsIOError(err) { + err = newMarshalErrorBefore(enc, t, err) + } + return err + } + return nil + } + unmarshalNano := fncs.unmarshal + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + xd := export.Decoder(dec) + var u durationArshaler + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + if !u.initFormat(uo.Format) { + return newInvalidFormatError(dec, t) } + } else if uo.Flags.Get(jsonflags.FormatDurationAsNano) { + return unmarshalNano(dec, va, uo) + } else { + // TODO(https://go.dev/issue/71631): Decide on default duration representation. + return newUnmarshalErrorBeforeWithSkipping(dec, t, errors.New("no default representation (see https://go.dev/issue/71631); specify an explicit format")) } - var flags valueFlags + stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + var flags jsonwire.ValueFlags td := va.Addr().Interface().(*time.Duration) - val, err := dec.readValue(&flags) + val, err := xd.ReadValue(&flags) if err != nil { return err } switch k := val.Kind(); k { case 'n': - *td = time.Duration(0) + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + *td = time.Duration(0) + } return nil case '"': - val = unescapeStringMayCopy(val, flags.isVerbatim()) - td2, err := time.ParseDuration(string(val)) - if err != nil { - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + if !stringify { + break + } + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + if err := u.unmarshal(val); err != nil { + return newUnmarshalErrorAfter(dec, t, err) + } + *td = u.td + return nil + case '0': + if stringify { + break + } + if err := u.unmarshal(val); err != nil { + return newUnmarshalErrorAfter(dec, t, err) } - *td = td2 + *td = u.td return nil - default: - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} } + return newUnmarshalErrorAfter(dec, t, nil) } case timeTimeType: fncs.nonDefault = true - fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { - format := time.RFC3339Nano - isRFC3339 := true - if mo.format != "" && mo.formatDepth == enc.tokens.depth() { - var err error - format, isRFC3339, err = checkTimeFormat(mo.format) - if err != nil { - return &SemanticError{action: "marshal", GoType: t, Err: err} + fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) (err error) { + xe := export.Encoder(enc) + var m timeArshaler + if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + if !m.initFormat(mo.Format) { + return newInvalidFormatError(enc, t) } } - tt := va.Interface().(time.Time) - b := enc.UnusedBuffer() - b = append(b, '"') - b = tt.AppendFormat(b, format) - b = append(b, '"') - if isRFC3339 { - // Not all Go timestamps can be represented as valid RFC 3339. - // Explicitly check for these edge cases. - // See https://go.dev/issue/4556 and https://go.dev/issue/54580. - var err error - switch b := b[len(`"`) : len(b)-len(`"`)]; { - case b[len("9999")] != '-': // year must be exactly 4 digits wide - err = errors.New("year outside of range [0,9999]") - case b[len(b)-1] != 'Z': - c := b[len(b)-len("Z07:00")] - if ('0' <= c && c <= '9') || parseDec2(b[len(b)-len("07:00"):]) >= 24 { - err = errors.New("timezone hour outside of range [0,23]") - } + // TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo. + m.tt = *va.Addr().Interface().(*time.Time) + k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + if err := xe.AppendRaw(k, !m.hasCustomFormat(), m.appendMarshal); err != nil { + if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSON") // unlike unmarshal, always wrapped } - if err != nil { - return &SemanticError{action: "marshal", GoType: t, Err: err} + if !isSyntacticError(err) && !export.IsIOError(err) { + err = newMarshalErrorBefore(enc, t, err) } - return enc.WriteValue(b) // RFC 3339 never needs JSON escaping - } - // The format may contain special characters that need escaping. - // Verify that the result is a valid JSON string (common case), - // otherwise escape the string correctly (slower case). - if consumeSimpleString(b) != len(b) { - b, _ = appendString(nil, string(b[len(`"`):len(b)-len(`"`)]), true, nil) + return err } - return enc.WriteValue(b) + return nil } - fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - format := time.RFC3339 - isRFC3339 := true - if uo.format != "" && uo.formatDepth == dec.tokens.depth() { - var err error - format, isRFC3339, err = checkTimeFormat(uo.format) - if err != nil { - return &SemanticError{action: "unmarshal", GoType: t, Err: err} + fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) (err error) { + xd := export.Decoder(dec) + var u timeArshaler + if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + if !u.initFormat(uo.Format) { + return newInvalidFormatError(dec, t) } + } else if uo.Flags.Get(jsonflags.ParseTimeWithLooseRFC3339) { + u.looseRFC3339 = true } - var flags valueFlags + stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + var flags jsonwire.ValueFlags tt := va.Addr().Interface().(*time.Time) - val, err := dec.readValue(&flags) + val, err := xd.ReadValue(&flags) if err != nil { return err } - k := val.Kind() - switch k { + switch k := val.Kind(); k { case 'n': - *tt = time.Time{} + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + *tt = time.Time{} + } return nil case '"': - val = unescapeStringMayCopy(val, flags.isVerbatim()) - tt2, err := time.Parse(format, string(val)) - if isRFC3339 && err == nil { - // TODO(https://go.dev/issue/54580): RFC 3339 specifies - // the exact grammar of a valid timestamp. However, - // the parsing functionality in "time" is too loose and - // incorrectly accepts invalid timestamps as valid. - // Remove these manual checks when "time" checks it for us. - newParseError := func(layout, value, layoutElem, valueElem, message string) error { - return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message} - } - switch { - case val[len("2006-01-02T")+1] == ':': // hour must be two digits - err = newParseError(format, string(val), "15", string(val[len("2006-01-02T"):][:1]), "") - case val[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period - err = newParseError(format, string(val), ".", ",", "") - case val[len(val)-1] != 'Z': - switch { - case parseDec2(val[len(val)-len("07:00"):]) >= 24: // timezone hour must be in range - err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone hour out of range") - case parseDec2(val[len(val)-len("00"):]) >= 60: // timezone minute must be in range - err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone minute out of range") - } + if !stringify { + break + } + val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) + if err := u.unmarshal(val); err != nil { + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err // unlike marshal, never wrapped } + return newUnmarshalErrorAfter(dec, t, err) + } + *tt = u.tt + return nil + case '0': + if stringify { + break } - if err != nil { - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} + if err := u.unmarshal(val); err != nil { + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return err // unlike marshal, never wrapped + } + return newUnmarshalErrorAfter(dec, t, err) } - *tt = tt2 + *tt = u.tt return nil - default: - return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} } + return newUnmarshalErrorAfter(dec, t, nil) } } return fncs } -func checkTimeFormat(format string) (string, bool, error) { +type durationArshaler struct { + td time.Duration + + // base records the representation where: + // - 0 uses time.Duration.String + // - 1e0, 1e3, 1e6, or 1e9 use a decimal encoding of the duration as + // nanoseconds, microseconds, milliseconds, or seconds. + // - 8601 uses ISO 8601 + base uint64 +} + +func (a *durationArshaler) initFormat(format string) (ok bool) { + switch format { + case "units": + a.base = 0 + case "sec": + a.base = 1e9 + case "milli": + a.base = 1e6 + case "micro": + a.base = 1e3 + case "nano": + a.base = 1e0 + case "iso8601": + a.base = 8601 + default: + return false + } + return true +} + +func (a *durationArshaler) isNumeric() bool { + return a.base != 0 && a.base != 8601 +} + +func (a *durationArshaler) appendMarshal(b []byte) ([]byte, error) { + switch a.base { + case 0: + return append(b, a.td.String()...), nil + case 8601: + return appendDurationISO8601(b, a.td), nil + default: + return appendDurationBase10(b, a.td, a.base), nil + } +} + +func (a *durationArshaler) unmarshal(b []byte) (err error) { + switch a.base { + case 0: + a.td, err = time.ParseDuration(string(b)) + case 8601: + a.td, err = parseDurationISO8601(b) + default: + a.td, err = parseDurationBase10(b, a.base) + } + return err +} + +type timeArshaler struct { + tt time.Time + + // base records the representation where: + // - 0 uses RFC 3339 encoding of the timestamp + // - 1e0, 1e3, 1e6, or 1e9 use a decimal encoding of the timestamp as + // seconds, milliseconds, microseconds, or nanoseconds since Unix epoch. + // - math.MaxUint uses time.Time.Format to encode the timestamp + base uint64 + format string // time format passed to time.Parse + + looseRFC3339 bool +} + +func (a *timeArshaler) initFormat(format string) bool { // We assume that an exported constant in the time package will // always start with an uppercase ASCII letter. - if len(format) > 0 && 'A' <= format[0] && format[0] <= 'Z' { - switch format { - case "ANSIC": - return time.ANSIC, false, nil - case "UnixDate": - return time.UnixDate, false, nil - case "RubyDate": - return time.RubyDate, false, nil - case "RFC822": - return time.RFC822, false, nil - case "RFC822Z": - return time.RFC822Z, false, nil - case "RFC850": - return time.RFC850, false, nil - case "RFC1123": - return time.RFC1123, false, nil - case "RFC1123Z": - return time.RFC1123Z, false, nil - case "RFC3339": - return time.RFC3339, true, nil - case "RFC3339Nano": - return time.RFC3339Nano, true, nil - case "Kitchen": - return time.Kitchen, false, nil - case "Stamp": - return time.Stamp, false, nil - case "StampMilli": - return time.StampMilli, false, nil - case "StampMicro": - return time.StampMicro, false, nil - case "StampNano": - return time.StampNano, false, nil - default: - // Reject any format that is an exported Go identifier in case - // new format constants are added to the time package. - if strings.TrimFunc(format, isLetterOrDigit) == "" { - return "", false, fmt.Errorf("undefined format layout: %v", format) + if len(format) == 0 { + return false + } + a.base = math.MaxUint // implies custom format + if c := format[0]; !('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') { + a.format = format + return true + } + switch format { + case "ANSIC": + a.format = time.ANSIC + case "UnixDate": + a.format = time.UnixDate + case "RubyDate": + a.format = time.RubyDate + case "RFC822": + a.format = time.RFC822 + case "RFC822Z": + a.format = time.RFC822Z + case "RFC850": + a.format = time.RFC850 + case "RFC1123": + a.format = time.RFC1123 + case "RFC1123Z": + a.format = time.RFC1123Z + case "RFC3339": + a.base = 0 + a.format = time.RFC3339 + case "RFC3339Nano": + a.base = 0 + a.format = time.RFC3339Nano + case "Kitchen": + a.format = time.Kitchen + case "Stamp": + a.format = time.Stamp + case "StampMilli": + a.format = time.StampMilli + case "StampMicro": + a.format = time.StampMicro + case "StampNano": + a.format = time.StampNano + case "DateTime": + a.format = time.DateTime + case "DateOnly": + a.format = time.DateOnly + case "TimeOnly": + a.format = time.TimeOnly + case "unix": + a.base = 1e0 + case "unixmilli": + a.base = 1e3 + case "unixmicro": + a.base = 1e6 + case "unixnano": + a.base = 1e9 + default: + // Reject any Go identifier in case new constants are supported. + if strings.TrimFunc(format, isLetterOrDigit) == "" { + return false + } + a.format = format + } + return true +} + +func (a *timeArshaler) isNumeric() bool { + return int(a.base) > 0 +} + +func (a *timeArshaler) hasCustomFormat() bool { + return a.base == math.MaxUint +} + +func (a *timeArshaler) appendMarshal(b []byte) ([]byte, error) { + switch a.base { + case 0: + format := cmp.Or(a.format, time.RFC3339Nano) + n0 := len(b) + b = a.tt.AppendFormat(b, format) + // Not all Go timestamps can be represented as valid RFC 3339. + // Explicitly check for these edge cases. + // See https://go.dev/issue/4556 and https://go.dev/issue/54580. + switch b := b[n0:]; { + case b[len("9999")] != '-': // year must be exactly 4 digits wide + return b, errors.New("year outside of range [0,9999]") + case b[len(b)-1] != 'Z': + c := b[len(b)-len("Z07:00")] + if ('0' <= c && c <= '9') || parseDec2(b[len(b)-len("07:00"):]) >= 24 { + return b, errors.New("timezone hour outside of range [0,23]") } } + return b, nil + case math.MaxUint: + return a.tt.AppendFormat(b, a.format), nil + default: + return appendTimeUnix(b, a.tt, a.base), nil } - return format, false, nil +} + +func (a *timeArshaler) unmarshal(b []byte) (err error) { + switch a.base { + case 0: + // Use time.Time.UnmarshalText to avoid possible string allocation. + if err := a.tt.UnmarshalText(b); err != nil { + return err + } + // TODO(https://go.dev/issue/57912): + // RFC 3339 specifies the grammar for a valid timestamp. + // However, the parsing functionality in "time" is too loose and + // incorrectly accepts invalid timestamps as valid. + // Remove these manual checks when "time" checks it for us. + newParseError := func(layout, value, layoutElem, valueElem, message string) error { + return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message} + } + switch { + case a.looseRFC3339: + return nil + case b[len("2006-01-02T")+1] == ':': // hour must be two digits + return newParseError(time.RFC3339, string(b), "15", string(b[len("2006-01-02T"):][:1]), "") + case b[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period + return newParseError(time.RFC3339, string(b), ".", ",", "") + case b[len(b)-1] != 'Z': + switch { + case parseDec2(b[len(b)-len("07:00"):]) >= 24: // timezone hour must be in range + return newParseError(time.RFC3339, string(b), "Z07:00", string(b[len(b)-len("Z07:00"):]), ": timezone hour out of range") + case parseDec2(b[len(b)-len("00"):]) >= 60: // timezone minute must be in range + return newParseError(time.RFC3339, string(b), "Z07:00", string(b[len(b)-len("Z07:00"):]), ": timezone minute out of range") + } + } + return nil + case math.MaxUint: + a.tt, err = time.Parse(a.format, string(b)) + return err + default: + a.tt, err = parseTimeUnix(b, a.base) + return err + } +} + +// appendDurationBase10 appends d formatted as a decimal fractional number, +// where pow10 is a power-of-10 used to scale down the number. +func appendDurationBase10(b []byte, d time.Duration, pow10 uint64) []byte { + b, n := mayAppendDurationSign(b, d) // append sign + whole, frac := bits.Div64(0, n, uint64(pow10)) // compute whole and frac fields + b = strconv.AppendUint(b, whole, 10) // append whole field + return appendFracBase10(b, frac, pow10) // append frac field +} + +// parseDurationBase10 parses d from a decimal fractional number, +// where pow10 is a power-of-10 used to scale up the number. +func parseDurationBase10(b []byte, pow10 uint64) (time.Duration, error) { + suffix, neg := consumeSign(b, false) // consume sign + wholeBytes, fracBytes := bytesCutByte(suffix, '.', true) // consume whole and frac fields + whole, okWhole := jsonwire.ParseUint(wholeBytes) // parse whole field; may overflow + frac, okFrac := parseFracBase10(fracBytes, pow10) // parse frac field + hi, lo := bits.Mul64(whole, uint64(pow10)) // overflow if hi > 0 + sum, co := bits.Add64(lo, uint64(frac), 0) // overflow if co > 0 + switch d := mayApplyDurationSign(sum, neg); { // overflow if neg != (d < 0) + case (!okWhole && whole != math.MaxUint64) || !okFrac: + return 0, fmt.Errorf("invalid duration %q: %w", b, strconv.ErrSyntax) + case !okWhole || hi > 0 || co > 0 || neg != (d < 0): + return 0, fmt.Errorf("invalid duration %q: %w", b, strconv.ErrRange) + default: + return d, nil + } +} + +// appendDurationISO8601 appends an ISO 8601 duration with a restricted grammar, +// where leading and trailing zeroes and zero-value designators are omitted. +// It only uses hour, minute, and second designators since ISO 8601 defines +// those as being "accurate", while year, month, week, and day are "nominal". +func appendDurationISO8601(b []byte, d time.Duration) []byte { + if d == 0 { + return append(b, "PT0S"...) + } + b, n := mayAppendDurationSign(b, d) + b = append(b, "PT"...) + n, nsec := bits.Div64(0, n, 1e9) // compute nsec field + n, sec := bits.Div64(0, n, 60) // compute sec field + hour, min := bits.Div64(0, n, 60) // compute hour and min fields + if hour > 0 { + b = append(strconv.AppendUint(b, hour, 10), 'H') + } + if min > 0 { + b = append(strconv.AppendUint(b, min, 10), 'M') + } + if sec > 0 || nsec > 0 { + b = append(appendFracBase10(strconv.AppendUint(b, sec, 10), nsec, 1e9), 'S') + } + return b +} + +// daysPerYear is the exact average number of days in a year according to +// the Gregorian calender, which has an extra day each year that is +// a multiple of 4, unless it is evenly divisible by 100 but not by 400. +// This does not take into account leap seconds, which are not deterministic. +const daysPerYear = 365.2425 + +var errInaccurateDateUnits = errors.New("inaccurate year, month, week, or day units") + +// parseDurationISO8601 parses a duration according to ISO 8601-1:2019, +// section 5.5.2.2 and 5.5.2.3 with the following restrictions or extensions: +// +// - A leading minus sign is permitted for negative duration according +// to ISO 8601-2:2019, section 4.4.1.9. We do not permit negative values +// for each "time scale component", which is permitted by section 4.4.1.1, +// but rarely supported by parsers. +// +// - A leading plus sign is permitted (and ignored). +// This is not required by ISO 8601, but not forbidden either. +// There is some precedent for this as it is supported by the principle of +// duration arithmetic as specified in ISO 8601-2-2019, section 14.1. +// Of note, the JavaScript grammar for ISO 8601 permits a leading plus sign. +// +// - A fractional value is only permitted for accurate units +// (i.e., hour, minute, and seconds) in the last time component, +// which is permissible by ISO 8601-1:2019, section 5.5.2.3. +// +// - Both periods ('.') and commas (',') are supported as the separator +// between the integer part and fraction part of a number, +// as specified in ISO 8601-1:2019, section 3.2.6. +// While ISO 8601 recommends comma as the default separator, +// most formatters uses a period. +// +// - Leading zeros are ignored. This is not required by ISO 8601, +// but also not forbidden by the standard. Many parsers support this. +// +// - Lowercase designators are supported. This is not required by ISO 8601, +// but also not forbidden by the standard. Many parsers support this. +// +// If the nominal units of year, month, week, or day are present, +// this produces a best-effort value and also reports [errInaccurateDateUnits]. +// +// The accepted grammar is identical to JavaScript's Duration: +// +// https://tc39.es/proposal-temporal/#prod-Duration +// +// We follow JavaScript's grammar as JSON itself is derived from JavaScript. +// The Temporal.Duration.toJSON method is guaranteed to produce an output +// that can be parsed by this function so long as arithmetic in JavaScript +// do not use a largestUnit value higher than "hours" (which is the default). +// Even if it does, this will do a best-effort parsing with inaccurate units, +// but report [errInaccurateDateUnits]. +func parseDurationISO8601(b []byte) (time.Duration, error) { + var invalid, overflow, inaccurate, sawFrac bool + var sumNanos, n, co uint64 + + // cutBytes is like [bytes.Cut], but uses either c0 or c1 as the separator. + cutBytes := func(b []byte, c0, c1 byte) (prefix, suffix []byte, ok bool) { + for i, c := range b { + if c == c0 || c == c1 { + return b[:i], b[i+1:], true + } + } + return b, nil, false + } + + // mayParseUnit attempts to parse another date or time number + // identified by the desHi and desLo unit characters. + // If the part is absent for current unit, it returns b as is. + mayParseUnit := func(b []byte, desHi, desLo byte, unit time.Duration) []byte { + number, suffix, ok := cutBytes(b, desHi, desLo) + if !ok || sawFrac { + return b // designator is not present or already saw fraction, which can only be in the last component + } + + // Parse the number. + // A fraction allowed for the accurate units in the last part. + whole, frac, ok := cutBytes(number, '.', ',') + if ok { + sawFrac = true + invalid = invalid || len(frac) == len("") || unit > time.Hour + if unit == time.Second { + n, ok = parsePaddedBase10(frac, uint64(time.Second)) + invalid = invalid || !ok + } else { + f, err := strconv.ParseFloat("0."+string(frac), 64) + invalid = invalid || err != nil || len(bytes.Trim(frac[len("."):], "0123456789")) > 0 + n = uint64(math.Round(f * float64(unit))) // never overflows since f is within [0..1] + } + sumNanos, co = bits.Add64(sumNanos, n, 0) // overflow if co > 0 + overflow = overflow || co > 0 + } + for len(whole) > 1 && whole[0] == '0' { + whole = whole[len("0"):] // trim leading zeros + } + n, ok := jsonwire.ParseUint(whole) // overflow if !ok && MaxUint64 + hi, lo := bits.Mul64(n, uint64(unit)) // overflow if hi > 0 + sumNanos, co = bits.Add64(sumNanos, lo, 0) // overflow if co > 0 + invalid = invalid || (!ok && n != math.MaxUint64) + overflow = overflow || (!ok && n == math.MaxUint64) || hi > 0 || co > 0 + inaccurate = inaccurate || unit > time.Hour + return suffix + } + + suffix, neg := consumeSign(b, true) + prefix, suffix, okP := cutBytes(suffix, 'P', 'p') + durDate, durTime, okT := cutBytes(suffix, 'T', 't') + invalid = invalid || len(prefix) > 0 || !okP || (okT && len(durTime) == 0) || len(durDate)+len(durTime) == 0 + if len(durDate) > 0 { // nominal portion of the duration + durDate = mayParseUnit(durDate, 'Y', 'y', time.Duration(daysPerYear*24*60*60*1e9)) + durDate = mayParseUnit(durDate, 'M', 'm', time.Duration(daysPerYear/12*24*60*60*1e9)) + durDate = mayParseUnit(durDate, 'W', 'w', time.Duration(7*24*60*60*1e9)) + durDate = mayParseUnit(durDate, 'D', 'd', time.Duration(24*60*60*1e9)) + invalid = invalid || len(durDate) > 0 // unknown elements + } + if len(durTime) > 0 { // accurate portion of the duration + durTime = mayParseUnit(durTime, 'H', 'h', time.Duration(60*60*1e9)) + durTime = mayParseUnit(durTime, 'M', 'm', time.Duration(60*1e9)) + durTime = mayParseUnit(durTime, 'S', 's', time.Duration(1e9)) + invalid = invalid || len(durTime) > 0 // unknown elements + } + d := mayApplyDurationSign(sumNanos, neg) + overflow = overflow || (neg != (d < 0) && d != 0) // overflows signed duration + + switch { + case invalid: + return 0, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, strconv.ErrSyntax) + case overflow: + return 0, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, strconv.ErrRange) + case inaccurate: + return d, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, errInaccurateDateUnits) + default: + return d, nil + } +} + +// mayAppendDurationSign appends a negative sign if n is negative. +func mayAppendDurationSign(b []byte, d time.Duration) ([]byte, uint64) { + if d < 0 { + b = append(b, '-') + d *= -1 + } + return b, uint64(d) +} + +// mayApplyDurationSign inverts n if neg is specified. +func mayApplyDurationSign(n uint64, neg bool) time.Duration { + if neg { + return -1 * time.Duration(n) + } else { + return +1 * time.Duration(n) + } +} + +// appendTimeUnix appends t formatted as a decimal fractional number, +// where pow10 is a power-of-10 used to scale up the number. +func appendTimeUnix(b []byte, t time.Time, pow10 uint64) []byte { + sec, nsec := t.Unix(), int64(t.Nanosecond()) + if sec < 0 { + b = append(b, '-') + sec, nsec = negateSecNano(sec, nsec) + } + switch { + case pow10 == 1e0: // fast case where units is in seconds + b = strconv.AppendUint(b, uint64(sec), 10) + return appendFracBase10(b, uint64(nsec), 1e9) + case uint64(sec) < 1e9: // intermediate case where units is not seconds, but no overflow + b = strconv.AppendUint(b, uint64(sec)*uint64(pow10)+uint64(uint64(nsec)/(1e9/pow10)), 10) + return appendFracBase10(b, (uint64(nsec)*pow10)%1e9, 1e9) + default: // slow case where units is not seconds and overflow would occur + b = strconv.AppendUint(b, uint64(sec), 10) + b = appendPaddedBase10(b, uint64(nsec)/(1e9/pow10), pow10) + return appendFracBase10(b, (uint64(nsec)*pow10)%1e9, 1e9) + } +} + +// parseTimeUnix parses t formatted as a decimal fractional number, +// where pow10 is a power-of-10 used to scale down the number. +func parseTimeUnix(b []byte, pow10 uint64) (time.Time, error) { + suffix, neg := consumeSign(b, false) // consume sign + wholeBytes, fracBytes := bytesCutByte(suffix, '.', true) // consume whole and frac fields + whole, okWhole := jsonwire.ParseUint(wholeBytes) // parse whole field; may overflow + frac, okFrac := parseFracBase10(fracBytes, 1e9/pow10) // parse frac field + var sec, nsec int64 + switch { + case pow10 == 1e0: // fast case where units is in seconds + sec = int64(whole) // check overflow later after negation + nsec = int64(frac) // cannot overflow + case okWhole: // intermediate case where units is not seconds, but no overflow + sec = int64(whole / pow10) // check overflow later after negation + nsec = int64((whole%pow10)*(1e9/pow10) + frac) // cannot overflow + case !okWhole && whole == math.MaxUint64: // slow case where units is not seconds and overflow occurred + width := int(math.Log10(float64(pow10))) // compute len(strconv.Itoa(pow10-1)) + whole, okWhole = jsonwire.ParseUint(wholeBytes[:len(wholeBytes)-width]) // parse the upper whole field + mid, _ := parsePaddedBase10(wholeBytes[len(wholeBytes)-width:], pow10) // parse the lower whole field + sec = int64(whole) // check overflow later after negation + nsec = int64(mid*(1e9/pow10) + frac) // cannot overflow + } + if neg { + sec, nsec = negateSecNano(sec, nsec) + } + switch t := time.Unix(sec, nsec).UTC(); { + case (!okWhole && whole != math.MaxUint64) || !okFrac: + return time.Time{}, fmt.Errorf("invalid time %q: %w", b, strconv.ErrSyntax) + case !okWhole || neg != (t.Unix() < 0): + return time.Time{}, fmt.Errorf("invalid time %q: %w", b, strconv.ErrRange) + default: + return t, nil + } +} + +// negateSecNano negates a Unix timestamp, where nsec must be within [0, 1e9). +func negateSecNano(sec, nsec int64) (int64, int64) { + sec = ^sec // twos-complement negation (i.e., -1*sec + 1) + nsec = -nsec + 1e9 // negate nsec and add 1e9 (which is the extra +1 from sec negation) + sec += int64(nsec / 1e9) // handle possible overflow of nsec if it started as zero + nsec %= 1e9 // ensure nsec stays within [0, 1e9) + return sec, nsec +} + +// appendFracBase10 appends the fraction of n/max10, +// where max10 is a power-of-10 that is larger than n. +func appendFracBase10(b []byte, n, max10 uint64) []byte { + if n == 0 { + return b + } + return bytes.TrimRight(appendPaddedBase10(append(b, '.'), n, max10), "0") +} + +// parseFracBase10 parses the fraction of n/max10, +// where max10 is a power-of-10 that is larger than n. +func parseFracBase10(b []byte, max10 uint64) (n uint64, ok bool) { + switch { + case len(b) == 0: + return 0, true + case len(b) < len(".0") || b[0] != '.': + return 0, false + } + return parsePaddedBase10(b[len("."):], max10) +} + +// appendPaddedBase10 appends a zero-padded encoding of n, +// where max10 is a power-of-10 that is larger than n. +func appendPaddedBase10(b []byte, n, max10 uint64) []byte { + if n < max10/10 { + // Formatting of n is shorter than log10(max10), + // so add max10/10 to ensure the length is equal to log10(max10). + i := len(b) + b = strconv.AppendUint(b, n+max10/10, 10) + b[i]-- // subtract the addition of max10/10 + return b + } + return strconv.AppendUint(b, n, 10) +} + +// parsePaddedBase10 parses b as the zero-padded encoding of n, +// where max10 is a power-of-10 that is larger than n. +// Truncated suffix is treated as implicit zeros. +// Extended suffix is ignored, but verified to contain only digits. +func parsePaddedBase10(b []byte, max10 uint64) (n uint64, ok bool) { + pow10 := uint64(1) + for pow10 < max10 { + n *= 10 + if len(b) > 0 { + if b[0] < '0' || '9' < b[0] { + return n, false + } + n += uint64(b[0] - '0') + b = b[1:] + } + pow10 *= 10 + } + if len(b) > 0 && len(bytes.TrimRight(b, "0123456789")) > 0 { + return n, false // trailing characters are not digits + } + return n, true +} + +// consumeSign consumes an optional leading negative or positive sign. +func consumeSign(b []byte, allowPlus bool) ([]byte, bool) { + if len(b) > 0 { + if b[0] == '-' { + return b[len("-"):], true + } else if b[0] == '+' && allowPlus { + return b[len("+"):], false + } + } + return b, false +} + +// bytesCutByte is similar to bytes.Cut(b, []byte{c}), +// except c may optionally be included as part of the suffix. +func bytesCutByte(b []byte, c byte, include bool) ([]byte, []byte) { + if i := bytes.IndexByte(b, c); i >= 0 { + if include { + return b[:i], b[i:] + } + return b[:i], b[i+1:] + } + return b, nil } // parseDec2 parses b as an unsigned, base-10, 2-digit number. -// It panics if len(b) < 2. The result is undefined if digits are not base-10. +// The result is undefined if digits are not base-10. func parseDec2(b []byte) byte { + if len(b) < 2 { + return 0 + } return 10*(b[0]-'0') + (b[1] - '0') } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go deleted file mode 100644 index 0d68b323..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go +++ /dev/null @@ -1,1655 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package json - -import ( - "bytes" - "errors" - "io" - "math" - "strconv" - "unicode/utf16" - "unicode/utf8" -) - -// NOTE: The logic for decoding is complicated by the fact that reading from -// an io.Reader into a temporary buffer means that the buffer may contain a -// truncated portion of some valid input, requiring the need to fetch more data. -// -// This file is structured in the following way: -// -// - consumeXXX functions parse an exact JSON token from a []byte. -// If the buffer appears truncated, then it returns io.ErrUnexpectedEOF. -// The consumeSimpleXXX functions are so named because they only handle -// a subset of the grammar for the JSON token being parsed. -// They do not handle the full grammar to keep these functions inlineable. -// -// - Decoder.consumeXXX methods parse the next JSON token from Decoder.buf, -// automatically fetching more input if necessary. These methods take -// a position relative to the start of Decoder.buf as an argument and -// return the end of the consumed JSON token as a position, -// also relative to the start of Decoder.buf. -// -// - In the event of an I/O errors or state machine violations, -// the implementation avoids mutating the state of Decoder -// (aside from the book-keeping needed to implement Decoder.fetch). -// For this reason, only Decoder.ReadToken and Decoder.ReadValue are -// responsible for updated Decoder.prevStart and Decoder.prevEnd. -// -// - For performance, much of the implementation uses the pattern of calling -// the inlineable consumeXXX functions first, and if more work is necessary, -// then it calls the slower Decoder.consumeXXX methods. -// TODO: Revisit this pattern if the Go compiler provides finer control -// over exactly which calls are inlined or not. - -// DecodeOptions configures how JSON decoding operates. -// The zero value is equivalent to the default settings, -// which is compliant with both RFC 7493 and RFC 8259. -type DecodeOptions struct { - requireKeyedLiterals - nonComparable - - // AllowDuplicateNames specifies that JSON objects may contain - // duplicate member names. Disabling the duplicate name check may provide - // computational and performance benefits, but breaks compliance with - // RFC 7493, section 2.3. The input will still be compliant with RFC 8259, - // which leaves the handling of duplicate names as unspecified behavior. - AllowDuplicateNames bool - - // AllowInvalidUTF8 specifies that JSON strings may contain invalid UTF-8, - // which will be mangled as the Unicode replacement character, U+FFFD. - // This causes the decoder to break compliance with - // RFC 7493, section 2.1, and RFC 8259, section 8.1. - AllowInvalidUTF8 bool -} - -// Decoder is a streaming decoder for raw JSON tokens and values. -// It is used to read a stream of top-level JSON values, -// each separated by optional whitespace characters. -// -// ReadToken and ReadValue calls may be interleaved. -// For example, the following JSON value: -// -// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} -// -// can be parsed with the following calls (ignoring errors for brevity): -// -// d.ReadToken() // { -// d.ReadToken() // "name" -// d.ReadToken() // "value" -// d.ReadValue() // "array" -// d.ReadToken() // [ -// d.ReadToken() // null -// d.ReadToken() // false -// d.ReadValue() // true -// d.ReadToken() // 3.14159 -// d.ReadToken() // ] -// d.ReadValue() // "object" -// d.ReadValue() // {"k":"v"} -// d.ReadToken() // } -// -// The above is one of many possible sequence of calls and -// may not represent the most sensible method to call for any given token/value. -// For example, it is probably more common to call ReadToken to obtain a -// string token for object names. -type Decoder struct { - state - decodeBuffer - options DecodeOptions - - stringCache *stringCache // only used when unmarshaling -} - -// decodeBuffer is a buffer split into 4 segments: -// -// - buf[0:prevEnd] // already read portion of the buffer -// - buf[prevStart:prevEnd] // previously read value -// - buf[prevEnd:len(buf)] // unread portion of the buffer -// - buf[len(buf):cap(buf)] // unused portion of the buffer -// -// Invariants: -// -// 0 ≤ prevStart ≤ prevEnd ≤ len(buf) ≤ cap(buf) -type decodeBuffer struct { - peekPos int // non-zero if valid offset into buf for start of next token - peekErr error // implies peekPos is -1 - - buf []byte // may alias rd if it is a bytes.Buffer - prevStart int - prevEnd int - - // baseOffset is added to prevStart and prevEnd to obtain - // the absolute offset relative to the start of io.Reader stream. - baseOffset int64 - - rd io.Reader -} - -// NewDecoder constructs a new streaming decoder reading from r. -// -// If r is a bytes.Buffer, then the decoder parses directly from the buffer -// without first copying the contents to an intermediate buffer. -// Additional writes to the buffer must not occur while the decoder is in use. -func NewDecoder(r io.Reader) *Decoder { - return DecodeOptions{}.NewDecoder(r) -} - -// NewDecoder constructs a new streaming decoder reading from r -// configured with the provided options. -func (o DecodeOptions) NewDecoder(r io.Reader) *Decoder { - d := new(Decoder) - o.ResetDecoder(d, r) - return d -} - -// ResetDecoder resets a decoder such that it is reading afresh from r and -// configured with the provided options. -func (o DecodeOptions) ResetDecoder(d *Decoder, r io.Reader) { - if d == nil { - panic("json: invalid nil Decoder") - } - if r == nil { - panic("json: invalid nil io.Reader") - } - d.reset(nil, r, o) -} - -func (d *Decoder) reset(b []byte, r io.Reader, o DecodeOptions) { - d.state.reset() - d.decodeBuffer = decodeBuffer{buf: b, rd: r} - d.options = o -} - -// Reset resets a decoder such that it is reading afresh from r but -// keep any pre-existing decoder options. -func (d *Decoder) Reset(r io.Reader) { - d.options.ResetDecoder(d, r) -} - -var errBufferWriteAfterNext = errors.New("invalid bytes.Buffer.Write call after calling bytes.Buffer.Next") - -// fetch reads at least 1 byte from the underlying io.Reader. -// It returns io.ErrUnexpectedEOF if zero bytes were read and io.EOF was seen. -func (d *Decoder) fetch() error { - if d.rd == nil { - return io.ErrUnexpectedEOF - } - - // Inform objectNameStack that we are about to fetch new buffer content. - d.names.copyQuotedBuffer(d.buf) - - // Specialize bytes.Buffer for better performance. - if bb, ok := d.rd.(*bytes.Buffer); ok { - switch { - case bb.Len() == 0: - return io.ErrUnexpectedEOF - case len(d.buf) == 0: - d.buf = bb.Next(bb.Len()) // "read" all data in the buffer - return nil - default: - // This only occurs if a partially filled bytes.Buffer was provided - // and more data is written to it while Decoder is reading from it. - // This practice will lead to data corruption since future writes - // may overwrite the contents of the current buffer. - // - // The user is trying to use a bytes.Buffer as a pipe, - // but a bytes.Buffer is poor implementation of a pipe, - // the purpose-built io.Pipe should be used instead. - return &ioError{action: "read", err: errBufferWriteAfterNext} - } - } - - // Allocate initial buffer if empty. - if cap(d.buf) == 0 { - d.buf = make([]byte, 0, 64) - } - - // Check whether to grow the buffer. - const maxBufferSize = 4 << 10 - const growthSizeFactor = 2 // higher value is faster - const growthRateFactor = 2 // higher value is slower - // By default, grow if below the maximum buffer size. - grow := cap(d.buf) <= maxBufferSize/growthSizeFactor - // Growing can be expensive, so only grow - // if a sufficient number of bytes have been processed. - grow = grow && int64(cap(d.buf)) < d.previousOffsetEnd()/growthRateFactor - // If prevStart==0, then fetch was called in order to fetch more data - // to finish consuming a large JSON value contiguously. - // Grow if less than 25% of the remaining capacity is available. - // Note that this may cause the input buffer to exceed maxBufferSize. - grow = grow || (d.prevStart == 0 && len(d.buf) >= 3*cap(d.buf)/4) - - if grow { - // Allocate a new buffer and copy the contents of the old buffer over. - // TODO: Provide a hard limit on the maximum internal buffer size? - buf := make([]byte, 0, cap(d.buf)*growthSizeFactor) - d.buf = append(buf, d.buf[d.prevStart:]...) - } else { - // Move unread portion of the data to the front. - n := copy(d.buf[:cap(d.buf)], d.buf[d.prevStart:]) - d.buf = d.buf[:n] - } - d.baseOffset += int64(d.prevStart) - d.prevEnd -= d.prevStart - d.prevStart = 0 - - // Read more data into the internal buffer. - for { - n, err := d.rd.Read(d.buf[len(d.buf):cap(d.buf)]) - switch { - case n > 0: - d.buf = d.buf[:len(d.buf)+n] - return nil // ignore errors if any bytes are read - case err == io.EOF: - return io.ErrUnexpectedEOF - case err != nil: - return &ioError{action: "read", err: err} - default: - continue // Read returned (0, nil) - } - } -} - -const invalidateBufferByte = '#' // invalid starting character for JSON grammar - -// invalidatePreviousRead invalidates buffers returned by Peek and Read calls -// so that the first byte is an invalid character. -// This Hyrum-proofs the API against faulty application code that assumes -// values returned by ReadValue remain valid past subsequent Read calls. -func (d *decodeBuffer) invalidatePreviousRead() { - // Avoid mutating the buffer if d.rd is nil which implies that d.buf - // is provided by the user code and may not expect mutations. - isBytesBuffer := func(r io.Reader) bool { - _, ok := r.(*bytes.Buffer) - return ok - } - if d.rd != nil && !isBytesBuffer(d.rd) && d.prevStart < d.prevEnd && uint(d.prevStart) < uint(len(d.buf)) { - d.buf[d.prevStart] = invalidateBufferByte - d.prevStart = d.prevEnd - } -} - -// needMore reports whether there are no more unread bytes. -func (d *decodeBuffer) needMore(pos int) bool { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - return pos == len(d.buf) -} - -// injectSyntacticErrorWithPosition wraps a SyntacticError with the position, -// otherwise it returns the error as is. -// It takes a position relative to the start of the start of d.buf. -func (d *decodeBuffer) injectSyntacticErrorWithPosition(err error, pos int) error { - if serr, ok := err.(*SyntacticError); ok { - return serr.withOffset(d.baseOffset + int64(pos)) - } - return err -} - -func (d *decodeBuffer) previousOffsetStart() int64 { return d.baseOffset + int64(d.prevStart) } -func (d *decodeBuffer) previousOffsetEnd() int64 { return d.baseOffset + int64(d.prevEnd) } -func (d *decodeBuffer) previousBuffer() []byte { return d.buf[d.prevStart:d.prevEnd] } -func (d *decodeBuffer) unreadBuffer() []byte { return d.buf[d.prevEnd:len(d.buf)] } - -// PeekKind retrieves the next token kind, but does not advance the read offset. -// It returns 0 if there are no more tokens. -func (d *Decoder) PeekKind() Kind { - // Check whether we have a cached peek result. - if d.peekPos > 0 { - return Kind(d.buf[d.peekPos]).normalize() - } - - var err error - d.invalidatePreviousRead() - pos := d.prevEnd - - // Consume leading whitespace. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - if err == io.ErrUnexpectedEOF && d.tokens.depth() == 1 { - err = io.EOF // EOF possibly if no Tokens present after top-level value - } - d.peekPos, d.peekErr = -1, err - return invalidKind - } - } - - // Consume colon or comma. - var delim byte - if c := d.buf[pos]; c == ':' || c == ',' { - delim = c - pos += 1 - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - d.peekPos, d.peekErr = -1, err - return invalidKind - } - } - } - next := Kind(d.buf[pos]).normalize() - if d.tokens.needDelim(next) != delim { - pos = d.prevEnd // restore position to right after leading whitespace - pos += consumeWhitespace(d.buf[pos:]) - err = d.tokens.checkDelim(delim, next) - err = d.injectSyntacticErrorWithPosition(err, pos) - d.peekPos, d.peekErr = -1, err - return invalidKind - } - - // This may set peekPos to zero, which is indistinguishable from - // the uninitialized state. While a small hit to performance, it is correct - // since ReadValue and ReadToken will disregard the cached result and - // recompute the next kind. - d.peekPos, d.peekErr = pos, nil - return next -} - -// SkipValue is semantically equivalent to calling ReadValue and discarding -// the result except that memory is not wasted trying to hold the entire result. -func (d *Decoder) SkipValue() error { - switch d.PeekKind() { - case '{', '[': - // For JSON objects and arrays, keep skipping all tokens - // until the depth matches the starting depth. - depth := d.tokens.depth() - for { - if _, err := d.ReadToken(); err != nil { - return err - } - if depth >= d.tokens.depth() { - return nil - } - } - default: - // Trying to skip a value when the next token is a '}' or ']' - // will result in an error being returned here. - if _, err := d.ReadValue(); err != nil { - return err - } - return nil - } -} - -// ReadToken reads the next Token, advancing the read offset. -// The returned token is only valid until the next Peek, Read, or Skip call. -// It returns io.EOF if there are no more tokens. -func (d *Decoder) ReadToken() (Token, error) { - // Determine the next kind. - var err error - var next Kind - pos := d.peekPos - if pos != 0 { - // Use cached peek result. - if d.peekErr != nil { - err := d.peekErr - d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error - return Token{}, err - } - next = Kind(d.buf[pos]).normalize() - d.peekPos = 0 // reset cache - } else { - d.invalidatePreviousRead() - pos = d.prevEnd - - // Consume leading whitespace. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - if err == io.ErrUnexpectedEOF && d.tokens.depth() == 1 { - err = io.EOF // EOF possibly if no Tokens present after top-level value - } - return Token{}, err - } - } - - // Consume colon or comma. - var delim byte - if c := d.buf[pos]; c == ':' || c == ',' { - delim = c - pos += 1 - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return Token{}, err - } - } - } - next = Kind(d.buf[pos]).normalize() - if d.tokens.needDelim(next) != delim { - pos = d.prevEnd // restore position to right after leading whitespace - pos += consumeWhitespace(d.buf[pos:]) - err = d.tokens.checkDelim(delim, next) - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - } - - // Handle the next token. - var n int - switch next { - case 'n': - if consumeNull(d.buf[pos:]) == 0 { - pos, err = d.consumeLiteral(pos, "null") - if err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - } else { - pos += len("null") - } - if err = d.tokens.appendLiteral(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos-len("null")) // report position at start of literal - } - d.prevStart, d.prevEnd = pos, pos - return Null, nil - - case 'f': - if consumeFalse(d.buf[pos:]) == 0 { - pos, err = d.consumeLiteral(pos, "false") - if err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - } else { - pos += len("false") - } - if err = d.tokens.appendLiteral(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos-len("false")) // report position at start of literal - } - d.prevStart, d.prevEnd = pos, pos - return False, nil - - case 't': - if consumeTrue(d.buf[pos:]) == 0 { - pos, err = d.consumeLiteral(pos, "true") - if err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - } else { - pos += len("true") - } - if err = d.tokens.appendLiteral(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos-len("true")) // report position at start of literal - } - d.prevStart, d.prevEnd = pos, pos - return True, nil - - case '"': - var flags valueFlags // TODO: Preserve this in Token? - if n = consumeSimpleString(d.buf[pos:]); n == 0 { - oldAbsPos := d.baseOffset + int64(pos) - pos, err = d.consumeString(&flags, pos) - newAbsPos := d.baseOffset + int64(pos) - n = int(newAbsPos - oldAbsPos) - if err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - } else { - pos += n - } - if !d.options.AllowDuplicateNames && d.tokens.last.needObjectName() { - if !d.tokens.last.isValidNamespace() { - return Token{}, errInvalidNamespace - } - if d.tokens.last.isActiveNamespace() && !d.namespaces.last().insertQuoted(d.buf[pos-n:pos], flags.isVerbatim()) { - err = &SyntacticError{str: "duplicate name " + string(d.buf[pos-n:pos]) + " in object"} - return Token{}, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of string - } - d.names.replaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds - } - if err = d.tokens.appendString(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of string - } - d.prevStart, d.prevEnd = pos-n, pos - return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil - - case '0': - // NOTE: Since JSON numbers are not self-terminating, - // we need to make sure that the next byte is not part of a number. - if n = consumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { - oldAbsPos := d.baseOffset + int64(pos) - pos, err = d.consumeNumber(pos) - newAbsPos := d.baseOffset + int64(pos) - n = int(newAbsPos - oldAbsPos) - if err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - } else { - pos += n - } - if err = d.tokens.appendNumber(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of number - } - d.prevStart, d.prevEnd = pos-n, pos - return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil - - case '{': - if err = d.tokens.pushObject(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - if !d.options.AllowDuplicateNames { - d.names.push() - d.namespaces.push() - } - pos += 1 - d.prevStart, d.prevEnd = pos, pos - return ObjectStart, nil - - case '}': - if err = d.tokens.popObject(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - if !d.options.AllowDuplicateNames { - d.names.pop() - d.namespaces.pop() - } - pos += 1 - d.prevStart, d.prevEnd = pos, pos - return ObjectEnd, nil - - case '[': - if err = d.tokens.pushArray(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - pos += 1 - d.prevStart, d.prevEnd = pos, pos - return ArrayStart, nil - - case ']': - if err = d.tokens.popArray(); err != nil { - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } - pos += 1 - d.prevStart, d.prevEnd = pos, pos - return ArrayEnd, nil - - default: - err = newInvalidCharacterError(d.buf[pos:], "at start of token") - return Token{}, d.injectSyntacticErrorWithPosition(err, pos) - } -} - -type valueFlags uint - -const ( - _ valueFlags = (1 << iota) / 2 // powers of two starting with zero - - stringNonVerbatim // string cannot be naively treated as valid UTF-8 - stringNonCanonical // string not formatted according to RFC 8785, section 3.2.2.2. - // TODO: Track whether a number is a non-integer? -) - -func (f *valueFlags) set(f2 valueFlags) { *f |= f2 } -func (f valueFlags) isVerbatim() bool { return f&stringNonVerbatim == 0 } -func (f valueFlags) isCanonical() bool { return f&stringNonCanonical == 0 } - -// ReadValue returns the next raw JSON value, advancing the read offset. -// The value is stripped of any leading or trailing whitespace. -// The returned value is only valid until the next Peek, Read, or Skip call and -// may not be mutated while the Decoder remains in use. -// If the decoder is currently at the end token for an object or array, -// then it reports a SyntacticError and the internal state remains unchanged. -// It returns io.EOF if there are no more values. -func (d *Decoder) ReadValue() (RawValue, error) { - var flags valueFlags - return d.readValue(&flags) -} -func (d *Decoder) readValue(flags *valueFlags) (RawValue, error) { - // Determine the next kind. - var err error - var next Kind - pos := d.peekPos - if pos != 0 { - // Use cached peek result. - if d.peekErr != nil { - err := d.peekErr - d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error - return nil, err - } - next = Kind(d.buf[pos]).normalize() - d.peekPos = 0 // reset cache - } else { - d.invalidatePreviousRead() - pos = d.prevEnd - - // Consume leading whitespace. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - if err == io.ErrUnexpectedEOF && d.tokens.depth() == 1 { - err = io.EOF // EOF possibly if no Tokens present after top-level value - } - return nil, err - } - } - - // Consume colon or comma. - var delim byte - if c := d.buf[pos]; c == ':' || c == ',' { - delim = c - pos += 1 - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return nil, err - } - } - } - next = Kind(d.buf[pos]).normalize() - if d.tokens.needDelim(next) != delim { - pos = d.prevEnd // restore position to right after leading whitespace - pos += consumeWhitespace(d.buf[pos:]) - err = d.tokens.checkDelim(delim, next) - return nil, d.injectSyntacticErrorWithPosition(err, pos) - } - } - - // Handle the next value. - oldAbsPos := d.baseOffset + int64(pos) - pos, err = d.consumeValue(flags, pos) - newAbsPos := d.baseOffset + int64(pos) - n := int(newAbsPos - oldAbsPos) - if err != nil { - return nil, d.injectSyntacticErrorWithPosition(err, pos) - } - switch next { - case 'n', 't', 'f': - err = d.tokens.appendLiteral() - case '"': - if !d.options.AllowDuplicateNames && d.tokens.last.needObjectName() { - if !d.tokens.last.isValidNamespace() { - err = errInvalidNamespace - break - } - if d.tokens.last.isActiveNamespace() && !d.namespaces.last().insertQuoted(d.buf[pos-n:pos], flags.isVerbatim()) { - err = &SyntacticError{str: "duplicate name " + string(d.buf[pos-n:pos]) + " in object"} - break - } - d.names.replaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds - } - err = d.tokens.appendString() - case '0': - err = d.tokens.appendNumber() - case '{': - if err = d.tokens.pushObject(); err != nil { - break - } - if err = d.tokens.popObject(); err != nil { - panic("BUG: popObject should never fail immediately after pushObject: " + err.Error()) - } - case '[': - if err = d.tokens.pushArray(); err != nil { - break - } - if err = d.tokens.popArray(); err != nil { - panic("BUG: popArray should never fail immediately after pushArray: " + err.Error()) - } - } - if err != nil { - return nil, d.injectSyntacticErrorWithPosition(err, pos-n) // report position at start of value - } - d.prevEnd = pos - d.prevStart = pos - n - return d.buf[pos-n : pos : pos], nil -} - -// checkEOF verifies that the input has no more data. -func (d *Decoder) checkEOF() error { - switch pos, err := d.consumeWhitespace(d.prevEnd); err { - case nil: - return newInvalidCharacterError(d.buf[pos:], "after top-level value") - case io.ErrUnexpectedEOF: - return nil - default: - return err - } -} - -// consumeWhitespace consumes all whitespace starting at d.buf[pos:]. -// It returns the new position in d.buf immediately after the last whitespace. -// If it returns nil, there is guaranteed to at least be one unread byte. -// -// The following pattern is common in this implementation: -// -// pos += consumeWhitespace(d.buf[pos:]) -// if d.needMore(pos) { -// if pos, err = d.consumeWhitespace(pos); err != nil { -// return ... -// } -// } -// -// It is difficult to simplify this without sacrificing performance since -// consumeWhitespace must be inlined. The body of the if statement is -// executed only in rare situations where we need to fetch more data. -// Since fetching may return an error, we also need to check the error. -func (d *Decoder) consumeWhitespace(pos int) (newPos int, err error) { - for { - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - absPos := d.baseOffset + int64(pos) - err = d.fetch() // will mutate d.buf and invalidate pos - pos = int(absPos - d.baseOffset) - if err != nil { - return pos, err - } - continue - } - return pos, nil - } -} - -// consumeValue consumes a single JSON value starting at d.buf[pos:]. -// It returns the new position in d.buf immediately after the value. -func (d *Decoder) consumeValue(flags *valueFlags, pos int) (newPos int, err error) { - for { - var n int - var err error - switch next := Kind(d.buf[pos]).normalize(); next { - case 'n': - if n = consumeNull(d.buf[pos:]); n == 0 { - n, err = consumeLiteral(d.buf[pos:], "null") - } - case 'f': - if n = consumeFalse(d.buf[pos:]); n == 0 { - n, err = consumeLiteral(d.buf[pos:], "false") - } - case 't': - if n = consumeTrue(d.buf[pos:]); n == 0 { - n, err = consumeLiteral(d.buf[pos:], "true") - } - case '"': - if n = consumeSimpleString(d.buf[pos:]); n == 0 { - return d.consumeString(flags, pos) - } - case '0': - // NOTE: Since JSON numbers are not self-terminating, - // we need to make sure that the next byte is not part of a number. - if n = consumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { - return d.consumeNumber(pos) - } - case '{': - return d.consumeObject(flags, pos) - case '[': - return d.consumeArray(flags, pos) - default: - return pos, newInvalidCharacterError(d.buf[pos:], "at start of value") - } - if err == io.ErrUnexpectedEOF { - absPos := d.baseOffset + int64(pos) - err = d.fetch() // will mutate d.buf and invalidate pos - pos = int(absPos - d.baseOffset) - if err != nil { - return pos, err - } - continue - } - return pos + n, err - } -} - -// consumeLiteral consumes a single JSON literal starting at d.buf[pos:]. -// It returns the new position in d.buf immediately after the literal. -func (d *Decoder) consumeLiteral(pos int, lit string) (newPos int, err error) { - for { - n, err := consumeLiteral(d.buf[pos:], lit) - if err == io.ErrUnexpectedEOF { - absPos := d.baseOffset + int64(pos) - err = d.fetch() // will mutate d.buf and invalidate pos - pos = int(absPos - d.baseOffset) - if err != nil { - return pos, err - } - continue - } - return pos + n, err - } -} - -// consumeString consumes a single JSON string starting at d.buf[pos:]. -// It returns the new position in d.buf immediately after the string. -func (d *Decoder) consumeString(flags *valueFlags, pos int) (newPos int, err error) { - var n int - for { - n, err = consumeStringResumable(flags, d.buf[pos:], n, !d.options.AllowInvalidUTF8) - if err == io.ErrUnexpectedEOF { - absPos := d.baseOffset + int64(pos) - err = d.fetch() // will mutate d.buf and invalidate pos - pos = int(absPos - d.baseOffset) - if err != nil { - return pos, err - } - continue - } - return pos + n, err - } -} - -// consumeNumber consumes a single JSON number starting at d.buf[pos:]. -// It returns the new position in d.buf immediately after the number. -func (d *Decoder) consumeNumber(pos int) (newPos int, err error) { - var n int - var state consumeNumberState - for { - n, state, err = consumeNumberResumable(d.buf[pos:], n, state) - // NOTE: Since JSON numbers are not self-terminating, - // we need to make sure that the next byte is not part of a number. - if err == io.ErrUnexpectedEOF || d.needMore(pos+n) { - mayTerminate := err == nil - absPos := d.baseOffset + int64(pos) - err = d.fetch() // will mutate d.buf and invalidate pos - pos = int(absPos - d.baseOffset) - if err != nil { - if mayTerminate && err == io.ErrUnexpectedEOF { - return pos + n, nil - } - return pos, err - } - continue - } - return pos + n, err - } -} - -// consumeObject consumes a single JSON object starting at d.buf[pos:]. -// It returns the new position in d.buf immediately after the object. -func (d *Decoder) consumeObject(flags *valueFlags, pos int) (newPos int, err error) { - var n int - var names *objectNamespace - if !d.options.AllowDuplicateNames { - d.namespaces.push() - defer d.namespaces.pop() - names = d.namespaces.last() - } - - // Handle before start. - if d.buf[pos] != '{' { - panic("BUG: consumeObject must be called with a buffer that starts with '{'") - } - pos++ - - // Handle after start. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - if d.buf[pos] == '}' { - pos++ - return pos, nil - } - - for { - // Handle before name. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - var flags2 valueFlags - if n = consumeSimpleString(d.buf[pos:]); n == 0 { - oldAbsPos := d.baseOffset + int64(pos) - pos, err = d.consumeString(&flags2, pos) - newAbsPos := d.baseOffset + int64(pos) - n = int(newAbsPos - oldAbsPos) - flags.set(flags2) - if err != nil { - return pos, err - } - } else { - pos += n - } - if !d.options.AllowDuplicateNames && !names.insertQuoted(d.buf[pos-n:pos], flags2.isVerbatim()) { - return pos - n, &SyntacticError{str: "duplicate name " + string(d.buf[pos-n:pos]) + " in object"} - } - - // Handle after name. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - if d.buf[pos] != ':' { - return pos, newInvalidCharacterError(d.buf[pos:], "after object name (expecting ':')") - } - pos++ - - // Handle before value. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - pos, err = d.consumeValue(flags, pos) - if err != nil { - return pos, err - } - - // Handle after value. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - switch d.buf[pos] { - case ',': - pos++ - continue - case '}': - pos++ - return pos, nil - default: - return pos, newInvalidCharacterError(d.buf[pos:], "after object value (expecting ',' or '}')") - } - } -} - -// consumeArray consumes a single JSON array starting at d.buf[pos:]. -// It returns the new position in d.buf immediately after the array. -func (d *Decoder) consumeArray(flags *valueFlags, pos int) (newPos int, err error) { - // Handle before start. - if d.buf[pos] != '[' { - panic("BUG: consumeArray must be called with a buffer that starts with '['") - } - pos++ - - // Handle after start. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - if d.buf[pos] == ']' { - pos++ - return pos, nil - } - - for { - // Handle before value. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - pos, err = d.consumeValue(flags, pos) - if err != nil { - return pos, err - } - - // Handle after value. - pos += consumeWhitespace(d.buf[pos:]) - if d.needMore(pos) { - if pos, err = d.consumeWhitespace(pos); err != nil { - return pos, err - } - } - switch d.buf[pos] { - case ',': - pos++ - continue - case ']': - pos++ - return pos, nil - default: - return pos, newInvalidCharacterError(d.buf[pos:], "after array value (expecting ',' or ']')") - } - } -} - -// InputOffset returns the current input byte offset. It gives the location -// of the next byte immediately after the most recently returned token or value. -// The number of bytes actually read from the underlying io.Reader may be more -// than this offset due to internal buffering effects. -func (d *Decoder) InputOffset() int64 { - return d.previousOffsetEnd() -} - -// UnreadBuffer returns the data remaining in the unread buffer, -// which may contain zero or more bytes. -// The returned buffer must not be mutated while Decoder continues to be used. -// The buffer contents are valid until the next Peek, Read, or Skip call. -func (d *Decoder) UnreadBuffer() []byte { - return d.unreadBuffer() -} - -// StackDepth returns the depth of the state machine for read JSON data. -// Each level on the stack represents a nested JSON object or array. -// It is incremented whenever an ObjectStart or ArrayStart token is encountered -// and decremented whenever an ObjectEnd or ArrayEnd token is encountered. -// The depth is zero-indexed, where zero represents the top-level JSON value. -func (d *Decoder) StackDepth() int { - // NOTE: Keep in sync with Encoder.StackDepth. - return d.tokens.depth() - 1 -} - -// StackIndex returns information about the specified stack level. -// It must be a number between 0 and StackDepth, inclusive. -// For each level, it reports the kind: -// -// - 0 for a level of zero, -// - '{' for a level representing a JSON object, and -// - '[' for a level representing a JSON array. -// -// It also reports the length of that JSON object or array. -// Each name and value in a JSON object is counted separately, -// so the effective number of members would be half the length. -// A complete JSON object must have an even length. -func (d *Decoder) StackIndex(i int) (Kind, int) { - // NOTE: Keep in sync with Encoder.StackIndex. - switch s := d.tokens.index(i); { - case i > 0 && s.isObject(): - return '{', s.length() - case i > 0 && s.isArray(): - return '[', s.length() - default: - return 0, s.length() - } -} - -// StackPointer returns a JSON Pointer (RFC 6901) to the most recently read value. -// Object names are only present if AllowDuplicateNames is false, otherwise -// object members are represented using their index within the object. -func (d *Decoder) StackPointer() string { - d.names.copyQuotedBuffer(d.buf) - return string(d.appendStackPointer(nil)) -} - -// consumeWhitespace consumes leading JSON whitespace per RFC 7159, section 2. -func consumeWhitespace(b []byte) (n int) { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - for len(b) > n && (b[n] == ' ' || b[n] == '\t' || b[n] == '\r' || b[n] == '\n') { - n++ - } - return n -} - -// consumeNull consumes the next JSON null literal per RFC 7159, section 3. -// It returns 0 if it is invalid, in which case consumeLiteral should be used. -func consumeNull(b []byte) int { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - const literal = "null" - if len(b) >= len(literal) && string(b[:len(literal)]) == literal { - return len(literal) - } - return 0 -} - -// consumeFalse consumes the next JSON false literal per RFC 7159, section 3. -// It returns 0 if it is invalid, in which case consumeLiteral should be used. -func consumeFalse(b []byte) int { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - const literal = "false" - if len(b) >= len(literal) && string(b[:len(literal)]) == literal { - return len(literal) - } - return 0 -} - -// consumeTrue consumes the next JSON true literal per RFC 7159, section 3. -// It returns 0 if it is invalid, in which case consumeLiteral should be used. -func consumeTrue(b []byte) int { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - const literal = "true" - if len(b) >= len(literal) && string(b[:len(literal)]) == literal { - return len(literal) - } - return 0 -} - -// consumeLiteral consumes the next JSON literal per RFC 7159, section 3. -// If the input appears truncated, it returns io.ErrUnexpectedEOF. -func consumeLiteral(b []byte, lit string) (n int, err error) { - for i := 0; i < len(b) && i < len(lit); i++ { - if b[i] != lit[i] { - return i, newInvalidCharacterError(b[i:], "within literal "+lit+" (expecting "+strconv.QuoteRune(rune(lit[i]))+")") - } - } - if len(b) < len(lit) { - return len(b), io.ErrUnexpectedEOF - } - return len(lit), nil -} - -// consumeSimpleString consumes the next JSON string per RFC 7159, section 7 -// but is limited to the grammar for an ASCII string without escape sequences. -// It returns 0 if it is invalid or more complicated than a simple string, -// in which case consumeString should be called. -func consumeSimpleString(b []byte) (n int) { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - if len(b) > 0 && b[0] == '"' { - n++ - for len(b) > n && (' ' <= b[n] && b[n] != '\\' && b[n] != '"' && b[n] < utf8.RuneSelf) { - n++ - } - if len(b) > n && b[n] == '"' { - n++ - return n - } - } - return 0 -} - -// consumeString consumes the next JSON string per RFC 7159, section 7. -// If validateUTF8 is false, then this allows the presence of invalid UTF-8 -// characters within the string itself. -// It reports the number of bytes consumed and whether an error was encountered. -// If the input appears truncated, it returns io.ErrUnexpectedEOF. -func consumeString(flags *valueFlags, b []byte, validateUTF8 bool) (n int, err error) { - return consumeStringResumable(flags, b, 0, validateUTF8) -} - -// consumeStringResumable is identical to consumeString but supports resuming -// from a previous call that returned io.ErrUnexpectedEOF. -func consumeStringResumable(flags *valueFlags, b []byte, resumeOffset int, validateUTF8 bool) (n int, err error) { - // Consume the leading double quote. - switch { - case resumeOffset > 0: - n = resumeOffset // already handled the leading quote - case uint(len(b)) == 0: - return n, io.ErrUnexpectedEOF - case b[0] == '"': - n++ - default: - return n, newInvalidCharacterError(b[n:], `at start of string (expecting '"')`) - } - - // Consume every character in the string. - for uint(len(b)) > uint(n) { - // Optimize for long sequences of unescaped characters. - noEscape := func(c byte) bool { - return c < utf8.RuneSelf && ' ' <= c && c != '\\' && c != '"' - } - for uint(len(b)) > uint(n) && noEscape(b[n]) { - n++ - } - if uint(len(b)) <= uint(n) { - return n, io.ErrUnexpectedEOF - } - - // Check for terminating double quote. - if b[n] == '"' { - n++ - return n, nil - } - - switch r, rn := utf8.DecodeRune(b[n:]); { - // Handle UTF-8 encoded byte sequence. - // Due to specialized handling of ASCII above, we know that - // all normal sequences at this point must be 2 bytes or larger. - case rn > 1: - n += rn - // Handle escape sequence. - case r == '\\': - flags.set(stringNonVerbatim) - resumeOffset = n - if uint(len(b)) < uint(n+2) { - return resumeOffset, io.ErrUnexpectedEOF - } - switch r := b[n+1]; r { - case '/': - // Forward slash is the only character with 3 representations. - // Per RFC 8785, section 3.2.2.2., this must not be escaped. - flags.set(stringNonCanonical) - n += 2 - case '"', '\\', 'b', 'f', 'n', 'r', 't': - n += 2 - case 'u': - if uint(len(b)) < uint(n+6) { - if !hasEscapeSequencePrefix(b[n:]) { - flags.set(stringNonCanonical) - return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:])) + " within string"} - } - return resumeOffset, io.ErrUnexpectedEOF - } - v1, ok := parseHexUint16(b[n+2 : n+6]) - if !ok { - flags.set(stringNonCanonical) - return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+6])) + " within string"} - } - // Only certain control characters can use the \uFFFF notation - // for canonical formatting (per RFC 8785, section 3.2.2.2.). - switch v1 { - // \uFFFF notation not permitted for these characters. - case '\b', '\f', '\n', '\r', '\t': - flags.set(stringNonCanonical) - default: - // \uFFFF notation only permitted for control characters. - if v1 >= ' ' { - flags.set(stringNonCanonical) - } else { - // \uFFFF notation must be lower case. - for _, c := range b[n+2 : n+6] { - if 'A' <= c && c <= 'F' { - flags.set(stringNonCanonical) - } - } - } - } - n += 6 - - if validateUTF8 && utf16.IsSurrogate(rune(v1)) { - if uint(len(b)) >= uint(n+2) && (b[n] != '\\' || b[n+1] != 'u') { - return n, &SyntacticError{str: "invalid unpaired surrogate half within string"} - } - if uint(len(b)) < uint(n+6) { - if !hasEscapeSequencePrefix(b[n:]) { - flags.set(stringNonCanonical) - return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:])) + " within string"} - } - return resumeOffset, io.ErrUnexpectedEOF - } - v2, ok := parseHexUint16(b[n+2 : n+6]) - if !ok { - return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+6])) + " within string"} - } - if utf16.DecodeRune(rune(v1), rune(v2)) == utf8.RuneError { - return n, &SyntacticError{str: "invalid surrogate pair in string"} - } - n += 6 - } - default: - flags.set(stringNonCanonical) - return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+2])) + " within string"} - } - // Handle invalid UTF-8. - case r == utf8.RuneError: - if !utf8.FullRune(b[n:]) { - return n, io.ErrUnexpectedEOF - } - flags.set(stringNonVerbatim | stringNonCanonical) - if validateUTF8 { - return n, &SyntacticError{str: "invalid UTF-8 within string"} - } - n++ - // Handle invalid control characters. - case r < ' ': - flags.set(stringNonVerbatim | stringNonCanonical) - return n, newInvalidCharacterError(b[n:], "within string (expecting non-control character)") - default: - panic("BUG: unhandled character " + quoteRune(b[n:])) - } - } - return n, io.ErrUnexpectedEOF -} - -// hasEscapeSequencePrefix reports whether b is possibly -// the truncated prefix of a \uFFFF escape sequence. -func hasEscapeSequencePrefix(b []byte) bool { - for i, c := range b { - switch { - case i == 0 && c != '\\': - return false - case i == 1 && c != 'u': - return false - case i >= 2 && i < 6 && !('0' <= c && c <= '9') && !('a' <= c && c <= 'f') && !('A' <= c && c <= 'F'): - return false - } - } - return true -} - -// unescapeString appends the unescaped form of a JSON string in src to dst. -// Any invalid UTF-8 within the string will be replaced with utf8.RuneError. -// The input must be an entire JSON string with no surrounding whitespace. -func unescapeString(dst, src []byte) (v []byte, ok bool) { - // Consume leading double quote. - if uint(len(src)) == 0 || src[0] != '"' { - return dst, false - } - i, n := 1, 1 - - // Consume every character until completion. - for uint(len(src)) > uint(n) { - // Optimize for long sequences of unescaped characters. - noEscape := func(c byte) bool { - return c < utf8.RuneSelf && ' ' <= c && c != '\\' && c != '"' - } - for uint(len(src)) > uint(n) && noEscape(src[n]) { - n++ - } - if uint(len(src)) <= uint(n) { - break - } - - // Check for terminating double quote. - if src[n] == '"' { - dst = append(dst, src[i:n]...) - n++ - return dst, len(src) == n - } - - switch r, rn := utf8.DecodeRune(src[n:]); { - // Handle UTF-8 encoded byte sequence. - // Due to specialized handling of ASCII above, we know that - // all normal sequences at this point must be 2 bytes or larger. - case rn > 1: - n += rn - // Handle escape sequence. - case r == '\\': - dst = append(dst, src[i:n]...) - if r < ' ' { - return dst, false // invalid control character or unescaped quote - } - - // Handle escape sequence. - if uint(len(src)) < uint(n+2) { - return dst, false // truncated escape sequence - } - switch r := src[n+1]; r { - case '"', '\\', '/': - dst = append(dst, r) - n += 2 - case 'b': - dst = append(dst, '\b') - n += 2 - case 'f': - dst = append(dst, '\f') - n += 2 - case 'n': - dst = append(dst, '\n') - n += 2 - case 'r': - dst = append(dst, '\r') - n += 2 - case 't': - dst = append(dst, '\t') - n += 2 - case 'u': - if uint(len(src)) < uint(n+6) { - return dst, false // truncated escape sequence - } - v1, ok := parseHexUint16(src[n+2 : n+6]) - if !ok { - return dst, false // invalid escape sequence - } - n += 6 - - // Check whether this is a surrogate half. - r := rune(v1) - if utf16.IsSurrogate(r) { - r = utf8.RuneError // assume failure unless the following succeeds - if uint(len(src)) >= uint(n+6) && src[n+0] == '\\' && src[n+1] == 'u' { - if v2, ok := parseHexUint16(src[n+2 : n+6]); ok { - if r = utf16.DecodeRune(rune(v1), rune(v2)); r != utf8.RuneError { - n += 6 - } - } - } - } - - dst = utf8.AppendRune(dst, r) - default: - return dst, false // invalid escape sequence - } - i = n - // Handle invalid UTF-8. - case r == utf8.RuneError: - // NOTE: An unescaped string may be longer than the escaped string - // because invalid UTF-8 bytes are being replaced. - dst = append(dst, src[i:n]...) - dst = append(dst, "\uFFFD"...) - n += rn - i = n - // Handle invalid control characters. - case r < ' ': - dst = append(dst, src[i:n]...) - return dst, false // invalid control character or unescaped quote - default: - panic("BUG: unhandled character " + quoteRune(src[n:])) - } - } - dst = append(dst, src[i:n]...) - return dst, false // truncated input -} - -// unescapeStringMayCopy returns the unescaped form of b. -// If there are no escaped characters, the output is simply a subslice of -// the input with the surrounding quotes removed. -// Otherwise, a new buffer is allocated for the output. -func unescapeStringMayCopy(b []byte, isVerbatim bool) []byte { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - if isVerbatim { - return b[len(`"`) : len(b)-len(`"`)] - } - b, _ = unescapeString(make([]byte, 0, len(b)), b) - return b -} - -// consumeSimpleNumber consumes the next JSON number per RFC 7159, section 6 -// but is limited to the grammar for a positive integer. -// It returns 0 if it is invalid or more complicated than a simple integer, -// in which case consumeNumber should be called. -func consumeSimpleNumber(b []byte) (n int) { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - if len(b) > 0 { - if b[0] == '0' { - n++ - } else if '1' <= b[0] && b[0] <= '9' { - n++ - for len(b) > n && ('0' <= b[n] && b[n] <= '9') { - n++ - } - } else { - return 0 - } - if len(b) == n || !(b[n] == '.' || b[n] == 'e' || b[n] == 'E') { - return n - } - } - return 0 -} - -type consumeNumberState uint - -const ( - consumeNumberInit consumeNumberState = iota - beforeIntegerDigits - withinIntegerDigits - beforeFractionalDigits - withinFractionalDigits - beforeExponentDigits - withinExponentDigits -) - -// consumeNumber consumes the next JSON number per RFC 7159, section 6. -// It reports the number of bytes consumed and whether an error was encountered. -// If the input appears truncated, it returns io.ErrUnexpectedEOF. -// -// Note that JSON numbers are not self-terminating. -// If the entire input is consumed, then the caller needs to consider whether -// there may be subsequent unread data that may still be part of this number. -func consumeNumber(b []byte) (n int, err error) { - n, _, err = consumeNumberResumable(b, 0, consumeNumberInit) - return n, err -} - -// consumeNumberResumable is identical to consumeNumber but supports resuming -// from a previous call that returned io.ErrUnexpectedEOF. -func consumeNumberResumable(b []byte, resumeOffset int, state consumeNumberState) (n int, _ consumeNumberState, err error) { - // Jump to the right state when resuming from a partial consumption. - n = resumeOffset - if state > consumeNumberInit { - switch state { - case withinIntegerDigits, withinFractionalDigits, withinExponentDigits: - // Consume leading digits. - for len(b) > n && ('0' <= b[n] && b[n] <= '9') { - n++ - } - if len(b) == n { - return n, state, nil // still within the same state - } - state++ // switches "withinX" to "beforeY" where Y is the state after X - } - switch state { - case beforeIntegerDigits: - goto beforeInteger - case beforeFractionalDigits: - goto beforeFractional - case beforeExponentDigits: - goto beforeExponent - default: - return n, state, nil - } - } - - // Consume required integer component (with optional minus sign). -beforeInteger: - resumeOffset = n - if len(b) > 0 && b[0] == '-' { - n++ - } - switch { - case len(b) == n: - return resumeOffset, beforeIntegerDigits, io.ErrUnexpectedEOF - case b[n] == '0': - n++ - state = beforeFractionalDigits - case '1' <= b[n] && b[n] <= '9': - n++ - for len(b) > n && ('0' <= b[n] && b[n] <= '9') { - n++ - } - state = withinIntegerDigits - default: - return n, state, newInvalidCharacterError(b[n:], "within number (expecting digit)") - } - - // Consume optional fractional component. -beforeFractional: - if len(b) > n && b[n] == '.' { - resumeOffset = n - n++ - switch { - case len(b) == n: - return resumeOffset, beforeFractionalDigits, io.ErrUnexpectedEOF - case '0' <= b[n] && b[n] <= '9': - n++ - default: - return n, state, newInvalidCharacterError(b[n:], "within number (expecting digit)") - } - for len(b) > n && ('0' <= b[n] && b[n] <= '9') { - n++ - } - state = withinFractionalDigits - } - - // Consume optional exponent component. -beforeExponent: - if len(b) > n && (b[n] == 'e' || b[n] == 'E') { - resumeOffset = n - n++ - if len(b) > n && (b[n] == '-' || b[n] == '+') { - n++ - } - switch { - case len(b) == n: - return resumeOffset, beforeExponentDigits, io.ErrUnexpectedEOF - case '0' <= b[n] && b[n] <= '9': - n++ - default: - return n, state, newInvalidCharacterError(b[n:], "within number (expecting digit)") - } - for len(b) > n && ('0' <= b[n] && b[n] <= '9') { - n++ - } - state = withinExponentDigits - } - - return n, state, nil -} - -// parseHexUint16 is similar to strconv.ParseUint, -// but operates directly on []byte and is optimized for base-16. -// See https://go.dev/issue/42429. -func parseHexUint16(b []byte) (v uint16, ok bool) { - if len(b) != 4 { - return 0, false - } - for _, c := range b[:4] { - switch { - case '0' <= c && c <= '9': - c = c - '0' - case 'a' <= c && c <= 'f': - c = 10 + c - 'a' - case 'A' <= c && c <= 'F': - c = 10 + c - 'A' - default: - return 0, false - } - v = v*16 + uint16(c) - } - return v, true -} - -// parseDecUint is similar to strconv.ParseUint, -// but operates directly on []byte and is optimized for base-10. -// If the number is syntactically valid but overflows uint64, -// then it returns (math.MaxUint64, false). -// See https://go.dev/issue/42429. -func parseDecUint(b []byte) (v uint64, ok bool) { - // Overflow logic is based on strconv/atoi.go:138-149 from Go1.15, where: - // - cutoff is equal to math.MaxUint64/10+1, and - // - the n1 > maxVal check is unnecessary - // since maxVal is equivalent to math.MaxUint64. - var n int - var overflow bool - for len(b) > n && ('0' <= b[n] && b[n] <= '9') { - overflow = overflow || v >= math.MaxUint64/10+1 - v *= 10 - - v1 := v + uint64(b[n]-'0') - overflow = overflow || v1 < v - v = v1 - - n++ - } - if n == 0 || len(b) != n { - return 0, false - } - if overflow { - return math.MaxUint64, false - } - return v, true -} - -// parseFloat parses a floating point number according to the Go float grammar. -// Note that the JSON number grammar is a strict subset. -// -// If the number overflows the finite representation of a float, -// then we return MaxFloat since any finite value will always be infinitely -// more accurate at representing another finite value than an infinite value. -func parseFloat(b []byte, bits int) (v float64, ok bool) { - // Fast path for exact integer numbers which fit in the - // 24-bit or 53-bit significand of a float32 or float64. - var negLen int // either 0 or 1 - if len(b) > 0 && b[0] == '-' { - negLen = 1 - } - u, ok := parseDecUint(b[negLen:]) - if ok && ((bits == 32 && u <= 1<<24) || (bits == 64 && u <= 1<<53)) { - return math.Copysign(float64(u), float64(-1*negLen)), true - } - - // Note that the []byte->string conversion unfortunately allocates. - // See https://go.dev/issue/42429 for more information. - fv, err := strconv.ParseFloat(string(b), bits) - if math.IsInf(fv, 0) { - switch { - case bits == 32 && math.IsInf(fv, +1): - return +math.MaxFloat32, true - case bits == 64 && math.IsInf(fv, +1): - return +math.MaxFloat64, true - case bits == 32 && math.IsInf(fv, -1): - return -math.MaxFloat32, true - case bits == 64 && math.IsInf(fv, -1): - return -math.MaxFloat64, true - } - } - return fv, err == nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go index e4eefa3d..ff70951a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go @@ -2,61 +2,41 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package json implements serialization of JSON -// as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785. +// Package json implements semantic processing of JSON as specified in RFC 8259. // JSON is a simple data interchange format that can represent // primitive data types such as booleans, strings, and numbers, // in addition to structured data types such as objects and arrays. // -// # Terminology -// -// This package uses the terms "encode" and "decode" for syntactic functionality -// that is concerned with processing JSON based on its grammar, and -// uses the terms "marshal" and "unmarshal" for semantic functionality -// that determines the meaning of JSON values as Go values and vice-versa. -// It aims to provide a clear distinction between functionality that -// is purely concerned with encoding versus that of marshaling. -// For example, one can directly encode a stream of JSON tokens without -// needing to marshal a concrete Go value representing them. -// Similarly, one can decode a stream of JSON tokens without -// needing to unmarshal them into a concrete Go value. -// -// This package uses JSON terminology when discussing JSON, which may differ -// from related concepts in Go or elsewhere in computing literature. -// -// - A JSON "object" refers to an unordered collection of name/value members. -// - A JSON "array" refers to an ordered sequence of elements. -// - A JSON "value" refers to either a literal (i.e., null, false, or true), -// string, number, object, or array. -// -// See RFC 8259 for more information. -// -// # Specifications -// -// Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259, -// and RFC 8785. Each RFC is generally a stricter subset of another RFC. -// In increasing order of strictness: -// -// - RFC 4627 and RFC 7159 do not require (but recommend) the use of UTF-8 -// and also do not require (but recommend) that object names be unique. -// - RFC 8259 requires the use of UTF-8, -// but does not require (but recommends) that object names be unique. -// - RFC 7493 requires the use of UTF-8 -// and also requires that object names be unique. -// - RFC 8785 defines a canonical representation. It requires the use of UTF-8 -// and also requires that object names be unique and in a specific ordering. -// It specifies exactly how strings and numbers must be formatted. -// -// The primary difference between RFC 4627 and RFC 7159 is that the former -// restricted top-level values to only JSON objects and arrays, while -// RFC 7159 and subsequent RFCs permit top-level values to additionally be -// JSON nulls, booleans, strings, or numbers. -// -// By default, this package operates on RFC 7493, but can be configured -// to operate according to the other RFC specifications. -// RFC 7493 is a stricter subset of RFC 8259 and fully compliant with it. -// In particular, it makes specific choices about behavior that RFC 8259 -// leaves as undefined in order to ensure greater interoperability. +// [Marshal] and [Unmarshal] encode and decode Go values +// to/from JSON text contained within a []byte. +// [MarshalWrite] and [UnmarshalRead] operate on JSON text +// by writing to or reading from an [io.Writer] or [io.Reader]. +// [MarshalEncode] and [UnmarshalDecode] operate on JSON text +// by encoding to or decoding from a [jsontext.Encoder] or [jsontext.Decoder]. +// [Options] may be passed to each of the marshal or unmarshal functions +// to configure the semantic behavior of marshaling and unmarshaling +// (i.e., alter how JSON data is understood as Go data and vice versa). +// [jsontext.Options] may also be passed to the marshal or unmarshal functions +// to configure the syntactic behavior of encoding or decoding. +// +// The data types of JSON are mapped to/from the data types of Go based on +// the closest logical equivalent between the two type systems. For example, +// a JSON boolean corresponds with a Go bool, +// a JSON string corresponds with a Go string, +// a JSON number corresponds with a Go int, uint or float, +// a JSON array corresponds with a Go slice or array, and +// a JSON object corresponds with a Go struct or map. +// See the documentation on [Marshal] and [Unmarshal] for a comprehensive list +// of how the JSON and Go type systems correspond. +// +// Arbitrary Go types can customize their JSON representation by implementing +// [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom]. +// This provides authors of Go types with control over how their types are +// serialized as JSON. Alternatively, users can implement functions that match +// [MarshalFunc], [MarshalToFunc], [UnmarshalFunc], or [UnmarshalFromFunc] +// to specify the JSON representation for arbitrary types. +// This provides callers of JSON functionality with control over +// how any arbitrary type is serialized as JSON. // // # JSON Representation of Go structs // @@ -68,12 +48,14 @@ // into the corresponding Go struct fields. // Object members that do not match any struct fields, // also known as “unknown members”, are ignored by default or rejected -// if UnmarshalOptions.RejectUnknownMembers is specified. +// if [RejectUnknownMembers] is specified. // // The representation of each struct field can be customized in the // "json" struct field tag, where the tag is a comma separated list of options. // As a special case, if the entire tag is `json:"-"`, // then the field is ignored with regard to its JSON representation. +// Some options also have equivalent behavior controlled by a caller-specified [Options]. +// Field-specified options take precedence over caller-specified options. // // The first option is the JSON object name override for the Go struct field. // If the name is not specified, then the Go struct field name @@ -98,21 +80,23 @@ // encoded as a JSON null, empty string, empty object, or empty array. // This option has no effect when unmarshaling. // -// - string: The "string" option specifies that -// MarshalOptions.StringifyNumbers and UnmarshalOptions.StringifyNumbers +// - string: The "string" option specifies that [StringifyNumbers] // be set when marshaling or unmarshaling a struct field value. // This causes numeric types to be encoded as a JSON number -// within a JSON string, and to be decoded from either a JSON number or -// a JSON string containing a JSON number. +// within a JSON string, and to be decoded from a JSON string +// containing the JSON number without any surrounding whitespace. // This extra level of encoding is often necessary since // many JSON parsers cannot precisely represent 64-bit integers. // -// - nocase: When unmarshaling, the "nocase" option specifies that -// if the JSON object name does not exactly match the JSON name -// for any of the struct fields, then it attempts to match the struct field -// using a case-insensitive match that also ignores dashes and underscores. -// If multiple fields match, the first declared field in breadth-first order -// takes precedence. This option has no effect when marshaling. +// - case: When unmarshaling, the "case" option specifies how +// JSON object names are matched with the JSON name for Go struct fields. +// The option is a key-value pair specified as "case:value" where +// the value must either be 'ignore' or 'strict'. +// The 'ignore' value specifies that matching is case-insensitive +// where dashes and underscores are also ignored. If multiple fields match, +// the first declared field in breadth-first order takes precedence. +// The 'strict' value specifies that matching is case-sensitive. +// This takes precedence over the [MatchCaseInsensitiveNames] option. // // - inline: The "inline" option specifies that // the JSON representable content of this field type is to be promoted @@ -120,10 +104,10 @@ // It is the JSON equivalent of Go struct embedding. // A Go embedded field is implicitly inlined unless an explicit JSON name // is specified. The inlined field must be a Go struct -// (that does not implement any JSON methods), RawValue, map[string]T, -// or an unnamed pointer to such types. When marshaling, +// (that does not implement any JSON methods), [jsontext.Value], +// map[~string]T, or an unnamed pointer to such types. When marshaling, // inlined fields from a pointer type are omitted if it is nil. -// Inlined fields of type RawValue and map[string]T are called +// Inlined fields of type [jsontext.Value] and map[~string]T are called // “inlined fallbacks” as they can represent all possible // JSON object members not directly handled by the parent struct. // Only one inlined fallback field may be specified in a struct, @@ -132,11 +116,11 @@ // // - unknown: The "unknown" option is a specialized variant // of the inlined fallback to indicate that this Go struct field -// contains any number of unknown JSON object members. The field type -// must be a RawValue, map[string]T, or an unnamed pointer to such types. -// If MarshalOptions.DiscardUnknownMembers is specified when marshaling, +// contains any number of unknown JSON object members. The field type must +// be a [jsontext.Value], map[~string]T, or an unnamed pointer to such types. +// If [DiscardUnknownMembers] is specified when marshaling, // the contents of this field are ignored. -// If UnmarshalOptions.RejectUnknownMembers is specified when unmarshaling, +// If [RejectUnknownMembers] is specified when unmarshaling, // any unknown object members are rejected regardless of whether // an inlined fallback with the "unknown" option exists. This option // must not be specified with any other option (including the JSON name). @@ -156,7 +140,7 @@ // For example, only a nil slice or map is omitted under "omitzero", while // an empty slice or map is omitted under "omitempty" regardless of nilness. // The "omitzero" option is useful for types with a well-defined zero value -// (e.g., netip.Addr) or have an IsZero method (e.g., time.Time). +// (e.g., [net/netip.Addr]) or have an IsZero method (e.g., [time.Time.IsZero]). // // Every Go struct corresponds to a list of JSON representable fields // which is constructed by performing a breadth-first search over @@ -167,12 +151,108 @@ // at shallowest depth takes precedence and the other fields at deeper depths // are excluded from the list of JSON representable fields. // If multiple fields at the shallowest depth have the same JSON name, -// then all of those fields are excluded from the list. This is analogous to -// Go visibility rules for struct field selection with embedded struct types. +// but exactly one is explicitly tagged with a JSON name, +// then that field takes precedence and all others are excluded from the list. +// This is analogous to Go visibility rules for struct field selection +// with embedded struct types. // // Marshaling or unmarshaling a non-empty struct -// without any JSON representable fields results in a SemanticError. +// without any JSON representable fields results in a [SemanticError]. // Unexported fields must not have any `json` tags except for `json:"-"`. +// +// # Security Considerations +// +// JSON is frequently used as a data interchange format to communicate +// between different systems, possibly implemented in different languages. +// For interoperability and security reasons, it is important that +// all implementations agree upon the semantic meaning of the data. +// +// [For example, suppose we have two micro-services.] +// The first service is responsible for authenticating a JSON request, +// while the second service is responsible for executing the request +// (having assumed that the prior service authenticated the request). +// If an attacker were able to maliciously craft a JSON request such that +// both services believe that the same request is from different users, +// it could bypass the authenticator with valid credentials for one user, +// but maliciously perform an action on behalf of a different user. +// +// According to RFC 8259, there unfortunately exist many JSON texts +// that are syntactically valid but semantically ambiguous. +// For example, the standard does not define how to interpret duplicate +// names within an object. +// +// The v1 [encoding/json] and [encoding/json/v2] packages +// interpret some inputs in different ways. In particular: +// +// - The standard specifies that JSON must be encoded using UTF-8. +// By default, v1 replaces invalid bytes of UTF-8 in JSON strings +// with the Unicode replacement character, +// while v2 rejects inputs with invalid UTF-8. +// To change the default, specify the [jsontext.AllowInvalidUTF8] option. +// The replacement of invalid UTF-8 is a form of data corruption +// that alters the precise meaning of strings. +// +// - The standard does not specify a particular behavior when +// duplicate names are encountered within a JSON object, +// which means that different implementations may behave differently. +// By default, v1 allows for the presence of duplicate names, +// while v2 rejects duplicate names. +// To change the default, specify the [jsontext.AllowDuplicateNames] option. +// If allowed, object members are processed in the order they are observed, +// meaning that later values will replace or be merged into prior values, +// depending on the Go value type. +// +// - The standard defines a JSON object as an unordered collection of name/value pairs. +// While ordering can be observed through the underlying [jsontext] API, +// both v1 and v2 generally avoid exposing the ordering. +// No application should semantically depend on the order of object members. +// Allowing duplicate names is a vector through which ordering of members +// can accidentally be observed and depended upon. +// +// - The standard suggests that JSON object names are typically compared +// based on equality of the sequence of Unicode code points, +// which implies that comparing names is often case-sensitive. +// When unmarshaling a JSON object into a Go struct, +// by default, v1 uses a (loose) case-insensitive match on the name, +// while v2 uses a (strict) case-sensitive match on the name. +// To change the default, specify the [MatchCaseInsensitiveNames] option. +// The use of case-insensitive matching provides another vector through +// which duplicate names can occur. Allowing case-insensitive matching +// means that v1 or v2 might interpret JSON objects differently from most +// other JSON implementations (which typically use a case-sensitive match). +// +// - The standard does not specify a particular behavior when +// an unknown name in a JSON object is encountered. +// When unmarshaling a JSON object into a Go struct, by default +// both v1 and v2 ignore unknown names and their corresponding values. +// To change the default, specify the [RejectUnknownMembers] option. +// +// - The standard suggests that implementations may use a float64 +// to represent a JSON number. Consequently, large JSON integers +// may lose precision when stored as a floating-point type. +// Both v1 and v2 correctly preserve precision when marshaling and +// unmarshaling a concrete integer type. However, even if v1 and v2 +// preserve precision for concrete types, other JSON implementations +// may not be able to preserve precision for outputs produced by v1 or v2. +// The `string` tag option can be used to specify that an integer type +// is to be quoted within a JSON string to avoid loss of precision. +// Furthermore, v1 and v2 may still lose precision when unmarshaling +// into an any interface value, where unmarshal uses a float64 +// by default to represent a JSON number. +// To change the default, specify the [WithUnmarshalers] option +// with a custom unmarshaler that pre-populates the interface value +// with a concrete Go type that can preserve precision. +// +// RFC 8785 specifies a canonical form for any JSON text, +// which explicitly defines specific behaviors that RFC 8259 leaves undefined. +// In theory, if a text can successfully [jsontext.Value.Canonicalize] +// without changing the semantic meaning of the data, then it provides a +// greater degree of confidence that the data is more secure and interoperable. +// +// The v2 API generally chooses more secure defaults than v1, +// but care should still be taken with large integers or unknown members. +// +// [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s package json // requireKeyedLiterals can be embedded in a struct to require keyed literals. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go deleted file mode 100644 index 5b81ca15..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go +++ /dev/null @@ -1,1170 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package json - -import ( - "bytes" - "io" - "math" - "math/bits" - "strconv" - "unicode/utf16" - "unicode/utf8" -) - -// EncodeOptions configures how JSON encoding operates. -// The zero value is equivalent to the default settings, -// which is compliant with both RFC 7493 and RFC 8259. -type EncodeOptions struct { - requireKeyedLiterals - nonComparable - - // multiline specifies whether the encoder should emit multiline output. - multiline bool - - // omitTopLevelNewline specifies whether to omit the newline - // that is appended after every top-level JSON value when streaming. - omitTopLevelNewline bool - - // AllowDuplicateNames specifies that JSON objects may contain - // duplicate member names. Disabling the duplicate name check may provide - // performance benefits, but breaks compliance with RFC 7493, section 2.3. - // The output will still be compliant with RFC 8259, - // which leaves the handling of duplicate names as unspecified behavior. - AllowDuplicateNames bool - - // AllowInvalidUTF8 specifies that JSON strings may contain invalid UTF-8, - // which will be mangled as the Unicode replacement character, U+FFFD. - // This causes the encoder to break compliance with - // RFC 7493, section 2.1, and RFC 8259, section 8.1. - AllowInvalidUTF8 bool - - // preserveRawStrings specifies that WriteToken and WriteValue should not - // reformat any JSON string, but keep the formatting verbatim. - preserveRawStrings bool - - // canonicalizeNumbers specifies that WriteToken and WriteValue should - // reformat any JSON numbers according to RFC 8785, section 3.2.2.3. - canonicalizeNumbers bool - - // EscapeRune reports whether the provided character should be escaped - // as a hexadecimal Unicode codepoint (e.g., \ufffd). - // If nil, the shortest and simplest encoding will be used, - // which is also the formatting specified by RFC 8785, section 3.2.2.2. - EscapeRune func(rune) bool - - // Indent (if non-empty) specifies that the encoder should emit multiline - // output where each element in a JSON object or array begins on a new, - // indented line beginning with the indent prefix followed by one or more - // copies of indent according to the indentation nesting. - // It may only be composed of space or tab characters. - Indent string - - // IndentPrefix is prepended to each line within a JSON object or array. - // The purpose of the indent prefix is to encode data that can more easily - // be embedded inside other formatted JSON data. - // It may only be composed of space or tab characters. - // It is ignored if Indent is empty. - IndentPrefix string -} - -// Encoder is a streaming encoder from raw JSON tokens and values. -// It is used to write a stream of top-level JSON values, -// each terminated with a newline character. -// -// WriteToken and WriteValue calls may be interleaved. -// For example, the following JSON value: -// -// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} -// -// can be composed with the following calls (ignoring errors for brevity): -// -// e.WriteToken(ObjectStart) // { -// e.WriteToken(String("name")) // "name" -// e.WriteToken(String("value")) // "value" -// e.WriteValue(RawValue(`"array"`)) // "array" -// e.WriteToken(ArrayStart) // [ -// e.WriteToken(Null) // null -// e.WriteToken(False) // false -// e.WriteValue(RawValue("true")) // true -// e.WriteToken(Float(3.14159)) // 3.14159 -// e.WriteToken(ArrayEnd) // ] -// e.WriteValue(RawValue(`"object"`)) // "object" -// e.WriteValue(RawValue(`{"k":"v"}`)) // {"k":"v"} -// e.WriteToken(ObjectEnd) // } -// -// The above is one of many possible sequence of calls and -// may not represent the most sensible method to call for any given token/value. -// For example, it is probably more common to call WriteToken with a string -// for object names. -type Encoder struct { - state - encodeBuffer - options EncodeOptions - - seenPointers seenPointers // only used when marshaling -} - -// encodeBuffer is a buffer split into 2 segments: -// -// - buf[0:len(buf)] // written (but unflushed) portion of the buffer -// - buf[len(buf):cap(buf)] // unused portion of the buffer -type encodeBuffer struct { - buf []byte // may alias wr if it is a bytes.Buffer - - // baseOffset is added to len(buf) to obtain the absolute offset - // relative to the start of io.Writer stream. - baseOffset int64 - - wr io.Writer - - // maxValue is the approximate maximum RawValue size passed to WriteValue. - maxValue int - // unusedCache is the buffer returned by the UnusedBuffer method. - unusedCache []byte - // bufStats is statistics about buffer utilization. - // It is only used with pooled encoders in pools.go. - bufStats bufferStatistics -} - -// NewEncoder constructs a new streaming encoder writing to w. -func NewEncoder(w io.Writer) *Encoder { - return EncodeOptions{}.NewEncoder(w) -} - -// NewEncoder constructs a new streaming encoder writing to w -// configured with the provided options. -// It flushes the internal buffer when the buffer is sufficiently full or -// when a top-level value has been written. -// -// If w is a bytes.Buffer, then the encoder appends directly into the buffer -// without copying the contents from an intermediate buffer. -func (o EncodeOptions) NewEncoder(w io.Writer) *Encoder { - e := new(Encoder) - o.ResetEncoder(e, w) - return e -} - -// ResetEncoder resets an encoder such that it is writing afresh to w and -// configured with the provided options. -func (o EncodeOptions) ResetEncoder(e *Encoder, w io.Writer) { - if e == nil { - panic("json: invalid nil Encoder") - } - if w == nil { - panic("json: invalid nil io.Writer") - } - e.reset(nil, w, o) -} - -func (e *Encoder) reset(b []byte, w io.Writer, o EncodeOptions) { - if len(o.Indent) > 0 { - o.multiline = true - if s := trimLeftSpaceTab(o.IndentPrefix); len(s) > 0 { - panic("json: invalid character " + quoteRune([]byte(s)) + " in indent prefix") - } - if s := trimLeftSpaceTab(o.Indent); len(s) > 0 { - panic("json: invalid character " + quoteRune([]byte(s)) + " in indent") - } - } - e.state.reset() - e.encodeBuffer = encodeBuffer{buf: b, wr: w, bufStats: e.bufStats} - e.options = o - if bb, ok := w.(*bytes.Buffer); ok && bb != nil { - e.buf = bb.Bytes()[bb.Len():] // alias the unused buffer of bb - } -} - -// Reset resets an encoder such that it is writing afresh to w but -// keeps any pre-existing encoder options. -func (e *Encoder) Reset(w io.Writer) { - e.options.ResetEncoder(e, w) -} - -// needFlush determines whether to flush at this point. -func (e *Encoder) needFlush() bool { - // NOTE: This function is carefully written to be inlineable. - - // Avoid flushing if e.wr is nil since there is no underlying writer. - // Flush if less than 25% of the capacity remains. - // Flushing at some constant fraction ensures that the buffer stops growing - // so long as the largest Token or Value fits within that unused capacity. - return e.wr != nil && (e.tokens.depth() == 1 || len(e.buf) > 3*cap(e.buf)/4) -} - -// flush flushes the buffer to the underlying io.Writer. -// It may append a trailing newline after the top-level value. -func (e *Encoder) flush() error { - if e.wr == nil || e.avoidFlush() { - return nil - } - - // In streaming mode, always emit a newline after the top-level value. - if e.tokens.depth() == 1 && !e.options.omitTopLevelNewline { - e.buf = append(e.buf, '\n') - } - - // Inform objectNameStack that we are about to flush the buffer content. - e.names.copyQuotedBuffer(e.buf) - - // Specialize bytes.Buffer for better performance. - if bb, ok := e.wr.(*bytes.Buffer); ok { - // If e.buf already aliases the internal buffer of bb, - // then the Write call simply increments the internal offset, - // otherwise Write operates as expected. - // See https://go.dev/issue/42986. - n, _ := bb.Write(e.buf) // never fails unless bb is nil - e.baseOffset += int64(n) - - // If the internal buffer of bytes.Buffer is too small, - // append operations elsewhere in the Encoder may grow the buffer. - // This would be semantically correct, but hurts performance. - // As such, ensure 25% of the current length is always available - // to reduce the probability that other appends must allocate. - if avail := bb.Cap() - bb.Len(); avail < bb.Len()/4 { - bb.Grow(avail + 1) - } - - e.buf = bb.Bytes()[bb.Len():] // alias the unused buffer of bb - return nil - } - - // Flush the internal buffer to the underlying io.Writer. - n, err := e.wr.Write(e.buf) - e.baseOffset += int64(n) - if err != nil { - // In the event of an error, preserve the unflushed portion. - // Thus, write errors aren't fatal so long as the io.Writer - // maintains consistent state after errors. - if n > 0 { - e.buf = e.buf[:copy(e.buf, e.buf[n:])] - } - return &ioError{action: "write", err: err} - } - e.buf = e.buf[:0] - - // Check whether to grow the buffer. - // Note that cap(e.buf) may already exceed maxBufferSize since - // an append elsewhere already grew it to store a large token. - const maxBufferSize = 4 << 10 - const growthSizeFactor = 2 // higher value is faster - const growthRateFactor = 2 // higher value is slower - // By default, grow if below the maximum buffer size. - grow := cap(e.buf) <= maxBufferSize/growthSizeFactor - // Growing can be expensive, so only grow - // if a sufficient number of bytes have been processed. - grow = grow && int64(cap(e.buf)) < e.previousOffsetEnd()/growthRateFactor - if grow { - e.buf = make([]byte, 0, cap(e.buf)*growthSizeFactor) - } - - return nil -} - -func (e *encodeBuffer) previousOffsetEnd() int64 { return e.baseOffset + int64(len(e.buf)) } -func (e *encodeBuffer) unflushedBuffer() []byte { return e.buf } - -// avoidFlush indicates whether to avoid flushing to ensure there is always -// enough in the buffer to unwrite the last object member if it were empty. -func (e *Encoder) avoidFlush() bool { - switch { - case e.tokens.last.length() == 0: - // Never flush after ObjectStart or ArrayStart since we don't know yet - // if the object or array will end up being empty. - return true - case e.tokens.last.needObjectValue(): - // Never flush before the object value since we don't know yet - // if the object value will end up being empty. - return true - case e.tokens.last.needObjectName() && len(e.buf) >= 2: - // Never flush after the object value if it does turn out to be empty. - switch string(e.buf[len(e.buf)-2:]) { - case `ll`, `""`, `{}`, `[]`: // last two bytes of every empty value - return true - } - } - return false -} - -// unwriteEmptyObjectMember unwrites the last object member if it is empty -// and reports whether it performed an unwrite operation. -func (e *Encoder) unwriteEmptyObjectMember(prevName *string) bool { - if last := e.tokens.last; !last.isObject() || !last.needObjectName() || last.length() == 0 { - panic("BUG: must be called on an object after writing a value") - } - - // The flushing logic is modified to never flush a trailing empty value. - // The encoder never writes trailing whitespace eagerly. - b := e.unflushedBuffer() - - // Detect whether the last value was empty. - var n int - if len(b) >= 3 { - switch string(b[len(b)-2:]) { - case "ll": // last two bytes of `null` - n = len(`null`) - case `""`: - // It is possible for a non-empty string to have `""` as a suffix - // if the second to the last quote was escaped. - if b[len(b)-3] == '\\' { - return false // e.g., `"\""` is not empty - } - n = len(`""`) - case `{}`: - n = len(`{}`) - case `[]`: - n = len(`[]`) - } - } - if n == 0 { - return false - } - - // Unwrite the value, whitespace, colon, name, whitespace, and comma. - b = b[:len(b)-n] - b = trimSuffixWhitespace(b) - b = trimSuffixByte(b, ':') - b = trimSuffixString(b) - b = trimSuffixWhitespace(b) - b = trimSuffixByte(b, ',') - e.buf = b // store back truncated unflushed buffer - - // Undo state changes. - e.tokens.last.decrement() // for object member value - e.tokens.last.decrement() // for object member name - if !e.options.AllowDuplicateNames { - if e.tokens.last.isActiveNamespace() { - e.namespaces.last().removeLast() - } - e.names.clearLast() - if prevName != nil { - e.names.copyQuotedBuffer(e.buf) // required by objectNameStack.replaceLastUnquotedName - e.names.replaceLastUnquotedName(*prevName) - } - } - return true -} - -// unwriteOnlyObjectMemberName unwrites the only object member name -// and returns the unquoted name. -func (e *Encoder) unwriteOnlyObjectMemberName() string { - if last := e.tokens.last; !last.isObject() || last.length() != 1 { - panic("BUG: must be called on an object after writing first name") - } - - // Unwrite the name and whitespace. - b := trimSuffixString(e.buf) - isVerbatim := bytes.IndexByte(e.buf[len(b):], '\\') < 0 - name := string(unescapeStringMayCopy(e.buf[len(b):], isVerbatim)) - e.buf = trimSuffixWhitespace(b) - - // Undo state changes. - e.tokens.last.decrement() - if !e.options.AllowDuplicateNames { - if e.tokens.last.isActiveNamespace() { - e.namespaces.last().removeLast() - } - e.names.clearLast() - } - return name -} - -func trimSuffixWhitespace(b []byte) []byte { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - n := len(b) - 1 - for n >= 0 && (b[n] == ' ' || b[n] == '\t' || b[n] == '\r' || b[n] == '\n') { - n-- - } - return b[:n+1] -} - -func trimSuffixString(b []byte) []byte { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - if len(b) > 0 && b[len(b)-1] == '"' { - b = b[:len(b)-1] - } - for len(b) >= 2 && !(b[len(b)-1] == '"' && b[len(b)-2] != '\\') { - b = b[:len(b)-1] // trim all characters except an unescaped quote - } - if len(b) > 0 && b[len(b)-1] == '"' { - b = b[:len(b)-1] - } - return b -} - -func hasSuffixByte(b []byte, c byte) bool { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - return len(b) > 0 && b[len(b)-1] == c -} - -func trimSuffixByte(b []byte, c byte) []byte { - // NOTE: The arguments and logic are kept simple to keep this inlineable. - if len(b) > 0 && b[len(b)-1] == c { - return b[:len(b)-1] - } - return b -} - -// WriteToken writes the next token and advances the internal write offset. -// -// The provided token kind must be consistent with the JSON grammar. -// For example, it is an error to provide a number when the encoder -// is expecting an object name (which is always a string), or -// to provide an end object delimiter when the encoder is finishing an array. -// If the provided token is invalid, then it reports a SyntacticError and -// the internal state remains unchanged. -func (e *Encoder) WriteToken(t Token) error { - k := t.Kind() - b := e.buf // use local variable to avoid mutating e in case of error - - // Append any delimiters or optional whitespace. - b = e.tokens.mayAppendDelim(b, k) - if e.options.multiline { - b = e.appendWhitespace(b, k) - } - - // Append the token to the output and to the state machine. - var err error - switch k { - case 'n': - b = append(b, "null"...) - err = e.tokens.appendLiteral() - case 'f': - b = append(b, "false"...) - err = e.tokens.appendLiteral() - case 't': - b = append(b, "true"...) - err = e.tokens.appendLiteral() - case '"': - n0 := len(b) // offset before calling t.appendString - if b, err = t.appendString(b, !e.options.AllowInvalidUTF8, e.options.preserveRawStrings, e.options.EscapeRune); err != nil { - break - } - if !e.options.AllowDuplicateNames && e.tokens.last.needObjectName() { - if !e.tokens.last.isValidNamespace() { - err = errInvalidNamespace - break - } - if e.tokens.last.isActiveNamespace() && !e.namespaces.last().insertQuoted(b[n0:], false) { - err = &SyntacticError{str: "duplicate name " + string(b[n0:]) + " in object"} - break - } - e.names.replaceLastQuotedOffset(n0) // only replace if insertQuoted succeeds - } - err = e.tokens.appendString() - case '0': - if b, err = t.appendNumber(b, e.options.canonicalizeNumbers); err != nil { - break - } - err = e.tokens.appendNumber() - case '{': - b = append(b, '{') - if err = e.tokens.pushObject(); err != nil { - break - } - if !e.options.AllowDuplicateNames { - e.names.push() - e.namespaces.push() - } - case '}': - b = append(b, '}') - if err = e.tokens.popObject(); err != nil { - break - } - if !e.options.AllowDuplicateNames { - e.names.pop() - e.namespaces.pop() - } - case '[': - b = append(b, '[') - err = e.tokens.pushArray() - case ']': - b = append(b, ']') - err = e.tokens.popArray() - default: - return &SyntacticError{str: "invalid json.Token"} - } - if err != nil { - return err - } - - // Finish off the buffer and store it back into e. - e.buf = b - if e.needFlush() { - return e.flush() - } - return nil -} - -const ( - rawIntNumber = -1 - rawUintNumber = -2 -) - -// writeNumber is specialized version of WriteToken, but optimized for numbers. -// As a special-case, if bits is -1 or -2, it will treat v as -// the raw-encoded bits of an int64 or uint64, respectively. -// It is only called from arshal_default.go. -func (e *Encoder) writeNumber(v float64, bits int, quote bool) error { - b := e.buf // use local variable to avoid mutating e in case of error - - // Append any delimiters or optional whitespace. - b = e.tokens.mayAppendDelim(b, '0') - if e.options.multiline { - b = e.appendWhitespace(b, '0') - } - - if quote { - // Append the value to the output. - n0 := len(b) // offset before appending the number - b = append(b, '"') - switch bits { - case rawIntNumber: - b = strconv.AppendInt(b, int64(math.Float64bits(v)), 10) - case rawUintNumber: - b = strconv.AppendUint(b, uint64(math.Float64bits(v)), 10) - default: - b = appendNumber(b, v, bits) - } - b = append(b, '"') - - // Escape the string if necessary. - if e.options.EscapeRune != nil { - b2 := append(e.unusedCache, b[n0+len(`"`):len(b)-len(`"`)]...) - b, _ = appendString(b[:n0], string(b2), false, e.options.EscapeRune) - e.unusedCache = b2[:0] - } - - // Update the state machine. - if !e.options.AllowDuplicateNames && e.tokens.last.needObjectName() { - if !e.tokens.last.isValidNamespace() { - return errInvalidNamespace - } - if e.tokens.last.isActiveNamespace() && !e.namespaces.last().insertQuoted(b[n0:], false) { - return &SyntacticError{str: "duplicate name " + string(b[n0:]) + " in object"} - } - e.names.replaceLastQuotedOffset(n0) // only replace if insertQuoted succeeds - } - if err := e.tokens.appendString(); err != nil { - return err - } - } else { - switch bits { - case rawIntNumber: - b = strconv.AppendInt(b, int64(math.Float64bits(v)), 10) - case rawUintNumber: - b = strconv.AppendUint(b, uint64(math.Float64bits(v)), 10) - default: - b = appendNumber(b, v, bits) - } - if err := e.tokens.appendNumber(); err != nil { - return err - } - } - - // Finish off the buffer and store it back into e. - e.buf = b - if e.needFlush() { - return e.flush() - } - return nil -} - -// WriteValue writes the next raw value and advances the internal write offset. -// The Encoder does not simply copy the provided value verbatim, but -// parses it to ensure that it is syntactically valid and reformats it -// according to how the Encoder is configured to format whitespace and strings. -// -// The provided value kind must be consistent with the JSON grammar -// (see examples on Encoder.WriteToken). If the provided value is invalid, -// then it reports a SyntacticError and the internal state remains unchanged. -func (e *Encoder) WriteValue(v RawValue) error { - e.maxValue |= len(v) // bitwise OR is a fast approximation of max - - k := v.Kind() - b := e.buf // use local variable to avoid mutating e in case of error - - // Append any delimiters or optional whitespace. - b = e.tokens.mayAppendDelim(b, k) - if e.options.multiline { - b = e.appendWhitespace(b, k) - } - - // Append the value the output. - var err error - v = v[consumeWhitespace(v):] - n0 := len(b) // offset before calling e.reformatValue - b, v, err = e.reformatValue(b, v, e.tokens.depth()) - if err != nil { - return err - } - v = v[consumeWhitespace(v):] - if len(v) > 0 { - return newInvalidCharacterError(v[0:], "after top-level value") - } - - // Append the kind to the state machine. - switch k { - case 'n', 'f', 't': - err = e.tokens.appendLiteral() - case '"': - if !e.options.AllowDuplicateNames && e.tokens.last.needObjectName() { - if !e.tokens.last.isValidNamespace() { - err = errInvalidNamespace - break - } - if e.tokens.last.isActiveNamespace() && !e.namespaces.last().insertQuoted(b[n0:], false) { - err = &SyntacticError{str: "duplicate name " + string(b[n0:]) + " in object"} - break - } - e.names.replaceLastQuotedOffset(n0) // only replace if insertQuoted succeeds - } - err = e.tokens.appendString() - case '0': - err = e.tokens.appendNumber() - case '{': - if err = e.tokens.pushObject(); err != nil { - break - } - if err = e.tokens.popObject(); err != nil { - panic("BUG: popObject should never fail immediately after pushObject: " + err.Error()) - } - case '[': - if err = e.tokens.pushArray(); err != nil { - break - } - if err = e.tokens.popArray(); err != nil { - panic("BUG: popArray should never fail immediately after pushArray: " + err.Error()) - } - } - if err != nil { - return err - } - - // Finish off the buffer and store it back into e. - e.buf = b - if e.needFlush() { - return e.flush() - } - return nil -} - -// appendWhitespace appends whitespace that immediately precedes the next token. -func (e *Encoder) appendWhitespace(b []byte, next Kind) []byte { - if e.tokens.needDelim(next) == ':' { - return append(b, ' ') - } else { - return e.appendIndent(b, e.tokens.needIndent(next)) - } -} - -// appendIndent appends the appropriate number of indentation characters -// for the current nested level, n. -func (e *Encoder) appendIndent(b []byte, n int) []byte { - if n == 0 { - return b - } - b = append(b, '\n') - b = append(b, e.options.IndentPrefix...) - for ; n > 1; n-- { - b = append(b, e.options.Indent...) - } - return b -} - -// reformatValue parses a JSON value from the start of src and -// appends it to the end of dst, reformatting whitespace and strings as needed. -// It returns the updated versions of dst and src. -func (e *Encoder) reformatValue(dst []byte, src RawValue, depth int) ([]byte, RawValue, error) { - // TODO: Should this update valueFlags as input? - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - var n int - var err error - switch k := Kind(src[0]).normalize(); k { - case 'n': - if n = consumeNull(src); n == 0 { - n, err = consumeLiteral(src, "null") - } - case 'f': - if n = consumeFalse(src); n == 0 { - n, err = consumeLiteral(src, "false") - } - case 't': - if n = consumeTrue(src); n == 0 { - n, err = consumeLiteral(src, "true") - } - case '"': - if n := consumeSimpleString(src); n > 0 && e.options.EscapeRune == nil { - dst, src = append(dst, src[:n]...), src[n:] // copy simple strings verbatim - return dst, src, nil - } - return reformatString(dst, src, !e.options.AllowInvalidUTF8, e.options.preserveRawStrings, e.options.EscapeRune) - case '0': - if n := consumeSimpleNumber(src); n > 0 && !e.options.canonicalizeNumbers { - dst, src = append(dst, src[:n]...), src[n:] // copy simple numbers verbatim - return dst, src, nil - } - return reformatNumber(dst, src, e.options.canonicalizeNumbers) - case '{': - return e.reformatObject(dst, src, depth) - case '[': - return e.reformatArray(dst, src, depth) - default: - return dst, src, newInvalidCharacterError(src, "at start of value") - } - if err != nil { - return dst, src, err - } - dst, src = append(dst, src[:n]...), src[n:] - return dst, src, nil -} - -// reformatObject parses a JSON object from the start of src and -// appends it to the end of src, reformatting whitespace and strings as needed. -// It returns the updated versions of dst and src. -func (e *Encoder) reformatObject(dst []byte, src RawValue, depth int) ([]byte, RawValue, error) { - // Append object start. - if src[0] != '{' { - panic("BUG: reformatObject must be called with a buffer that starts with '{'") - } - dst, src = append(dst, '{'), src[1:] - - // Append (possible) object end. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - if src[0] == '}' { - dst, src = append(dst, '}'), src[1:] - return dst, src, nil - } - - var err error - var names *objectNamespace - if !e.options.AllowDuplicateNames { - e.namespaces.push() - defer e.namespaces.pop() - names = e.namespaces.last() - } - depth++ - for { - // Append optional newline and indentation. - if e.options.multiline { - dst = e.appendIndent(dst, depth) - } - - // Append object name. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - n0 := len(dst) // offset before calling reformatString - n := consumeSimpleString(src) - if n > 0 && e.options.EscapeRune == nil { - dst, src = append(dst, src[:n]...), src[n:] // copy simple strings verbatim - } else { - dst, src, err = reformatString(dst, src, !e.options.AllowInvalidUTF8, e.options.preserveRawStrings, e.options.EscapeRune) - } - if err != nil { - return dst, src, err - } - if !e.options.AllowDuplicateNames && !names.insertQuoted(dst[n0:], false) { - return dst, src, &SyntacticError{str: "duplicate name " + string(dst[n0:]) + " in object"} - } - - // Append colon. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - if src[0] != ':' { - return dst, src, newInvalidCharacterError(src, "after object name (expecting ':')") - } - dst, src = append(dst, ':'), src[1:] - if e.options.multiline { - dst = append(dst, ' ') - } - - // Append object value. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - dst, src, err = e.reformatValue(dst, src, depth) - if err != nil { - return dst, src, err - } - - // Append comma or object end. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - switch src[0] { - case ',': - dst, src = append(dst, ','), src[1:] - continue - case '}': - if e.options.multiline { - dst = e.appendIndent(dst, depth-1) - } - dst, src = append(dst, '}'), src[1:] - return dst, src, nil - default: - return dst, src, newInvalidCharacterError(src, "after object value (expecting ',' or '}')") - } - } -} - -// reformatArray parses a JSON array from the start of src and -// appends it to the end of dst, reformatting whitespace and strings as needed. -// It returns the updated versions of dst and src. -func (e *Encoder) reformatArray(dst []byte, src RawValue, depth int) ([]byte, RawValue, error) { - // Append array start. - if src[0] != '[' { - panic("BUG: reformatArray must be called with a buffer that starts with '['") - } - dst, src = append(dst, '['), src[1:] - - // Append (possible) array end. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - if src[0] == ']' { - dst, src = append(dst, ']'), src[1:] - return dst, src, nil - } - - var err error - depth++ - for { - // Append optional newline and indentation. - if e.options.multiline { - dst = e.appendIndent(dst, depth) - } - - // Append array value. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - dst, src, err = e.reformatValue(dst, src, depth) - if err != nil { - return dst, src, err - } - - // Append comma or array end. - src = src[consumeWhitespace(src):] - if len(src) == 0 { - return dst, src, io.ErrUnexpectedEOF - } - switch src[0] { - case ',': - dst, src = append(dst, ','), src[1:] - continue - case ']': - if e.options.multiline { - dst = e.appendIndent(dst, depth-1) - } - dst, src = append(dst, ']'), src[1:] - return dst, src, nil - default: - return dst, src, newInvalidCharacterError(src, "after array value (expecting ',' or ']')") - } - } -} - -// OutputOffset returns the current output byte offset. It gives the location -// of the next byte immediately after the most recently written token or value. -// The number of bytes actually written to the underlying io.Writer may be less -// than this offset due to internal buffering effects. -func (e *Encoder) OutputOffset() int64 { - return e.previousOffsetEnd() -} - -// UnusedBuffer returns a zero-length buffer with a possible non-zero capacity. -// This buffer is intended to be used to populate a RawValue -// being passed to an immediately succeeding WriteValue call. -// -// Example usage: -// -// b := d.UnusedBuffer() -// b = append(b, '"') -// b = appendString(b, v) // append the string formatting of v -// b = append(b, '"') -// ... := d.WriteValue(b) -// -// It is the user's responsibility to ensure that the value is valid JSON. -func (e *Encoder) UnusedBuffer() []byte { - // NOTE: We don't return e.buf[len(e.buf):cap(e.buf)] since WriteValue would - // need to take special care to avoid mangling the data while reformatting. - // WriteValue can't easily identify whether the input RawValue aliases e.buf - // without using unsafe.Pointer. Thus, we just return a different buffer. - // Should this ever alias e.buf, we need to consider how it operates with - // the specialized performance optimization for bytes.Buffer. - n := 1 << bits.Len(uint(e.maxValue|63)) // fast approximation for max length - if cap(e.unusedCache) < n { - e.unusedCache = make([]byte, 0, n) - } - return e.unusedCache -} - -// StackDepth returns the depth of the state machine for written JSON data. -// Each level on the stack represents a nested JSON object or array. -// It is incremented whenever an ObjectStart or ArrayStart token is encountered -// and decremented whenever an ObjectEnd or ArrayEnd token is encountered. -// The depth is zero-indexed, where zero represents the top-level JSON value. -func (e *Encoder) StackDepth() int { - // NOTE: Keep in sync with Decoder.StackDepth. - return e.tokens.depth() - 1 -} - -// StackIndex returns information about the specified stack level. -// It must be a number between 0 and StackDepth, inclusive. -// For each level, it reports the kind: -// -// - 0 for a level of zero, -// - '{' for a level representing a JSON object, and -// - '[' for a level representing a JSON array. -// -// It also reports the length of that JSON object or array. -// Each name and value in a JSON object is counted separately, -// so the effective number of members would be half the length. -// A complete JSON object must have an even length. -func (e *Encoder) StackIndex(i int) (Kind, int) { - // NOTE: Keep in sync with Decoder.StackIndex. - switch s := e.tokens.index(i); { - case i > 0 && s.isObject(): - return '{', s.length() - case i > 0 && s.isArray(): - return '[', s.length() - default: - return 0, s.length() - } -} - -// StackPointer returns a JSON Pointer (RFC 6901) to the most recently written value. -// Object names are only present if AllowDuplicateNames is false, otherwise -// object members are represented using their index within the object. -func (e *Encoder) StackPointer() string { - e.names.copyQuotedBuffer(e.buf) - return string(e.appendStackPointer(nil)) -} - -// appendString appends src to dst as a JSON string per RFC 7159, section 7. -// -// If validateUTF8 is specified, this rejects input that contains invalid UTF-8 -// otherwise invalid bytes are replaced with the Unicode replacement character. -// If escapeRune is provided, it specifies which runes to escape using -// hexadecimal sequences. If nil, the shortest representable form is used, -// which is also the canonical form for strings (RFC 8785, section 3.2.2.2). -// -// Note that this API allows full control over the formatting of strings -// except for whether a forward solidus '/' may be formatted as '\/' and -// the casing of hexadecimal Unicode escape sequences. -func appendString(dst []byte, src string, validateUTF8 bool, escapeRune func(rune) bool) ([]byte, error) { - appendEscapedASCII := func(dst []byte, c byte) []byte { - switch c { - case '"', '\\': - dst = append(dst, '\\', c) - case '\b': - dst = append(dst, "\\b"...) - case '\f': - dst = append(dst, "\\f"...) - case '\n': - dst = append(dst, "\\n"...) - case '\r': - dst = append(dst, "\\r"...) - case '\t': - dst = append(dst, "\\t"...) - default: - dst = append(dst, "\\u"...) - dst = appendHexUint16(dst, uint16(c)) - } - return dst - } - appendEscapedUnicode := func(dst []byte, r rune) []byte { - if r1, r2 := utf16.EncodeRune(r); r1 != '\ufffd' && r2 != '\ufffd' { - dst = append(dst, "\\u"...) - dst = appendHexUint16(dst, uint16(r1)) - dst = append(dst, "\\u"...) - dst = appendHexUint16(dst, uint16(r2)) - } else { - dst = append(dst, "\\u"...) - dst = appendHexUint16(dst, uint16(r)) - } - return dst - } - - // Optimize for when escapeRune is nil. - if escapeRune == nil { - var i, n int - dst = append(dst, '"') - for uint(len(src)) > uint(n) { - // Handle single-byte ASCII. - if c := src[n]; c < utf8.RuneSelf { - n++ - if c < ' ' || c == '"' || c == '\\' { - dst = append(dst, src[i:n-1]...) - dst = appendEscapedASCII(dst, c) - i = n - } - continue - } - - // Handle multi-byte Unicode. - _, rn := utf8.DecodeRuneInString(src[n:]) - n += rn - if rn == 1 { // must be utf8.RuneError since we already checked for single-byte ASCII - dst = append(dst, src[i:n-rn]...) - if validateUTF8 { - return dst, &SyntacticError{str: "invalid UTF-8 within string"} - } - dst = append(dst, "\ufffd"...) - i = n - } - } - dst = append(dst, src[i:n]...) - dst = append(dst, '"') - return dst, nil - } - - // Slower implementation for when escapeRune is non-nil. - var i, n int - dst = append(dst, '"') - for uint(len(src)) > uint(n) { - switch r, rn := utf8.DecodeRuneInString(src[n:]); { - case r == utf8.RuneError && rn == 1: - dst = append(dst, src[i:n]...) - if validateUTF8 { - return dst, &SyntacticError{str: "invalid UTF-8 within string"} - } - if escapeRune('\ufffd') { - dst = append(dst, `\ufffd`...) - } else { - dst = append(dst, "\ufffd"...) - } - n += rn - i = n - case escapeRune(r): - dst = append(dst, src[i:n]...) - dst = appendEscapedUnicode(dst, r) - n += rn - i = n - case r < ' ' || r == '"' || r == '\\': - dst = append(dst, src[i:n]...) - dst = appendEscapedASCII(dst, byte(r)) - n += rn - i = n - default: - n += rn - } - } - dst = append(dst, src[i:n]...) - dst = append(dst, '"') - return dst, nil -} - -// reformatString consumes a JSON string from src and appends it to dst, -// reformatting it if necessary for the given escapeRune parameter. -// It returns the appended output and the remainder of the input. -func reformatString(dst, src []byte, validateUTF8, preserveRaw bool, escapeRune func(rune) bool) ([]byte, []byte, error) { - // TODO: Should this update valueFlags as input? - var flags valueFlags - n, err := consumeString(&flags, src, validateUTF8) - if err != nil { - return dst, src[n:], err - } - if preserveRaw || (escapeRune == nil && flags.isCanonical()) { - dst = append(dst, src[:n]...) // copy the string verbatim - return dst, src[n:], nil - } - - // TODO: Implement a direct, raw-to-raw reformat for strings. - // If the escapeRune option would have resulted in no changes to the output, - // it would be faster to simply append src to dst without going through - // an intermediary representation in a separate buffer. - b, _ := unescapeString(make([]byte, 0, n), src[:n]) - dst, _ = appendString(dst, string(b), validateUTF8, escapeRune) - return dst, src[n:], nil -} - -// appendNumber appends src to dst as a JSON number per RFC 7159, section 6. -// It formats numbers similar to the ES6 number-to-string conversion. -// See https://go.dev/issue/14135. -// -// The output is identical to ECMA-262, 6th edition, section 7.1.12.1 and with -// RFC 8785, section 3.2.2.3 for 64-bit floating-point numbers except for -0, -// which is formatted as -0 instead of just 0. -// -// For 32-bit floating-point numbers, -// the output is a 32-bit equivalent of the algorithm. -// Note that ECMA-262 specifies no algorithm for 32-bit numbers. -func appendNumber(dst []byte, src float64, bits int) []byte { - if bits == 32 { - src = float64(float32(src)) - } - - abs := math.Abs(src) - fmt := byte('f') - if abs != 0 { - if bits == 64 && (float64(abs) < 1e-6 || float64(abs) >= 1e21) || - bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { - fmt = 'e' - } - } - dst = strconv.AppendFloat(dst, src, fmt, -1, bits) - if fmt == 'e' { - // Clean up e-09 to e-9. - n := len(dst) - if n >= 4 && dst[n-4] == 'e' && dst[n-3] == '-' && dst[n-2] == '0' { - dst[n-2] = dst[n-1] - dst = dst[:n-1] - } - } - return dst -} - -// reformatNumber consumes a JSON string from src and appends it to dst, -// canonicalizing it if specified. -// It returns the appended output and the remainder of the input. -func reformatNumber(dst, src []byte, canonicalize bool) ([]byte, []byte, error) { - n, err := consumeNumber(src) - if err != nil { - return dst, src[n:], err - } - if !canonicalize { - dst = append(dst, src[:n]...) // copy the number verbatim - return dst, src[n:], nil - } - - // Canonicalize the number per RFC 8785, section 3.2.2.3. - // As an optimization, we can copy integer numbers below 2⁵³ verbatim. - const maxExactIntegerDigits = 16 // len(strconv.AppendUint(nil, 1<<53, 10)) - if n < maxExactIntegerDigits && consumeSimpleNumber(src[:n]) == n { - dst = append(dst, src[:n]...) // copy the number verbatim - return dst, src[n:], nil - } - fv, _ := strconv.ParseFloat(string(src[:n]), 64) - switch { - case fv == 0: - fv = 0 // normalize negative zero as just zero - case math.IsInf(fv, +1): - fv = +math.MaxFloat64 - case math.IsInf(fv, -1): - fv = -math.MaxFloat64 - } - return appendNumber(dst, fv, 64), src[n:], nil -} - -// appendHexUint16 appends src to dst as a 4-byte hexadecimal number. -func appendHexUint16(dst []byte, src uint16) []byte { - dst = append(dst, "0000"[1+(bits.Len16(src)-1)/4:]...) - dst = strconv.AppendUint(dst, uint64(src), 16) - return dst -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go index 35be8601..1df76538 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go @@ -5,40 +5,56 @@ package json import ( + "cmp" "errors" + "fmt" "reflect" "strconv" "strings" - "unicode/utf8" -) + "sync" -const errorPrefix = "json: " + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" +) -// Error matches errors returned by this package according to errors.Is. -const Error = jsonError("json error") +// ErrUnknownName indicates that a JSON object member could not be +// unmarshaled because the name is not known to the target Go struct. +// This error is directly wrapped within a [SemanticError] when produced. +// +// The name of an unknown JSON object member can be extracted as: +// +// err := ... +// var serr json.SemanticError +// if errors.As(err, &serr) && serr.Err == json.ErrUnknownName { +// ptr := serr.JSONPointer // JSON pointer to unknown name +// name := ptr.LastToken() // unknown name itself +// ... +// } +// +// This error is only returned if [RejectUnknownMembers] is true. +var ErrUnknownName = errors.New("unknown object member name") -type jsonError string +const errorPrefix = "json: " -func (e jsonError) Error() string { - return string(e) -} -func (e jsonError) Is(target error) bool { - return e == target || target == Error +func isSemanticError(err error) bool { + _, ok := err.(*SemanticError) + return ok } -type ioError struct { - action string // either "read" or "write" - err error +func isSyntacticError(err error) bool { + _, ok := err.(*jsontext.SyntacticError) + return ok } -func (e *ioError) Error() string { - return errorPrefix + e.action + " error: " + e.err.Error() -} -func (e *ioError) Unwrap() error { - return e.err -} -func (e *ioError) Is(target error) bool { - return e == target || target == Error || errors.Is(e.err, target) +// isFatalError reports whether this error must terminate asharling. +// All errors are considered fatal unless operating under +// [jsonflags.ReportErrorsWithLegacySemantics] in which case only +// syntactic errors and I/O errors are considered fatal. +func isFatalError(err error, flags jsonflags.Flags) bool { + return !flags.Get(jsonflags.ReportErrorsWithLegacySemantics) || + isSyntacticError(err) || export.IsIOError(err) } // SemanticError describes an error determining the meaning @@ -55,10 +71,13 @@ type SemanticError struct { ByteOffset int64 // JSONPointer indicates that an error occurred within this JSON value // as indicated using the JSON Pointer notation (see RFC 6901). - JSONPointer string + JSONPointer jsontext.Pointer // JSONKind is the JSON kind that could not be handled. - JSONKind Kind // may be zero if unknown + JSONKind jsontext.Kind // may be zero if unknown + // JSONValue is the JSON number or string that could not be unmarshaled. + // It is not populated during marshaling. + JSONValue jsontext.Value // may be nil if irrelevant or unknown // GoType is the Go type that could not be handled. GoType reflect.Type // may be nil if unknown @@ -66,18 +85,228 @@ type SemanticError struct { Err error // may be nil } -func (e *SemanticError) Error() string { - var sb strings.Builder - sb.WriteString(errorPrefix) +// coder is implemented by [jsontext.Encoder] or [jsontext.Decoder]. +type coder interface { + StackPointer() jsontext.Pointer + Options() Options +} + +// newInvalidFormatError wraps err in a SemanticError because +// the current type t cannot handle the provided options format. +// This error must be called before producing or consuming the next value. +// +// If [jsonflags.ReportErrorsWithLegacySemantics] is specified, +// then this automatically skips the next value when unmarshaling +// to ensure that the value is fully consumed. +func newInvalidFormatError(c coder, t reflect.Type) error { + err := fmt.Errorf("invalid format flag %q", c.Options().(*jsonopts.Struct).Format) + switch c := c.(type) { + case *jsontext.Encoder: + err = newMarshalErrorBefore(c, t, err) + case *jsontext.Decoder: + err = newUnmarshalErrorBeforeWithSkipping(c, t, err) + } + return err +} + +// newMarshalErrorBefore wraps err in a SemanticError assuming that e +// is positioned right before the next token or value, which causes an error. +func newMarshalErrorBefore(e *jsontext.Encoder, t reflect.Type, err error) error { + return &SemanticError{action: "marshal", GoType: t, Err: err, + ByteOffset: e.OutputOffset() + int64(export.Encoder(e).CountNextDelimWhitespace()), + JSONPointer: jsontext.Pointer(export.Encoder(e).AppendStackPointer(nil, +1))} +} + +// newUnmarshalErrorBefore wraps err in a SemanticError assuming that d +// is positioned right before the next token or value, which causes an error. +// It does not record the next JSON kind as this error is used to indicate +// the receiving Go value is invalid to unmarshal into (and not a JSON error). +// However, if [jsonflags.ReportErrorsWithLegacySemantics] is specified, +// then it does record the next JSON kind for historical reporting reasons. +func newUnmarshalErrorBefore(d *jsontext.Decoder, t reflect.Type, err error) error { + var k jsontext.Kind + if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + k = d.PeekKind() + } + return &SemanticError{action: "unmarshal", GoType: t, Err: err, + ByteOffset: d.InputOffset() + int64(export.Decoder(d).CountNextDelimWhitespace()), + JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, +1)), + JSONKind: k} +} + +// newUnmarshalErrorBeforeWithSkipping is like [newUnmarshalErrorBefore], +// but automatically skips the next value if +// [jsonflags.ReportErrorsWithLegacySemantics] is specified. +func newUnmarshalErrorBeforeWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error { + err = newUnmarshalErrorBefore(d, t, err) + if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + if err2 := export.Decoder(d).SkipValue(); err2 != nil { + return err2 + } + } + return err +} + +// newUnmarshalErrorAfter wraps err in a SemanticError assuming that d +// is positioned right after the previous token or value, which caused an error. +func newUnmarshalErrorAfter(d *jsontext.Decoder, t reflect.Type, err error) error { + tokOrVal := export.Decoder(d).PreviousTokenOrValue() + return &SemanticError{action: "unmarshal", GoType: t, Err: err, + ByteOffset: d.InputOffset() - int64(len(tokOrVal)), + JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, -1)), + JSONKind: jsontext.Value(tokOrVal).Kind()} +} + +// newUnmarshalErrorAfter wraps err in a SemanticError assuming that d +// is positioned right after the previous token or value, which caused an error. +// It also stores a copy of the last JSON value if it is a string or number. +func newUnmarshalErrorAfterWithValue(d *jsontext.Decoder, t reflect.Type, err error) error { + serr := newUnmarshalErrorAfter(d, t, err).(*SemanticError) + if serr.JSONKind == '"' || serr.JSONKind == '0' { + serr.JSONValue = jsontext.Value(export.Decoder(d).PreviousTokenOrValue()).Clone() + } + return serr +} + +// newUnmarshalErrorAfterWithSkipping is like [newUnmarshalErrorAfter], +// but automatically skips the remainder of the current value if +// [jsonflags.ReportErrorsWithLegacySemantics] is specified. +func newUnmarshalErrorAfterWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error { + err = newUnmarshalErrorAfter(d, t, err) + if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + if err2 := export.Decoder(d).SkipValueRemainder(); err2 != nil { + return err2 + } + } + return err +} - // Hyrum-proof the error message by deliberately switching between - // two equivalent renderings of the same error message. - // The randomization is tied to the Hyrum-proofing already applied - // on map iteration in Go. +// newSemanticErrorWithPosition wraps err in a SemanticError assuming that +// the error occurred at the provided depth, and length. +// If err is already a SemanticError, then position information is only +// injected if it is currently unpopulated. +// +// If the position is unpopulated, it is ambiguous where the error occurred +// in the user code, whether it was before or after the current position. +// For the byte offset, we assume that the error occurred before the last read +// token or value when decoding, or before the next value when encoding. +// For the JSON pointer, we point to the parent object or array unless +// we can be certain that it happened with an object member. +// +// This is used to annotate errors returned by user-provided +// v2 MarshalJSON or UnmarshalJSON methods or functions. +func newSemanticErrorWithPosition(c coder, t reflect.Type, prevDepth int, prevLength int64, err error) error { + serr, _ := err.(*SemanticError) + if serr == nil { + serr = &SemanticError{Err: err} + } + var currDepth int + var currLength int64 + var coderState interface{ AppendStackPointer([]byte, int) []byte } + var offset int64 + switch c := c.(type) { + case *jsontext.Encoder: + e := export.Encoder(c) + serr.action = cmp.Or(serr.action, "marshal") + currDepth, currLength = e.Tokens.DepthLength() + offset = c.OutputOffset() + int64(export.Encoder(c).CountNextDelimWhitespace()) + coderState = e + case *jsontext.Decoder: + d := export.Decoder(c) + serr.action = cmp.Or(serr.action, "unmarshal") + currDepth, currLength = d.Tokens.DepthLength() + tokOrVal := d.PreviousTokenOrValue() + offset = c.InputOffset() - int64(len(tokOrVal)) + if (prevDepth == currDepth && prevLength == currLength) || len(tokOrVal) == 0 { + // If no Read method was called in the user-defined method or + // if the Peek method was called, then use the offset of the next value. + offset = c.InputOffset() + int64(export.Decoder(c).CountNextDelimWhitespace()) + } + coderState = d + } + serr.ByteOffset = cmp.Or(serr.ByteOffset, offset) + if serr.JSONPointer == "" { + where := 0 // default to ambiguous positioning + switch { + case prevDepth == currDepth && prevLength+0 == currLength: + where = +1 + case prevDepth == currDepth && prevLength+1 == currLength: + where = -1 + } + serr.JSONPointer = jsontext.Pointer(coderState.AppendStackPointer(nil, where)) + } + serr.GoType = cmp.Or(serr.GoType, t) + return serr +} + +// collapseSemanticErrors collapses double SemanticErrors at the outer levels +// into a single SemanticError by preserving the inner error, +// but prepending the ByteOffset and JSONPointer with the outer error. +// +// For example: +// +// collapseSemanticErrors(&SemanticError{ +// ByteOffset: len64(`[0,{"alpha":[0,1,`), +// JSONPointer: "/1/alpha/2", +// GoType: reflect.TypeFor[outerType](), +// Err: &SemanticError{ +// ByteOffset: len64(`{"foo":"bar","fizz":[0,`), +// JSONPointer: "/fizz/1", +// GoType: reflect.TypeFor[innerType](), +// Err: ..., +// }, +// }) +// +// results in: +// +// &SemanticError{ +// ByteOffset: len64(`[0,{"alpha":[0,1,`) + len64(`{"foo":"bar","fizz":[0,`), +// JSONPointer: "/1/alpha/2" + "/fizz/1", +// GoType: reflect.TypeFor[innerType](), +// Err: ..., +// } +// +// This is used to annotate errors returned by user-provided +// v1 MarshalJSON or UnmarshalJSON methods with precise position information +// if they themselves happened to return a SemanticError. +// Since MarshalJSON and UnmarshalJSON are not operating on the root JSON value, +// their positioning must be relative to the nested JSON value +// returned by UnmarshalJSON or passed to MarshalJSON. +// Therefore, we can construct an absolute position by concatenating +// the outer with the inner positions. +// +// Note that we do not use collapseSemanticErrors with user-provided functions +// that take in an [jsontext.Encoder] or [jsontext.Decoder] since they contain +// methods to report position relative to the root JSON value. +// We assume user-constructed errors are correctly precise about position. +func collapseSemanticErrors(err error) error { + if serr1, ok := err.(*SemanticError); ok { + if serr2, ok := serr1.Err.(*SemanticError); ok { + serr2.ByteOffset = serr1.ByteOffset + serr2.ByteOffset + serr2.JSONPointer = serr1.JSONPointer + serr2.JSONPointer + *serr1 = *serr2 + } + } + return err +} + +// errorModalVerb is a modal verb like "cannot" or "unable to". +// +// Once per process, Hyrum-proof the error message by deliberately +// switching between equivalent renderings of the same error message. +// The randomization is tied to the Hyrum-proofing already applied +// on map iteration in Go. +var errorModalVerb = sync.OnceValue(func() string { for phrase := range map[string]struct{}{"cannot": {}, "unable to": {}} { - sb.WriteString(phrase) - break // use whichever phrase we get in the first iteration + return phrase // use whichever phrase we get in the first iteration } + return "" +}) + +func (e *SemanticError) Error() string { + var sb strings.Builder + sb.WriteString(errorPrefix) + sb.WriteString(errorModalVerb()) // Format action. var preposition string @@ -94,7 +323,6 @@ func (e *SemanticError) Error() string { } // Format JSON kind. - var omitPreposition bool switch e.JSONKind { case 'n': sb.WriteString(" JSON null") @@ -109,75 +337,92 @@ func (e *SemanticError) Error() string { case '[', ']': sb.WriteString(" JSON array") default: - omitPreposition = true + if e.action == "" { + preposition = "" + } + } + if len(e.JSONValue) > 0 && len(e.JSONValue) < 100 { + sb.WriteByte(' ') + sb.Write(e.JSONValue) } // Format Go type. if e.GoType != nil { - if !omitPreposition { - sb.WriteString(preposition) + typeString := e.GoType.String() + if len(typeString) > 100 { + // An excessively long type string most likely occurs for + // an anonymous struct declaration with many fields. + // Reduce the noise by just printing the kind, + // and optionally prepending it with the package name + // if the struct happens to include an unexported field. + typeString = e.GoType.Kind().String() + if e.GoType.Kind() == reflect.Struct && e.GoType.Name() == "" { + for i := range e.GoType.NumField() { + if pkgPath := e.GoType.Field(i).PkgPath; pkgPath != "" { + typeString = pkgPath[strings.LastIndexByte(pkgPath, '/')+len("/"):] + ".struct" + break + } + } + } + } + sb.WriteString(preposition) + sb.WriteString(" Go ") + sb.WriteString(typeString) + } + + // Special handling for unknown names. + if e.Err == ErrUnknownName { + sb.WriteString(": ") + sb.WriteString(ErrUnknownName.Error()) + sb.WriteString(" ") + sb.WriteString(strconv.Quote(e.JSONPointer.LastToken())) + if parent := e.JSONPointer.Parent(); parent != "" { + sb.WriteString(" within ") + sb.WriteString(strconv.Quote(jsonwire.TruncatePointer(string(parent), 100))) } - sb.WriteString(" Go value of type ") - sb.WriteString(e.GoType.String()) + return sb.String() } // Format where. - switch { + // Avoid printing if it overlaps with a wrapped SyntacticError. + switch serr, _ := e.Err.(*jsontext.SyntacticError); { case e.JSONPointer != "": - sb.WriteString(" within JSON value at ") - sb.WriteString(strconv.Quote(e.JSONPointer)) + if serr == nil || !e.JSONPointer.Contains(serr.JSONPointer) { + sb.WriteString(" within ") + sb.WriteString(strconv.Quote(jsonwire.TruncatePointer(string(e.JSONPointer), 100))) + } case e.ByteOffset > 0: - sb.WriteString(" after byte offset ") - sb.WriteString(strconv.FormatInt(e.ByteOffset, 10)) + if serr == nil || !(e.ByteOffset <= serr.ByteOffset) { + sb.WriteString(" after offset ") + sb.WriteString(strconv.FormatInt(e.ByteOffset, 10)) + } } // Format underlying error. if e.Err != nil { + errString := e.Err.Error() + if isSyntacticError(e.Err) { + errString = strings.TrimPrefix(errString, "jsontext: ") + } sb.WriteString(": ") - sb.WriteString(e.Err.Error()) + sb.WriteString(errString) } return sb.String() } -func (e *SemanticError) Is(target error) bool { - return e == target || target == Error || errors.Is(e.Err, target) -} + func (e *SemanticError) Unwrap() error { return e.Err } -// SyntacticError is a description of a syntactic error that occurred when -// encoding or decoding JSON according to the grammar. -// -// The contents of this error as produced by this package may change over time. -type SyntacticError struct { - requireKeyedLiterals - nonComparable - - // ByteOffset indicates that an error occurred after this byte offset. - ByteOffset int64 - str string -} - -func (e *SyntacticError) Error() string { - return errorPrefix + e.str -} -func (e *SyntacticError) Is(target error) bool { - return e == target || target == Error -} -func (e *SyntacticError) withOffset(pos int64) error { - return &SyntacticError{ByteOffset: pos, str: e.str} -} - -func newInvalidCharacterError(prefix []byte, where string) *SyntacticError { - what := quoteRune(prefix) - return &SyntacticError{str: "invalid character " + what + " " + where} -} - -func quoteRune(b []byte) string { - r, n := utf8.DecodeRune(b) - if r == utf8.RuneError && n == 1 { - return `'\x` + strconv.FormatUint(uint64(b[0]), 16) + `'` +func newDuplicateNameError(ptr jsontext.Pointer, quotedName []byte, offset int64) error { + if quotedName != nil { + name, _ := jsonwire.AppendUnquote(nil, quotedName) + ptr = ptr.AppendToken(string(name)) + } + return &jsontext.SyntacticError{ + ByteOffset: offset, + JSONPointer: ptr, + Err: jsontext.ErrDuplicateName, } - return strconv.QuoteRune(r) } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go index c0ee3616..d539feed 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/fields.go @@ -5,24 +5,26 @@ package json import ( + "cmp" "errors" "fmt" "io" "reflect" - "sort" + "slices" "strconv" "strings" "unicode" "unicode/utf8" -) -var errIgnoredField = errors.New("ignored field") + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" +) type isZeroer interface { IsZero() bool } -var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem() +var isZeroerType = reflect.TypeFor[isZeroer]() type structFields struct { flattened []structField // listed in depth-first ordering @@ -31,9 +33,37 @@ type structFields struct { inlinedFallback *structField } +// reindex recomputes index to avoid bounds check during runtime. +// +// During the construction of each [structField] in [makeStructFields], +// the index field is 0-indexed. However, before it returns, +// the 0th field is stored in index0 and index stores the remainder. +func (sf *structFields) reindex() { + reindex := func(f *structField) { + f.index0 = f.index[0] + f.index = f.index[1:] + if len(f.index) == 0 { + f.index = nil // avoid pinning the backing slice + } + } + for i := range sf.flattened { + reindex(&sf.flattened[i]) + } + if sf.inlinedFallback != nil { + reindex(sf.inlinedFallback) + } +} + +// lookupByFoldedName looks up name by a case-insensitive match +// that also ignores the presence of dashes and underscores. +func (fs *structFields) lookupByFoldedName(name []byte) []*structField { + return fs.byFoldedName[string(foldName(name))] +} + type structField struct { id int // unique numeric ID in breadth-first ordering - index []int // index into a struct according to reflect.Type.FieldByIndex + index0 int // 0th index into a struct according to [reflect.Type.FieldByIndex] + index []int // 1st index and remainder according to [reflect.Type.FieldByIndex] typ reflect.Type fncs *arshaler isZero func(addressableValue) bool @@ -41,18 +71,12 @@ type structField struct { fieldOptions } -func makeStructFields(root reflect.Type) (structFields, *SemanticError) { - var fs structFields - fs.byActualName = make(map[string]*structField, root.NumField()) - fs.byFoldedName = make(map[string][]*structField, root.NumField()) +var errNoExportedFields = errors.New("Go struct has no exported fields") - // ambiguous is a sentinel value to indicate that at least two fields - // at the same depth have the same name, and thus cancel each other out. - // This follows the same rules as selecting a field on embedded structs - // where the shallowest field takes precedence. If more than one field - // exists at the shallowest depth, then the selection is illegal. - // See https://go.dev/ref/spec#Selectors. - ambiguous := new(structField) +func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) { + orErrorf := func(serr *SemanticError, t reflect.Type, f string, a ...any) *SemanticError { + return cmp.Or(serr, &SemanticError{GoType: t, Err: fmt.Errorf(f, a...)}) + } // Setup a queue for a breath-first search. var queueIndex int @@ -66,6 +90,7 @@ func makeStructFields(root reflect.Type) (structFields, *SemanticError) { // Perform a breadth-first search over all reachable fields. // This ensures that len(f.index) will be monotonically increasing. + var allFields, inlinedFallbacks []structField for queueIndex < len(queue) { qe := queue[queueIndex] queueIndex++ @@ -75,16 +100,16 @@ func makeStructFields(root reflect.Type) (structFields, *SemanticError) { namesIndex := make(map[string]int) // index of each field with a given JSON object name in current struct var hasAnyJSONTag bool // whether any Go struct field has a `json` tag var hasAnyJSONField bool // whether any JSON serializable fields exist in current struct - for i := 0; i < t.NumField(); i++ { + for i := range t.NumField() { sf := t.Field(i) _, hasTag := sf.Tag.Lookup("json") hasAnyJSONTag = hasAnyJSONTag || hasTag - options, err := parseFieldOptions(sf) + options, ignored, err := parseFieldOptions(sf) if err != nil { - if err == errIgnoredField { - continue - } - return structFields{}, &SemanticError{GoType: t, Err: err} + serr = cmp.Or(serr, &SemanticError{GoType: t, Err: err}) + } + if ignored { + continue } hasAnyJSONField = true f := structField{ @@ -96,84 +121,104 @@ func makeStructFields(root reflect.Type) (structFields, *SemanticError) { fieldOptions: options, } if sf.Anonymous && !f.hasName { - f.inline = true // implied by use of Go embedding without an explicit name + if indirectType(f.typ).Kind() != reflect.Struct { + serr = orErrorf(serr, t, "embedded Go struct field %s of non-struct type must be explicitly given a JSON name", sf.Name) + } else { + f.inline = true // implied by use of Go embedding without an explicit name + } } if f.inline || f.unknown { // Handle an inlined field that serializes to/from // zero or more JSON object members. - if f.inline && f.unknown { - err := fmt.Errorf("Go struct field %s cannot have both `inline` and `unknown` specified", sf.Name) - return structFields{}, &SemanticError{GoType: t, Err: err} - } switch f.fieldOptions { case fieldOptions{name: f.name, quotedName: f.quotedName, inline: true}: case fieldOptions{name: f.name, quotedName: f.quotedName, unknown: true}: + case fieldOptions{name: f.name, quotedName: f.quotedName, inline: true, unknown: true}: + serr = orErrorf(serr, t, "Go struct field %s cannot have both `inline` and `unknown` specified", sf.Name) + f.inline = false // let `unknown` take precedence default: - err := fmt.Errorf("Go struct field %s cannot have any options other than `inline` or `unknown` specified", sf.Name) - return structFields{}, &SemanticError{GoType: t, Err: err} + serr = orErrorf(serr, t, "Go struct field %s cannot have any options other than `inline` or `unknown` specified", sf.Name) + if f.hasName { + continue // invalid inlined field; treat as ignored + } + f.fieldOptions = fieldOptions{name: f.name, quotedName: f.quotedName, inline: f.inline, unknown: f.unknown} + if f.inline && f.unknown { + f.inline = false // let `unknown` take precedence + } } - // Unwrap one level of pointer indirection similar to how Go - // only allows embedding either T or *T, but not **T. - tf := f.typ - if tf.Kind() == reflect.Pointer && tf.Name() == "" { - tf = tf.Elem() - } // Reject any types with custom serialization otherwise // it becomes impossible to know what sub-fields to inline. - if which, _ := implementsWhich(tf, - jsonMarshalerV2Type, jsonMarshalerV1Type, textMarshalerType, - jsonUnmarshalerV2Type, jsonUnmarshalerV1Type, textUnmarshalerType, - ); which != nil && tf != rawValueType { - err := fmt.Errorf("inlined Go struct field %s of type %s must not implement JSON marshal or unmarshal methods", sf.Name, tf) - return structFields{}, &SemanticError{GoType: t, Err: err} + tf := indirectType(f.typ) + if implementsAny(tf, allMethodTypes...) && tf != jsontextValueType { + serr = orErrorf(serr, t, "inlined Go struct field %s of type %s must not implement marshal or unmarshal methods", sf.Name, tf) } // Handle an inlined field that serializes to/from // a finite number of JSON object members backed by a Go struct. if tf.Kind() == reflect.Struct { if f.unknown { - err := fmt.Errorf("inlined Go struct field %s of type %s with `unknown` tag must be a Go map of string key or a json.RawValue", sf.Name, tf) - return structFields{}, &SemanticError{GoType: t, Err: err} + serr = orErrorf(serr, t, "inlined Go struct field %s of type %s with `unknown` tag must be a Go map of string key or a jsontext.Value", sf.Name, tf) + continue // invalid inlined field; treat as ignored } if qe.visitChildren { queue = append(queue, queueEntry{tf, f.index, !seen[tf]}) } seen[tf] = true continue + } else if !sf.IsExported() { + serr = orErrorf(serr, t, "inlined Go struct field %s is not exported", sf.Name) + continue // invalid inlined field; treat as ignored } // Handle an inlined field that serializes to/from any number of - // JSON object members back by a Go map or RawValue. + // JSON object members back by a Go map or jsontext.Value. switch { - case tf == rawValueType: + case tf == jsontextValueType: f.fncs = nil // specially handled in arshal_inlined.go - case tf.Kind() == reflect.Map && tf.Key() == stringType: + case tf.Kind() == reflect.Map && tf.Key().Kind() == reflect.String: + if implementsAny(tf.Key(), allMethodTypes...) { + serr = orErrorf(serr, t, "inlined map field %s of type %s must have a string key that does not implement marshal or unmarshal methods", sf.Name, tf) + continue // invalid inlined field; treat as ignored + } f.fncs = lookupArshaler(tf.Elem()) default: - err := fmt.Errorf("inlined Go struct field %s of type %s must be a Go struct, Go map of string key, or json.RawValue", sf.Name, tf) - return structFields{}, &SemanticError{GoType: t, Err: err} + serr = orErrorf(serr, t, "inlined Go struct field %s of type %s must be a Go struct, Go map of string key, or jsontext.Value", sf.Name, tf) + continue // invalid inlined field; treat as ignored } // Reject multiple inlined fallback fields within the same struct. if inlinedFallbackIndex >= 0 { - err := fmt.Errorf("inlined Go struct fields %s and %s cannot both be a Go map or json.RawValue", t.Field(inlinedFallbackIndex).Name, sf.Name) - return structFields{}, &SemanticError{GoType: t, Err: err} + serr = orErrorf(serr, t, "inlined Go struct fields %s and %s cannot both be a Go map or jsontext.Value", t.Field(inlinedFallbackIndex).Name, sf.Name) + // Still append f to inlinedFallbacks as there is still a + // check for a dominant inlined fallback before returning. } inlinedFallbackIndex = i - // Multiple inlined fallback fields across different structs - // follow the same precedence rules as Go struct embedding. - if fs.inlinedFallback == nil { - fs.inlinedFallback = &f // store first occurrence at lowest depth - } else if len(fs.inlinedFallback.index) == len(f.index) { - fs.inlinedFallback = ambiguous // at least two occurrences at same depth - } + inlinedFallbacks = append(inlinedFallbacks, f) } else { // Handle normal Go struct field that serializes to/from // a single JSON object member. + // Unexported fields cannot be serialized except for + // embedded fields of a struct type, + // which might promote exported fields of their own. + if !sf.IsExported() { + tf := indirectType(f.typ) + if !(sf.Anonymous && tf.Kind() == reflect.Struct) { + serr = orErrorf(serr, t, "Go struct field %s is not exported", sf.Name) + continue + } + // Unfortunately, methods on the unexported field + // still cannot be called. + if implementsAny(tf, allMethodTypes...) || + (f.omitzero && implementsAny(tf, isZeroerType)) { + serr = orErrorf(serr, t, "Go struct field %s is not exported for method calls", sf.Name) + continue + } + } + // Provide a function that uses a type's IsZero method. switch { case sf.Type.Kind() == reflect.Interface && sf.Type.Implements(isZeroerType): @@ -202,29 +247,17 @@ func makeStructFields(root reflect.Type) (structFields, *SemanticError) { f.isEmpty = func(va addressableValue) bool { return va.IsNil() } } - f.id = len(fs.flattened) - f.fncs = lookupArshaler(sf.Type) - fs.flattened = append(fs.flattened, f) - - // Reject user-specified names with invalid UTF-8. - if !utf8.ValidString(f.name) { - err := fmt.Errorf("Go struct field %s has JSON object name %q with invalid UTF-8", sf.Name, f.name) - return structFields{}, &SemanticError{GoType: t, Err: err} - } // Reject multiple fields with same name within the same struct. if j, ok := namesIndex[f.name]; ok { - err := fmt.Errorf("Go struct fields %s and %s conflict over JSON object name %q", t.Field(j).Name, sf.Name, f.name) - return structFields{}, &SemanticError{GoType: t, Err: err} + serr = orErrorf(serr, t, "Go struct fields %s and %s conflict over JSON object name %q", t.Field(j).Name, sf.Name, f.name) + // Still append f to allFields as there is still a + // check for a dominant field before returning. } namesIndex[f.name] = i - // Multiple fields of the same name across different structs - // follow the same precedence rules as Go struct embedding. - if f2 := fs.byActualName[f.name]; f2 == nil { - fs.byActualName[f.name] = &fs.flattened[len(fs.flattened)-1] // store first occurrence at lowest depth - } else if len(f2.index) == len(f.index) { - fs.byActualName[f.name] = ambiguous // at least two occurrences at same depth - } + f.id = len(allFields) + f.fncs = lookupArshaler(sf.Type) + allFields = append(allFields, f) } } @@ -239,58 +272,58 @@ func makeStructFields(root reflect.Type) (structFields, *SemanticError) { // errors returned by errors.New would fail to serialize. isEmptyStruct := t.NumField() == 0 if !isEmptyStruct && !hasAnyJSONTag && !hasAnyJSONField { - err := errors.New("Go struct has no exported fields") - return structFields{}, &SemanticError{GoType: t, Err: err} + serr = cmp.Or(serr, &SemanticError{GoType: t, Err: errNoExportedFields}) } } - // Remove all fields that are duplicates. - // This may move elements forward to fill the holes from removed fields. - var n int - for _, f := range fs.flattened { - switch f2 := fs.byActualName[f.name]; { - case f2 == ambiguous: - delete(fs.byActualName, f.name) - case f2 == nil: - continue // may be nil due to previous delete - // TODO(https://go.dev/issue/45955): Use slices.Equal. - case reflect.DeepEqual(f.index, f2.index): - f.id = n - fs.flattened[n] = f - fs.byActualName[f.name] = &fs.flattened[n] // fix pointer to new location + // Sort the fields by exact name (breaking ties by depth and + // then by presence of an explicitly provided JSON name). + // Select the dominant field from each set of fields with the same name. + // If multiple fields have the same name, then the dominant field + // is the one that exists alone at the shallowest depth, + // or the one that is uniquely tagged with a JSON name. + // Otherwise, no dominant field exists for the set. + flattened := allFields[:0] + slices.SortStableFunc(allFields, func(x, y structField) int { + return cmp.Or( + strings.Compare(x.name, y.name), + cmp.Compare(len(x.index), len(y.index)), + boolsCompare(!x.hasName, !y.hasName)) + }) + for len(allFields) > 0 { + n := 1 // number of fields with the same exact name + for n < len(allFields) && allFields[n-1].name == allFields[n].name { n++ } + if n == 1 || len(allFields[0].index) != len(allFields[1].index) || allFields[0].hasName != allFields[1].hasName { + flattened = append(flattened, allFields[0]) // only keep field if there is a dominant field + } + allFields = allFields[n:] } - fs.flattened = fs.flattened[:n] - if fs.inlinedFallback == ambiguous { - fs.inlinedFallback = nil - } - if len(fs.flattened) != len(fs.byActualName) { - panic(fmt.Sprintf("BUG: flattened list of fields mismatches fields mapped by name: %d != %d", len(fs.flattened), len(fs.byActualName))) + + // Sort the fields according to a breadth-first ordering + // so that we can re-number IDs with the smallest possible values. + // This optimizes use of uintSet such that it fits in the 64-entry bit set. + slices.SortFunc(flattened, func(x, y structField) int { + return cmp.Compare(x.id, y.id) + }) + for i := range flattened { + flattened[i].id = i } - // Sort the fields according to a depth-first ordering. - // This operation will cause pointers in byActualName to become incorrect, - // which we will correct in another loop shortly thereafter. - sort.Slice(fs.flattened, func(i, j int) bool { - si := fs.flattened[i].index - sj := fs.flattened[j].index - for len(si) > 0 && len(sj) > 0 { - switch { - case si[0] < sj[0]: - return true - case si[0] > sj[0]: - return false - default: - si = si[1:] - sj = sj[1:] - } - } - return len(si) < len(sj) + // Sort the fields according to a depth-first ordering + // as the typical order that fields are marshaled. + slices.SortFunc(flattened, func(x, y structField) int { + return slices.Compare(x.index, y.index) }) - // Recompute the mapping of fields in the byActualName map. + // Compute the mapping of fields in the byActualName map. // Pre-fold all names so that we can lookup folded names quickly. + fs = structFields{ + flattened: flattened, + byActualName: make(map[string]*structField, len(flattened)), + byFoldedName: make(map[string][]*structField, len(flattened)), + } for i, f := range fs.flattened { foldedName := string(foldName([]byte(f.name))) fs.byActualName[f.name] = &fs.flattened[i] @@ -298,58 +331,99 @@ func makeStructFields(root reflect.Type) (structFields, *SemanticError) { } for foldedName, fields := range fs.byFoldedName { if len(fields) > 1 { - // The precedence order for conflicting nocase names + // The precedence order for conflicting ignoreCase names // is by breadth-first order, rather than depth-first order. - sort.Slice(fields, func(i, j int) bool { - return fields[i].id < fields[j].id + slices.SortFunc(fields, func(x, y *structField) int { + return cmp.Compare(x.id, y.id) }) fs.byFoldedName[foldedName] = fields } } + if n := len(inlinedFallbacks); n == 1 || (n > 1 && len(inlinedFallbacks[0].index) != len(inlinedFallbacks[1].index)) { + fs.inlinedFallback = &inlinedFallbacks[0] // dominant inlined fallback field + } + fs.reindex() + return fs, serr +} + +// indirectType unwraps one level of pointer indirection +// similar to how Go only allows embedding either T or *T, +// but not **T or P (which is a named pointer). +func indirectType(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Pointer && t.Name() == "" { + t = t.Elem() + } + return t +} - return fs, nil +// matchFoldedName matches a case-insensitive name depending on the options. +// It assumes that foldName(f.name) == foldName(name). +// +// Case-insensitive matching is used if the `case:ignore` tag option is specified +// or the MatchCaseInsensitiveNames call option is specified +// (and the `case:strict` tag option is not specified). +// Functionally, the `case:ignore` and `case:strict` tag options take precedence. +// +// The v1 definition of case-insensitivity operated under strings.EqualFold +// and would strictly compare dashes and underscores, +// while the v2 definition would ignore the presence of dashes and underscores. +// Thus, if the MatchCaseSensitiveDelimiter call option is specified, +// the match is further restricted to using strings.EqualFold. +func (f *structField) matchFoldedName(name []byte, flags *jsonflags.Flags) bool { + if f.casing == caseIgnore || (flags.Get(jsonflags.MatchCaseInsensitiveNames) && f.casing != caseStrict) { + if !flags.Get(jsonflags.MatchCaseSensitiveDelimiter) || strings.EqualFold(string(name), f.name) { + return true + } + } + return false } +const ( + caseIgnore = 1 + caseStrict = 2 +) + type fieldOptions struct { - name string - quotedName string // quoted name per RFC 8785, section 3.2.2.2. - hasName bool - nocase bool - inline bool - unknown bool - omitzero bool - omitempty bool - string bool - format string + name string + quotedName string // quoted name per RFC 8785, section 3.2.2.2. + hasName bool + nameNeedEscape bool + casing int8 // either 0, caseIgnore, or caseStrict + inline bool + unknown bool + omitzero bool + omitempty bool + string bool + format string } // parseFieldOptions parses the `json` tag in a Go struct field as // a structured set of options configuring parameters such as // the JSON member name and other features. -// As a special case, it returns errIgnoredField if the field is ignored. -func parseFieldOptions(sf reflect.StructField) (out fieldOptions, err error) { +func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, err error) { tag, hasTag := sf.Tag.Lookup("json") + tagOrig := tag // Check whether this field is explicitly ignored. if tag == "-" { - return fieldOptions{}, errIgnoredField + return fieldOptions{}, true, nil } - // Check whether this field is unexported. - if !sf.IsExported() { - // In contrast to v1, v2 no longer forwards exported fields from - // embedded fields of unexported types since Go reflection does not - // allow the same set of operations that are available in normal cases - // of purely exported fields. - // See https://go.dev/issue/21357 and https://go.dev/issue/24153. - if sf.Anonymous { - return fieldOptions{}, fmt.Errorf("embedded Go struct field %s of an unexported type must be explicitly ignored with a `json:\"-\"` tag", sf.Type.Name()) - } + // Check whether this field is unexported and not embedded, + // which Go reflection cannot mutate for the sake of serialization. + // + // An embedded field of an unexported type is still capable of + // forwarding exported fields, which may be JSON serialized. + // This technically operates on the edge of what is permissible by + // the Go language, but the most recent decision is to permit this. + // + // See https://go.dev/issue/24153 and https://go.dev/issue/32772. + if !sf.IsExported() && !sf.Anonymous { // Tag options specified on an unexported field suggests user error. if hasTag { - return fieldOptions{}, fmt.Errorf("unexported Go struct field %s cannot have non-ignored `json:%q` tag", sf.Name, tag) + err = cmp.Or(err, fmt.Errorf("unexported Go struct field %s cannot have non-ignored `json:%q` tag", sf.Name, tag)) } - return fieldOptions{}, errIgnoredField + return fieldOptions{}, true, err } // Determine the JSON member name for this Go field. A user-specified name @@ -362,20 +436,38 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, err error) { n := len(tag) - len(strings.TrimLeftFunc(tag, func(r rune) bool { return !strings.ContainsRune(",\\'\"`", r) // reserve comma, backslash, and quotes })) - opt := tag[:n] - if n == 0 { - // Allow a single quoted string for arbitrary names. - opt, n, err = consumeTagOption(tag) - if err != nil { - return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err) + name := tag[:n] + + // If the next character is not a comma, then the name is either + // malformed (if n > 0) or a single-quoted name. + // In either case, call consumeTagOption to handle it further. + var err2 error + if !strings.HasPrefix(tag[n:], ",") && len(name) != len(tag) { + name, n, err2 = consumeTagOption(tag) + if err2 != nil { + err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err2)) } } - out.hasName = true - out.name = opt + if !utf8.ValidString(name) { + err = cmp.Or(err, fmt.Errorf("Go struct field %s has JSON object name %q with invalid UTF-8", sf.Name, name)) + name = string([]rune(name)) // replace invalid UTF-8 with utf8.RuneError + } + if name == "-" && tag[0] == '-' { + defer func() { // defer to let other errors take precedence + err = cmp.Or(err, fmt.Errorf("Go struct field %s has JSON object name %q; either "+ + "use `json:\"-\"` to ignore the field or "+ + "use `json:\"'-'%s` to specify %q as the name", sf.Name, out.name, strings.TrimPrefix(strconv.Quote(tagOrig), `"-`), name)) + }() + } + if err2 == nil { + out.hasName = true + out.name = name + } tag = tag[n:] } - b, _ := appendString(nil, out.name, false, nil) + b, _ := jsonwire.AppendQuote(nil, out.name, &jsonflags.Flags{}) out.quotedName = string(b) + out.nameNeedEscape = jsonwire.NeedEscape(out.name) // Handle any additional tag options (if any). var wasFormat bool @@ -383,29 +475,53 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, err error) { for len(tag) > 0 { // Consume comma delimiter. if tag[0] != ',' { - return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: invalid character %q before next option (expecting ',')", sf.Name, tag[0]) - } - tag = tag[len(","):] - if len(tag) == 0 { - return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: invalid trailing ',' character", sf.Name) + err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed `json` tag: invalid character %q before next option (expecting ',')", sf.Name, tag[0])) + } else { + tag = tag[len(","):] + if len(tag) == 0 { + err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed `json` tag: invalid trailing ',' character", sf.Name)) + break + } } // Consume and process the tag option. - opt, n, err := consumeTagOption(tag) - if err != nil { - return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err) + opt, n, err2 := consumeTagOption(tag) + if err2 != nil { + err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err2)) } rawOpt := tag[:n] tag = tag[n:] switch { case wasFormat: - return fieldOptions{}, fmt.Errorf("Go struct field %s has `format` tag option that was not specified last", sf.Name) + err = cmp.Or(err, fmt.Errorf("Go struct field %s has `format` tag option that was not specified last", sf.Name)) case strings.HasPrefix(rawOpt, "'") && strings.TrimFunc(opt, isLetterOrDigit) == "": - return fieldOptions{}, fmt.Errorf("Go struct field %s has unnecessarily quoted appearance of `%s` tag option; specify `%s` instead", sf.Name, rawOpt, opt) + err = cmp.Or(err, fmt.Errorf("Go struct field %s has unnecessarily quoted appearance of `%s` tag option; specify `%s` instead", sf.Name, rawOpt, opt)) } switch opt { - case "nocase": - out.nocase = true + case "case": + if !strings.HasPrefix(tag, ":") { + err = cmp.Or(err, fmt.Errorf("Go struct field %s is missing value for `case` tag option; specify `case:ignore` or `case:strict` instead", sf.Name)) + break + } + tag = tag[len(":"):] + opt, n, err2 := consumeTagOption(tag) + if err2 != nil { + err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed value for `case` tag option: %v", sf.Name, err2)) + break + } + rawOpt := tag[:n] + tag = tag[n:] + if strings.HasPrefix(rawOpt, "'") { + err = cmp.Or(err, fmt.Errorf("Go struct field %s has unnecessarily quoted appearance of `case:%s` tag option; specify `case:%s` instead", sf.Name, rawOpt, opt)) + } + switch opt { + case "ignore": + out.casing |= caseIgnore + case "strict": + out.casing |= caseStrict + default: + err = cmp.Or(err, fmt.Errorf("Go struct field %s has unknown `case:%s` tag value", sf.Name, rawOpt)) + } case "inline": out.inline = true case "unknown": @@ -418,12 +534,14 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, err error) { out.string = true case "format": if !strings.HasPrefix(tag, ":") { - return fieldOptions{}, fmt.Errorf("Go struct field %s is missing value for `format` tag option", sf.Name) + err = cmp.Or(err, fmt.Errorf("Go struct field %s is missing value for `format` tag option", sf.Name)) + break } tag = tag[len(":"):] - opt, n, err := consumeTagOption(tag) - if err != nil { - return fieldOptions{}, fmt.Errorf("Go struct field %s has malformed value for `format` tag option: %v", sf.Name, err) + opt, n, err2 := consumeTagOption(tag) + if err2 != nil { + err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed value for `format` tag option: %v", sf.Name, err2)) + break } tag = tag[n:] out.format = opt @@ -433,8 +551,8 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, err error) { // This catches invalid mutants such as "omitEmpty" or "omit_empty". normOpt := strings.ReplaceAll(strings.ToLower(opt), "_", "") switch normOpt { - case "nocase", "inline", "unknown", "omitzero", "omitempty", "string", "format": - return fieldOptions{}, fmt.Errorf("Go struct field %s has invalid appearance of `%s` tag option; specify `%s` instead", sf.Name, opt, normOpt) + case "case", "inline", "unknown", "omitzero", "omitempty", "string", "format": + err = cmp.Or(err, fmt.Errorf("Go struct field %s has invalid appearance of `%s` tag option; specify `%s` instead", sf.Name, opt, normOpt)) } // NOTE: Everything else is ignored. This does not mean it is @@ -443,15 +561,28 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, err error) { } // Reject duplicates. - if seenOpts[opt] { - return fieldOptions{}, fmt.Errorf("Go struct field %s has duplicate appearance of `%s` tag option", sf.Name, rawOpt) + switch { + case out.casing == caseIgnore|caseStrict: + err = cmp.Or(err, fmt.Errorf("Go struct field %s cannot have both `case:ignore` and `case:strict` tag options", sf.Name)) + case seenOpts[opt]: + err = cmp.Or(err, fmt.Errorf("Go struct field %s has duplicate appearance of `%s` tag option", sf.Name, rawOpt)) } seenOpts[opt] = true } - return out, nil + return out, false, err } +// consumeTagOption consumes the next option, +// which is either a Go identifier or a single-quoted string. +// If the next option is invalid, it returns all of in until the next comma, +// and reports an error. func consumeTagOption(in string) (string, int, error) { + // For legacy compatibility with v1, assume options are comma-separated. + i := strings.IndexByte(in, ',') + if i < 0 { + i = len(in) + } + switch r, _ := utf8.DecodeRuneInString(in); { // Option as a Go identifier. case r == '_' || unicode.IsLetter(r): @@ -486,7 +617,7 @@ func consumeTagOption(in string) (string, int, error) { n += len(`'`) out, err := strconv.Unquote(string(b)) if err != nil { - return "", 0, fmt.Errorf("invalid single-quoted string: %s", in[:n]) + return in[:i], i, fmt.Errorf("invalid single-quoted string: %s", in[:n]) } return out, n, nil } @@ -496,14 +627,26 @@ func consumeTagOption(in string) (string, int, error) { if n > 10 { n = 10 // limit the amount of context printed in the error } - return "", 0, fmt.Errorf("single-quoted string not terminated: %s...", in[:n]) + return in[:i], i, fmt.Errorf("single-quoted string not terminated: %s...", in[:n]) case len(in) == 0: - return "", 0, io.ErrUnexpectedEOF + return in[:i], i, io.ErrUnexpectedEOF default: - return "", 0, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter or single quote)", r) + return in[:i], i, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter or single quote)", r) } } func isLetterOrDigit(r rune) bool { return r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r) } + +// boolsCompare compares x and y, ordering false before true. +func boolsCompare(x, y bool) int { + switch { + case !x && y: + return -1 + default: + return 0 + case x && !y: + return +1 + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go index 700a56db..42fc3d47 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/intern.go @@ -10,12 +10,12 @@ import ( ) // stringCache is a cache for strings converted from a []byte. -type stringCache [256]string // 256*unsafe.Sizeof(string("")) => 4KiB +type stringCache = [256]string // 256*unsafe.Sizeof(string("")) => 4KiB -// make returns the string form of b. +// makeString returns the string form of b. // It returns a pre-allocated string from c if present, otherwise // it allocates a new string, inserts it into the cache, and returns it. -func (c *stringCache) make(b []byte) string { +func makeString(c *stringCache, b []byte) string { const ( minCachedLen = 2 // single byte strings are already interned by the runtime maxCachedLen = 256 // large enough for UUIDs, IPv6 addresses, SHA-256 checksums, etc. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go new file mode 100644 index 00000000..05801c6b --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/internal.go @@ -0,0 +1,40 @@ +// Copyright 2023 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 internal + +import "errors" + +// NotForPublicUse is a marker type that an API is for internal use only. +// It does not perfectly prevent usage of that API, but helps to restrict usage. +// Anything with this marker is not covered by the Go compatibility agreement. +type NotForPublicUse struct{} + +// AllowInternalUse is passed from "json" to "jsontext" to authenticate +// that the caller can have access to internal functionality. +var AllowInternalUse NotForPublicUse + +// Sentinel error values internally shared between jsonv1 and jsonv2. +var ( + ErrCycle = errors.New("encountered a cycle") + ErrNonNilReference = errors.New("value must be passed as a non-nil pointer reference") + ErrNilInterface = errors.New("cannot derive concrete type for nil interface with finite type set") +) + +var ( + // TransformMarshalError converts a v2 error into a v1 error. + // It is called only at the top-level of a Marshal function. + TransformMarshalError func(any, error) error + // NewMarshalerError constructs a jsonv1.MarshalerError. + // It is called after a user-defined Marshal method/function fails. + NewMarshalerError func(any, error, string) error + // TransformUnmarshalError converts a v2 error into a v1 error. + // It is called only at the top-level of a Unmarshal function. + TransformUnmarshalError func(any, error) error + + // NewRawNumber returns new(jsonv1.Number). + NewRawNumber func() any + // RawNumberOf returns jsonv1.Number(b). + RawNumberOf func(b []byte) any +) diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go new file mode 100644 index 00000000..810128b5 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags/flags.go @@ -0,0 +1,213 @@ +// Copyright 2023 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. + +// jsonflags implements all the optional boolean flags. +// These flags are shared across both "json", "jsontext", and "jsonopts". +package jsonflags + +import "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + +// Bools represents zero or more boolean flags, all set to true or false. +// The least-significant bit is the boolean value of all flags in the set. +// The remaining bits identify which particular flags. +// +// In common usage, this is OR'd with 0 or 1. For example: +// - (AllowInvalidUTF8 | 0) means "AllowInvalidUTF8 is false" +// - (Multiline | Indent | 1) means "Multiline and Indent are true" +type Bools uint64 + +func (Bools) JSONOptions(internal.NotForPublicUse) {} + +const ( + // AllFlags is the set of all flags. + AllFlags = AllCoderFlags | AllArshalV2Flags | AllArshalV1Flags + + // AllCoderFlags is the set of all encoder/decoder flags. + AllCoderFlags = (maxCoderFlag - 1) - initFlag + + // AllArshalV2Flags is the set of all v2 marshal/unmarshal flags. + AllArshalV2Flags = (maxArshalV2Flag - 1) - (maxCoderFlag - 1) + + // AllArshalV1Flags is the set of all v1 marshal/unmarshal flags. + AllArshalV1Flags = (maxArshalV1Flag - 1) - (maxArshalV2Flag - 1) + + // NonBooleanFlags is the set of non-boolean flags, + // where the value is some other concrete Go type. + // The value of the flag is stored within jsonopts.Struct. + NonBooleanFlags = 0 | + Indent | + IndentPrefix | + ByteLimit | + DepthLimit | + Marshalers | + Unmarshalers + + // DefaultV1Flags is the set of booleans flags that default to true under + // v1 semantics. None of the non-boolean flags differ between v1 and v2. + DefaultV1Flags = 0 | + AllowDuplicateNames | + AllowInvalidUTF8 | + EscapeForHTML | + EscapeForJS | + PreserveRawStrings | + Deterministic | + FormatNilMapAsNull | + FormatNilSliceAsNull | + MatchCaseInsensitiveNames | + CallMethodsWithLegacySemantics | + FormatByteArrayAsArray | + FormatBytesWithLegacySemantics | + FormatDurationAsNano | + MatchCaseSensitiveDelimiter | + MergeWithLegacySemantics | + OmitEmptyWithLegacySemantics | + ParseBytesWithLooseRFC4648 | + ParseTimeWithLooseRFC3339 | + ReportErrorsWithLegacySemantics | + StringifyWithLegacySemantics | + UnmarshalArrayFromAnyLength + + // AnyWhitespace reports whether the encoded output might have any whitespace. + AnyWhitespace = Multiline | SpaceAfterColon | SpaceAfterComma + + // WhitespaceFlags is the set of flags related to whitespace formatting. + // In contrast to AnyWhitespace, this includes Indent and IndentPrefix + // as those settings take no effect if Multiline is false. + WhitespaceFlags = AnyWhitespace | Indent | IndentPrefix + + // AnyEscape is the set of flags related to escaping in a JSON string. + AnyEscape = EscapeForHTML | EscapeForJS + + // CanonicalizeNumbers is the set of flags related to raw number canonicalization. + CanonicalizeNumbers = CanonicalizeRawInts | CanonicalizeRawFloats +) + +// Encoder and decoder flags. +const ( + initFlag Bools = 1 << iota // reserved for the boolean value itself + + AllowDuplicateNames // encode or decode + AllowInvalidUTF8 // encode or decode + WithinArshalCall // encode or decode; for internal use by json.Marshal and json.Unmarshal + OmitTopLevelNewline // encode only; for internal use by json.Marshal and json.MarshalWrite + PreserveRawStrings // encode only + CanonicalizeRawInts // encode only + CanonicalizeRawFloats // encode only + ReorderRawObjects // encode only + EscapeForHTML // encode only + EscapeForJS // encode only + Multiline // encode only + SpaceAfterColon // encode only + SpaceAfterComma // encode only + Indent // encode only; non-boolean flag + IndentPrefix // encode only; non-boolean flag + ByteLimit // encode or decode; non-boolean flag + DepthLimit // encode or decode; non-boolean flag + + maxCoderFlag +) + +// Marshal and Unmarshal flags (for v2). +const ( + _ Bools = (maxCoderFlag >> 1) << iota + + StringifyNumbers // marshal or unmarshal + Deterministic // marshal only + FormatNilMapAsNull // marshal only + FormatNilSliceAsNull // marshal only + OmitZeroStructFields // marshal only + MatchCaseInsensitiveNames // marshal or unmarshal + DiscardUnknownMembers // marshal only + RejectUnknownMembers // unmarshal only + Marshalers // marshal only; non-boolean flag + Unmarshalers // unmarshal only; non-boolean flag + + maxArshalV2Flag +) + +// Marshal and Unmarshal flags (for v1). +const ( + _ Bools = (maxArshalV2Flag >> 1) << iota + + CallMethodsWithLegacySemantics // marshal or unmarshal + FormatByteArrayAsArray // marshal or unmarshal + FormatBytesWithLegacySemantics // marshal or unmarshal + FormatDurationAsNano // marshal or unmarshal + MatchCaseSensitiveDelimiter // marshal or unmarshal + MergeWithLegacySemantics // unmarshal + OmitEmptyWithLegacySemantics // marshal + ParseBytesWithLooseRFC4648 // unmarshal + ParseTimeWithLooseRFC3339 // unmarshal + ReportErrorsWithLegacySemantics // marshal or unmarshal + StringifyWithLegacySemantics // marshal or unmarshal + StringifyBoolsAndStrings // marshal or unmarshal; for internal use by jsonv2.makeStructArshaler + UnmarshalAnyWithRawNumber // unmarshal; for internal use by jsonv1.Decoder.UseNumber + UnmarshalArrayFromAnyLength // unmarshal + + maxArshalV1Flag +) + +// bitsUsed is the number of bits used in the 64-bit boolean flags +const bitsUsed = 42 + +// Static compile check that bitsUsed and maxArshalV1Flag are in sync. +const _ = uint64((1< 0b_110_11011 + dst.Values &= ^src.Presence // e.g., 0b_1000_0011 & 0b_1010_0101 -> 0b_100_00001 + dst.Values |= src.Values // e.g., 0b_1000_0001 | 0b_1001_0010 -> 0b_100_10011 +} + +// Set sets both the presence and value for the provided bool (or set of bools). +func (fs *Flags) Set(f Bools) { + // Select out the bits for the flag identifiers (everything except LSB), + // then set the presence for all the identifier bits (using OR), + // then invert the identifier bits to clear out the values (using AND-NOT), + // then copy over all the identifier bits to the value if LSB is 1. + // e.g., fs := Flags{Presence: 0b_0101_0010, Value: 0b_0001_0010} + // e.g., f := 0b_1001_0001 + id := uint64(f) &^ uint64(1) // e.g., 0b_1001_0001 & 0b_1111_1110 -> 0b_1001_0000 + fs.Presence |= id // e.g., 0b_0101_0010 | 0b_1001_0000 -> 0b_1101_0011 + fs.Values &= ^id // e.g., 0b_0001_0010 & 0b_0110_1111 -> 0b_0000_0010 + fs.Values |= uint64(f&1) * id // e.g., 0b_0000_0010 | 0b_1001_0000 -> 0b_1001_0010 +} + +// Get reports whether the bool (or any of the bools) is true. +// This is generally only used with a singular bool. +// The value bit of f (i.e., the LSB) is ignored. +func (fs Flags) Get(f Bools) bool { + return fs.Values&uint64(f) > 0 +} + +// Has reports whether the bool (or any of the bools) is set. +// The value bit of f (i.e., the LSB) is ignored. +func (fs Flags) Has(f Bools) bool { + return fs.Presence&uint64(f) > 0 +} + +// Clear clears both the presence and value for the provided bool or bools. +// The value bit of f (i.e., the LSB) is ignored. +func (fs *Flags) Clear(f Bools) { + // Invert f to produce a mask to clear all bits in f (using AND). + // e.g., fs := Flags{Presence: 0b_0101_0010, Value: 0b_0001_0010} + // e.g., f := 0b_0001_1000 + mask := uint64(^f) // e.g., 0b_0001_1000 -> 0b_1110_0111 + fs.Presence &= mask // e.g., 0b_0101_0010 & 0b_1110_0111 -> 0b_0100_0010 + fs.Values &= mask // e.g., 0b_0001_0010 & 0b_1110_0111 -> 0b_0000_0010 +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go new file mode 100644 index 00000000..14265351 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts/options.go @@ -0,0 +1,200 @@ +// Copyright 2023 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 jsonopts + +import ( + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" +) + +// Options is the common options type shared across json packages. +type Options interface { + // JSONOptions is exported so related json packages can implement Options. + JSONOptions(internal.NotForPublicUse) +} + +// Struct is the combination of all options in struct form. +// This is efficient to pass down the call stack and to query. +type Struct struct { + Flags jsonflags.Flags + + CoderValues + ArshalValues +} + +type CoderValues struct { + Indent string // jsonflags.Indent + IndentPrefix string // jsonflags.IndentPrefix + ByteLimit int64 // jsonflags.ByteLimit + DepthLimit int // jsonflags.DepthLimit +} + +type ArshalValues struct { + // The Marshalers and Unmarshalers fields use the any type to avoid a + // concrete dependency on *json.Marshalers and *json.Unmarshalers, + // which would in turn create a dependency on the "reflect" package. + + Marshalers any // jsonflags.Marshalers + Unmarshalers any // jsonflags.Unmarshalers + + Format string + FormatDepth int +} + +// DefaultOptionsV2 is the set of all options that define default v2 behavior. +var DefaultOptionsV2 = Struct{ + Flags: jsonflags.Flags{ + Presence: uint64(jsonflags.AllFlags & ^jsonflags.WhitespaceFlags), + Values: uint64(0), + }, +} + +// DefaultOptionsV1 is the set of all options that define default v1 behavior. +var DefaultOptionsV1 = Struct{ + Flags: jsonflags.Flags{ + Presence: uint64(jsonflags.AllFlags & ^jsonflags.WhitespaceFlags), + Values: uint64(jsonflags.DefaultV1Flags), + }, +} + +func (*Struct) JSONOptions(internal.NotForPublicUse) {} + +// GetUnknownOption is injected by the "json" package to handle Options +// declared in that package so that "jsonopts" can handle them. +var GetUnknownOption = func(Struct, Options) (any, bool) { panic("unknown option") } + +func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { + // Collapse the options to *Struct to simplify lookup. + structOpts, ok := opts.(*Struct) + if !ok { + var structOpts2 Struct + structOpts2.Join(opts) + structOpts = &structOpts2 + } + + // Lookup the option based on the return value of the setter. + var zero T + switch opt := setter(zero).(type) { + case jsonflags.Bools: + v := structOpts.Flags.Get(opt) + ok := structOpts.Flags.Has(opt) + return any(v).(T), ok + case Indent: + if !structOpts.Flags.Has(jsonflags.Indent) { + return zero, false + } + return any(structOpts.Indent).(T), true + case IndentPrefix: + if !structOpts.Flags.Has(jsonflags.IndentPrefix) { + return zero, false + } + return any(structOpts.IndentPrefix).(T), true + case ByteLimit: + if !structOpts.Flags.Has(jsonflags.ByteLimit) { + return zero, false + } + return any(structOpts.ByteLimit).(T), true + case DepthLimit: + if !structOpts.Flags.Has(jsonflags.DepthLimit) { + return zero, false + } + return any(structOpts.DepthLimit).(T), true + default: + v, ok := GetUnknownOption(*structOpts, opt) + return v.(T), ok + } +} + +// JoinUnknownOption is injected by the "json" package to handle Options +// declared in that package so that "jsonopts" can handle them. +var JoinUnknownOption = func(Struct, Options) Struct { panic("unknown option") } + +func (dst *Struct) Join(srcs ...Options) { + dst.join(false, srcs...) +} + +func (dst *Struct) JoinWithoutCoderOptions(srcs ...Options) { + dst.join(true, srcs...) +} + +func (dst *Struct) join(excludeCoderOptions bool, srcs ...Options) { + for _, src := range srcs { + switch src := src.(type) { + case nil: + continue + case jsonflags.Bools: + if excludeCoderOptions { + src &= ^jsonflags.AllCoderFlags + } + dst.Flags.Set(src) + case Indent: + if excludeCoderOptions { + continue + } + dst.Flags.Set(jsonflags.Multiline | jsonflags.Indent | 1) + dst.Indent = string(src) + case IndentPrefix: + if excludeCoderOptions { + continue + } + dst.Flags.Set(jsonflags.Multiline | jsonflags.IndentPrefix | 1) + dst.IndentPrefix = string(src) + case ByteLimit: + if excludeCoderOptions { + continue + } + dst.Flags.Set(jsonflags.ByteLimit | 1) + dst.ByteLimit = int64(src) + case DepthLimit: + if excludeCoderOptions { + continue + } + dst.Flags.Set(jsonflags.DepthLimit | 1) + dst.DepthLimit = int(src) + case *Struct: + srcFlags := src.Flags // shallow copy the flags + if excludeCoderOptions { + srcFlags.Clear(jsonflags.AllCoderFlags) + } + dst.Flags.Join(srcFlags) + if srcFlags.Has(jsonflags.NonBooleanFlags) { + if srcFlags.Has(jsonflags.Indent) { + dst.Indent = src.Indent + } + if srcFlags.Has(jsonflags.IndentPrefix) { + dst.IndentPrefix = src.IndentPrefix + } + if srcFlags.Has(jsonflags.ByteLimit) { + dst.ByteLimit = src.ByteLimit + } + if srcFlags.Has(jsonflags.DepthLimit) { + dst.DepthLimit = src.DepthLimit + } + if srcFlags.Has(jsonflags.Marshalers) { + dst.Marshalers = src.Marshalers + } + if srcFlags.Has(jsonflags.Unmarshalers) { + dst.Unmarshalers = src.Unmarshalers + } + } + default: + *dst = JoinUnknownOption(*dst, src) + } + } +} + +type ( + Indent string // jsontext.WithIndent + IndentPrefix string // jsontext.WithIndentPrefix + ByteLimit int64 // jsontext.WithByteLimit + DepthLimit int // jsontext.WithDepthLimit + // type for jsonflags.Marshalers declared in "json" package + // type for jsonflags.Unmarshalers declared in "json" package +) + +func (Indent) JSONOptions(internal.NotForPublicUse) {} +func (IndentPrefix) JSONOptions(internal.NotForPublicUse) {} +func (ByteLimit) JSONOptions(internal.NotForPublicUse) {} +func (DepthLimit) JSONOptions(internal.NotForPublicUse) {} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go new file mode 100644 index 00000000..02787719 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/decode.go @@ -0,0 +1,627 @@ +// Copyright 2023 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 jsonwire + +import ( + "io" + "math" + "slices" + "strconv" + "unicode/utf16" + "unicode/utf8" +) + +type ValueFlags uint + +const ( + _ ValueFlags = (1 << iota) / 2 // powers of two starting with zero + + stringNonVerbatim // string cannot be naively treated as valid UTF-8 + stringNonCanonical // string not formatted according to RFC 8785, section 3.2.2.2. + // TODO: Track whether a number is a non-integer? +) + +func (f *ValueFlags) Join(f2 ValueFlags) { *f |= f2 } +func (f ValueFlags) IsVerbatim() bool { return f&stringNonVerbatim == 0 } +func (f ValueFlags) IsCanonical() bool { return f&stringNonCanonical == 0 } + +// ConsumeWhitespace consumes leading JSON whitespace per RFC 7159, section 2. +func ConsumeWhitespace(b []byte) (n int) { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + for len(b) > n && (b[n] == ' ' || b[n] == '\t' || b[n] == '\r' || b[n] == '\n') { + n++ + } + return n +} + +// ConsumeNull consumes the next JSON null literal per RFC 7159, section 3. +// It returns 0 if it is invalid, in which case consumeLiteral should be used. +func ConsumeNull(b []byte) int { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + const literal = "null" + if len(b) >= len(literal) && string(b[:len(literal)]) == literal { + return len(literal) + } + return 0 +} + +// ConsumeFalse consumes the next JSON false literal per RFC 7159, section 3. +// It returns 0 if it is invalid, in which case consumeLiteral should be used. +func ConsumeFalse(b []byte) int { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + const literal = "false" + if len(b) >= len(literal) && string(b[:len(literal)]) == literal { + return len(literal) + } + return 0 +} + +// ConsumeTrue consumes the next JSON true literal per RFC 7159, section 3. +// It returns 0 if it is invalid, in which case consumeLiteral should be used. +func ConsumeTrue(b []byte) int { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + const literal = "true" + if len(b) >= len(literal) && string(b[:len(literal)]) == literal { + return len(literal) + } + return 0 +} + +// ConsumeLiteral consumes the next JSON literal per RFC 7159, section 3. +// If the input appears truncated, it returns io.ErrUnexpectedEOF. +func ConsumeLiteral(b []byte, lit string) (n int, err error) { + for i := 0; i < len(b) && i < len(lit); i++ { + if b[i] != lit[i] { + return i, NewInvalidCharacterError(b[i:], "in literal "+lit+" (expecting "+strconv.QuoteRune(rune(lit[i]))+")") + } + } + if len(b) < len(lit) { + return len(b), io.ErrUnexpectedEOF + } + return len(lit), nil +} + +// ConsumeSimpleString consumes the next JSON string per RFC 7159, section 7 +// but is limited to the grammar for an ASCII string without escape sequences. +// It returns 0 if it is invalid or more complicated than a simple string, +// in which case consumeString should be called. +// +// It rejects '<', '>', and '&' for compatibility reasons since these were +// always escaped in the v1 implementation. Thus, if this function reports +// non-zero then we know that the string would be encoded the same way +// under both v1 or v2 escape semantics. +func ConsumeSimpleString(b []byte) (n int) { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + if len(b) > 0 && b[0] == '"' { + n++ + for len(b) > n && b[n] < utf8.RuneSelf && escapeASCII[b[n]] == 0 { + n++ + } + if uint(len(b)) > uint(n) && b[n] == '"' { + n++ + return n + } + } + return 0 +} + +// ConsumeString consumes the next JSON string per RFC 7159, section 7. +// If validateUTF8 is false, then this allows the presence of invalid UTF-8 +// characters within the string itself. +// It reports the number of bytes consumed and whether an error was encountered. +// If the input appears truncated, it returns io.ErrUnexpectedEOF. +func ConsumeString(flags *ValueFlags, b []byte, validateUTF8 bool) (n int, err error) { + return ConsumeStringResumable(flags, b, 0, validateUTF8) +} + +// ConsumeStringResumable is identical to consumeString but supports resuming +// from a previous call that returned io.ErrUnexpectedEOF. +func ConsumeStringResumable(flags *ValueFlags, b []byte, resumeOffset int, validateUTF8 bool) (n int, err error) { + // Consume the leading double quote. + switch { + case resumeOffset > 0: + n = resumeOffset // already handled the leading quote + case uint(len(b)) == 0: + return n, io.ErrUnexpectedEOF + case b[0] == '"': + n++ + default: + return n, NewInvalidCharacterError(b[n:], `at start of string (expecting '"')`) + } + + // Consume every character in the string. + for uint(len(b)) > uint(n) { + // Optimize for long sequences of unescaped characters. + noEscape := func(c byte) bool { + return c < utf8.RuneSelf && ' ' <= c && c != '\\' && c != '"' + } + for uint(len(b)) > uint(n) && noEscape(b[n]) { + n++ + } + if uint(len(b)) <= uint(n) { + return n, io.ErrUnexpectedEOF + } + + // Check for terminating double quote. + if b[n] == '"' { + n++ + return n, nil + } + + switch r, rn := utf8.DecodeRune(b[n:]); { + // Handle UTF-8 encoded byte sequence. + // Due to specialized handling of ASCII above, we know that + // all normal sequences at this point must be 2 bytes or larger. + case rn > 1: + n += rn + // Handle escape sequence. + case r == '\\': + flags.Join(stringNonVerbatim) + resumeOffset = n + if uint(len(b)) < uint(n+2) { + return resumeOffset, io.ErrUnexpectedEOF + } + switch r := b[n+1]; r { + case '/': + // Forward slash is the only character with 3 representations. + // Per RFC 8785, section 3.2.2.2., this must not be escaped. + flags.Join(stringNonCanonical) + n += 2 + case '"', '\\', 'b', 'f', 'n', 'r', 't': + n += 2 + case 'u': + if uint(len(b)) < uint(n+6) { + if hasEscapedUTF16Prefix(b[n:], false) { + return resumeOffset, io.ErrUnexpectedEOF + } + flags.Join(stringNonCanonical) + return n, NewInvalidEscapeSequenceError(b[n:]) + } + v1, ok := parseHexUint16(b[n+2 : n+6]) + if !ok { + flags.Join(stringNonCanonical) + return n, NewInvalidEscapeSequenceError(b[n : n+6]) + } + // Only certain control characters can use the \uFFFF notation + // for canonical formatting (per RFC 8785, section 3.2.2.2.). + switch v1 { + // \uFFFF notation not permitted for these characters. + case '\b', '\f', '\n', '\r', '\t': + flags.Join(stringNonCanonical) + default: + // \uFFFF notation only permitted for control characters. + if v1 >= ' ' { + flags.Join(stringNonCanonical) + } else { + // \uFFFF notation must be lower case. + for _, c := range b[n+2 : n+6] { + if 'A' <= c && c <= 'F' { + flags.Join(stringNonCanonical) + } + } + } + } + n += 6 + + r := rune(v1) + if validateUTF8 && utf16.IsSurrogate(r) { + if uint(len(b)) < uint(n+6) { + if hasEscapedUTF16Prefix(b[n:], true) { + return resumeOffset, io.ErrUnexpectedEOF + } + flags.Join(stringNonCanonical) + return n - 6, NewInvalidEscapeSequenceError(b[n-6:]) + } else if v2, ok := parseHexUint16(b[n+2 : n+6]); b[n] != '\\' || b[n+1] != 'u' || !ok { + flags.Join(stringNonCanonical) + return n - 6, NewInvalidEscapeSequenceError(b[n-6 : n+6]) + } else if r = utf16.DecodeRune(rune(v1), rune(v2)); r == utf8.RuneError { + flags.Join(stringNonCanonical) + return n - 6, NewInvalidEscapeSequenceError(b[n-6 : n+6]) + } else { + n += 6 + } + } + default: + flags.Join(stringNonCanonical) + return n, NewInvalidEscapeSequenceError(b[n : n+2]) + } + // Handle invalid UTF-8. + case r == utf8.RuneError: + if !utf8.FullRune(b[n:]) { + return n, io.ErrUnexpectedEOF + } + flags.Join(stringNonVerbatim | stringNonCanonical) + if validateUTF8 { + return n, ErrInvalidUTF8 + } + n++ + // Handle invalid control characters. + case r < ' ': + flags.Join(stringNonVerbatim | stringNonCanonical) + return n, NewInvalidCharacterError(b[n:], "in string (expecting non-control character)") + default: + panic("BUG: unhandled character " + QuoteRune(b[n:])) + } + } + return n, io.ErrUnexpectedEOF +} + +// AppendUnquote appends the unescaped form of a JSON string in src to dst. +// Any invalid UTF-8 within the string will be replaced with utf8.RuneError, +// but the error will be specified as having encountered such an error. +// The input must be an entire JSON string with no surrounding whitespace. +func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) (v []byte, err error) { + dst = slices.Grow(dst, len(src)) + + // Consume the leading double quote. + var i, n int + switch { + case uint(len(src)) == 0: + return dst, io.ErrUnexpectedEOF + case src[0] == '"': + i, n = 1, 1 + default: + return dst, NewInvalidCharacterError(src, `at start of string (expecting '"')`) + } + + // Consume every character in the string. + for uint(len(src)) > uint(n) { + // Optimize for long sequences of unescaped characters. + noEscape := func(c byte) bool { + return c < utf8.RuneSelf && ' ' <= c && c != '\\' && c != '"' + } + for uint(len(src)) > uint(n) && noEscape(src[n]) { + n++ + } + if uint(len(src)) <= uint(n) { + dst = append(dst, src[i:n]...) + return dst, io.ErrUnexpectedEOF + } + + // Check for terminating double quote. + if src[n] == '"' { + dst = append(dst, src[i:n]...) + n++ + if n < len(src) { + err = NewInvalidCharacterError(src[n:], "after string value") + } + return dst, err + } + + switch r, rn := utf8.DecodeRuneInString(string(truncateMaxUTF8(src[n:]))); { + // Handle UTF-8 encoded byte sequence. + // Due to specialized handling of ASCII above, we know that + // all normal sequences at this point must be 2 bytes or larger. + case rn > 1: + n += rn + // Handle escape sequence. + case r == '\\': + dst = append(dst, src[i:n]...) + + // Handle escape sequence. + if uint(len(src)) < uint(n+2) { + return dst, io.ErrUnexpectedEOF + } + switch r := src[n+1]; r { + case '"', '\\', '/': + dst = append(dst, r) + n += 2 + case 'b': + dst = append(dst, '\b') + n += 2 + case 'f': + dst = append(dst, '\f') + n += 2 + case 'n': + dst = append(dst, '\n') + n += 2 + case 'r': + dst = append(dst, '\r') + n += 2 + case 't': + dst = append(dst, '\t') + n += 2 + case 'u': + if uint(len(src)) < uint(n+6) { + if hasEscapedUTF16Prefix(src[n:], false) { + return dst, io.ErrUnexpectedEOF + } + return dst, NewInvalidEscapeSequenceError(src[n:]) + } + v1, ok := parseHexUint16(src[n+2 : n+6]) + if !ok { + return dst, NewInvalidEscapeSequenceError(src[n : n+6]) + } + n += 6 + + // Check whether this is a surrogate half. + r := rune(v1) + if utf16.IsSurrogate(r) { + r = utf8.RuneError // assume failure unless the following succeeds + if uint(len(src)) < uint(n+6) { + if hasEscapedUTF16Prefix(src[n:], true) { + return utf8.AppendRune(dst, r), io.ErrUnexpectedEOF + } + err = NewInvalidEscapeSequenceError(src[n-6:]) + } else if v2, ok := parseHexUint16(src[n+2 : n+6]); src[n] != '\\' || src[n+1] != 'u' || !ok { + err = NewInvalidEscapeSequenceError(src[n-6 : n+6]) + } else if r = utf16.DecodeRune(rune(v1), rune(v2)); r == utf8.RuneError { + err = NewInvalidEscapeSequenceError(src[n-6 : n+6]) + } else { + n += 6 + } + } + + dst = utf8.AppendRune(dst, r) + default: + return dst, NewInvalidEscapeSequenceError(src[n : n+2]) + } + i = n + // Handle invalid UTF-8. + case r == utf8.RuneError: + dst = append(dst, src[i:n]...) + if !utf8.FullRuneInString(string(truncateMaxUTF8(src[n:]))) { + return dst, io.ErrUnexpectedEOF + } + // NOTE: An unescaped string may be longer than the escaped string + // because invalid UTF-8 bytes are being replaced. + dst = append(dst, "\uFFFD"...) + n += rn + i = n + err = ErrInvalidUTF8 + // Handle invalid control characters. + case r < ' ': + dst = append(dst, src[i:n]...) + return dst, NewInvalidCharacterError(src[n:], "in string (expecting non-control character)") + default: + panic("BUG: unhandled character " + QuoteRune(src[n:])) + } + } + dst = append(dst, src[i:n]...) + return dst, io.ErrUnexpectedEOF +} + +// hasEscapedUTF16Prefix reports whether b is possibly +// the truncated prefix of a \uFFFF escape sequence. +func hasEscapedUTF16Prefix[Bytes ~[]byte | ~string](b Bytes, lowerSurrogateHalf bool) bool { + for i := range len(b) { + switch c := b[i]; { + case i == 0 && c != '\\': + return false + case i == 1 && c != 'u': + return false + case i == 2 && lowerSurrogateHalf && c != 'd' && c != 'D': + return false // not within ['\uDC00':'\uDFFF'] + case i == 3 && lowerSurrogateHalf && !('c' <= c && c <= 'f') && !('C' <= c && c <= 'F'): + return false // not within ['\uDC00':'\uDFFF'] + case i >= 2 && i < 6 && !('0' <= c && c <= '9') && !('a' <= c && c <= 'f') && !('A' <= c && c <= 'F'): + return false + } + } + return true +} + +// UnquoteMayCopy returns the unescaped form of b. +// If there are no escaped characters, the output is simply a subslice of +// the input with the surrounding quotes removed. +// Otherwise, a new buffer is allocated for the output. +// It assumes the input is valid. +func UnquoteMayCopy(b []byte, isVerbatim bool) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + if isVerbatim { + return b[len(`"`) : len(b)-len(`"`)] + } + b, _ = AppendUnquote(nil, b) + return b +} + +// ConsumeSimpleNumber consumes the next JSON number per RFC 7159, section 6 +// but is limited to the grammar for a positive integer. +// It returns 0 if it is invalid or more complicated than a simple integer, +// in which case consumeNumber should be called. +func ConsumeSimpleNumber(b []byte) (n int) { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + if len(b) > 0 { + if b[0] == '0' { + n++ + } else if '1' <= b[0] && b[0] <= '9' { + n++ + for len(b) > n && ('0' <= b[n] && b[n] <= '9') { + n++ + } + } else { + return 0 + } + if uint(len(b)) <= uint(n) || (b[n] != '.' && b[n] != 'e' && b[n] != 'E') { + return n + } + } + return 0 +} + +type ConsumeNumberState uint + +const ( + consumeNumberInit ConsumeNumberState = iota + beforeIntegerDigits + withinIntegerDigits + beforeFractionalDigits + withinFractionalDigits + beforeExponentDigits + withinExponentDigits +) + +// ConsumeNumber consumes the next JSON number per RFC 7159, section 6. +// It reports the number of bytes consumed and whether an error was encountered. +// If the input appears truncated, it returns io.ErrUnexpectedEOF. +// +// Note that JSON numbers are not self-terminating. +// If the entire input is consumed, then the caller needs to consider whether +// there may be subsequent unread data that may still be part of this number. +func ConsumeNumber(b []byte) (n int, err error) { + n, _, err = ConsumeNumberResumable(b, 0, consumeNumberInit) + return n, err +} + +// ConsumeNumberResumable is identical to consumeNumber but supports resuming +// from a previous call that returned io.ErrUnexpectedEOF. +func ConsumeNumberResumable(b []byte, resumeOffset int, state ConsumeNumberState) (n int, _ ConsumeNumberState, err error) { + // Jump to the right state when resuming from a partial consumption. + n = resumeOffset + if state > consumeNumberInit { + switch state { + case withinIntegerDigits, withinFractionalDigits, withinExponentDigits: + // Consume leading digits. + for uint(len(b)) > uint(n) && ('0' <= b[n] && b[n] <= '9') { + n++ + } + if uint(len(b)) <= uint(n) { + return n, state, nil // still within the same state + } + state++ // switches "withinX" to "beforeY" where Y is the state after X + } + switch state { + case beforeIntegerDigits: + goto beforeInteger + case beforeFractionalDigits: + goto beforeFractional + case beforeExponentDigits: + goto beforeExponent + default: + return n, state, nil + } + } + + // Consume required integer component (with optional minus sign). +beforeInteger: + resumeOffset = n + if uint(len(b)) > 0 && b[0] == '-' { + n++ + } + switch { + case uint(len(b)) <= uint(n): + return resumeOffset, beforeIntegerDigits, io.ErrUnexpectedEOF + case b[n] == '0': + n++ + state = beforeFractionalDigits + case '1' <= b[n] && b[n] <= '9': + n++ + for uint(len(b)) > uint(n) && ('0' <= b[n] && b[n] <= '9') { + n++ + } + state = withinIntegerDigits + default: + return n, state, NewInvalidCharacterError(b[n:], "in number (expecting digit)") + } + + // Consume optional fractional component. +beforeFractional: + if uint(len(b)) > uint(n) && b[n] == '.' { + resumeOffset = n + n++ + switch { + case uint(len(b)) <= uint(n): + return resumeOffset, beforeFractionalDigits, io.ErrUnexpectedEOF + case '0' <= b[n] && b[n] <= '9': + n++ + default: + return n, state, NewInvalidCharacterError(b[n:], "in number (expecting digit)") + } + for uint(len(b)) > uint(n) && ('0' <= b[n] && b[n] <= '9') { + n++ + } + state = withinFractionalDigits + } + + // Consume optional exponent component. +beforeExponent: + if uint(len(b)) > uint(n) && (b[n] == 'e' || b[n] == 'E') { + resumeOffset = n + n++ + if uint(len(b)) > uint(n) && (b[n] == '-' || b[n] == '+') { + n++ + } + switch { + case uint(len(b)) <= uint(n): + return resumeOffset, beforeExponentDigits, io.ErrUnexpectedEOF + case '0' <= b[n] && b[n] <= '9': + n++ + default: + return n, state, NewInvalidCharacterError(b[n:], "in number (expecting digit)") + } + for uint(len(b)) > uint(n) && ('0' <= b[n] && b[n] <= '9') { + n++ + } + state = withinExponentDigits + } + + return n, state, nil +} + +// parseHexUint16 is similar to strconv.ParseUint, +// but operates directly on []byte and is optimized for base-16. +// See https://go.dev/issue/42429. +func parseHexUint16[Bytes ~[]byte | ~string](b Bytes) (v uint16, ok bool) { + if len(b) != 4 { + return 0, false + } + for i := range 4 { + c := b[i] + switch { + case '0' <= c && c <= '9': + c = c - '0' + case 'a' <= c && c <= 'f': + c = 10 + c - 'a' + case 'A' <= c && c <= 'F': + c = 10 + c - 'A' + default: + return 0, false + } + v = v*16 + uint16(c) + } + return v, true +} + +// ParseUint parses b as a decimal unsigned integer according to +// a strict subset of the JSON number grammar, returning the value if valid. +// It returns (0, false) if there is a syntax error and +// returns (math.MaxUint64, false) if there is an overflow. +func ParseUint(b []byte) (v uint64, ok bool) { + const unsafeWidth = 20 // len(fmt.Sprint(uint64(math.MaxUint64))) + var n int + for ; len(b) > n && ('0' <= b[n] && b[n] <= '9'); n++ { + v = 10*v + uint64(b[n]-'0') + } + switch { + case n == 0 || len(b) != n || (b[0] == '0' && string(b) != "0"): + return 0, false + case n >= unsafeWidth && (b[0] != '1' || v < 1e19 || n > unsafeWidth): + return math.MaxUint64, false + } + return v, true +} + +// ParseFloat parses a floating point number according to the Go float grammar. +// Note that the JSON number grammar is a strict subset. +// +// If the number overflows the finite representation of a float, +// then we return MaxFloat since any finite value will always be infinitely +// more accurate at representing another finite value than an infinite value. +func ParseFloat(b []byte, bits int) (v float64, ok bool) { + fv, err := strconv.ParseFloat(string(b), bits) + if math.IsInf(fv, 0) { + switch { + case bits == 32 && math.IsInf(fv, +1): + fv = +math.MaxFloat32 + case bits == 64 && math.IsInf(fv, +1): + fv = +math.MaxFloat64 + case bits == 32 && math.IsInf(fv, -1): + fv = -math.MaxFloat32 + case bits == 64 && math.IsInf(fv, -1): + fv = -math.MaxFloat64 + } + } + return fv, err == nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go new file mode 100644 index 00000000..35b238a2 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/encode.go @@ -0,0 +1,288 @@ +// Copyright 2023 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 jsonwire + +import ( + "math" + "slices" + "strconv" + "unicode/utf16" + "unicode/utf8" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" +) + +// escapeASCII reports whether the ASCII character needs to be escaped. +// It conservatively assumes EscapeForHTML. +var escapeASCII = [...]uint8{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // escape control characters + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // escape control characters + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // escape '"' and '&' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, // escape '<' and '>' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // escape '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +} + +// NeedEscape reports whether src needs escaping of any characters. +// It conservatively assumes EscapeForHTML and EscapeForJS. +// It reports true for inputs with invalid UTF-8. +func NeedEscape[Bytes ~[]byte | ~string](src Bytes) bool { + var i int + for uint(len(src)) > uint(i) { + if c := src[i]; c < utf8.RuneSelf { + if escapeASCII[c] > 0 { + return true + } + i++ + } else { + r, rn := utf8.DecodeRuneInString(string(truncateMaxUTF8(src[i:]))) + if r == utf8.RuneError || r == '\u2028' || r == '\u2029' { + return true + } + i += rn + } + } + return false +} + +// AppendQuote appends src to dst as a JSON string per RFC 7159, section 7. +// +// It takes in flags and respects the following: +// - EscapeForHTML escapes '<', '>', and '&'. +// - EscapeForJS escapes '\u2028' and '\u2029'. +// - AllowInvalidUTF8 avoids reporting an error for invalid UTF-8. +// +// Regardless of whether AllowInvalidUTF8 is specified, +// invalid bytes are replaced with the Unicode replacement character ('\ufffd'). +// If no escape flags are set, then the shortest representable form is used, +// which is also the canonical form for strings (RFC 8785, section 3.2.2.2). +func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes, flags *jsonflags.Flags) ([]byte, error) { + var i, n int + var hasInvalidUTF8 bool + dst = slices.Grow(dst, len(`"`)+len(src)+len(`"`)) + dst = append(dst, '"') + for uint(len(src)) > uint(n) { + if c := src[n]; c < utf8.RuneSelf { + // Handle single-byte ASCII. + n++ + if escapeASCII[c] == 0 { + continue // no escaping possibly needed + } + // Handle escaping of single-byte ASCII. + if !(c == '<' || c == '>' || c == '&') || flags.Get(jsonflags.EscapeForHTML) { + dst = append(dst, src[i:n-1]...) + dst = appendEscapedASCII(dst, c) + i = n + } + } else { + // Handle multi-byte Unicode. + r, rn := utf8.DecodeRuneInString(string(truncateMaxUTF8(src[n:]))) + n += rn + if r != utf8.RuneError && r != '\u2028' && r != '\u2029' { + continue // no escaping possibly needed + } + // Handle escaping of multi-byte Unicode. + switch { + case isInvalidUTF8(r, rn): + hasInvalidUTF8 = true + dst = append(dst, src[i:n-rn]...) + dst = append(dst, "\ufffd"...) + i = n + case (r == '\u2028' || r == '\u2029') && flags.Get(jsonflags.EscapeForJS): + dst = append(dst, src[i:n-rn]...) + dst = appendEscapedUnicode(dst, r) + i = n + } + } + } + dst = append(dst, src[i:n]...) + dst = append(dst, '"') + if hasInvalidUTF8 && !flags.Get(jsonflags.AllowInvalidUTF8) { + return dst, ErrInvalidUTF8 + } + return dst, nil +} + +func appendEscapedASCII(dst []byte, c byte) []byte { + switch c { + case '"', '\\': + dst = append(dst, '\\', c) + case '\b': + dst = append(dst, "\\b"...) + case '\f': + dst = append(dst, "\\f"...) + case '\n': + dst = append(dst, "\\n"...) + case '\r': + dst = append(dst, "\\r"...) + case '\t': + dst = append(dst, "\\t"...) + default: + dst = appendEscapedUTF16(dst, uint16(c)) + } + return dst +} + +func appendEscapedUnicode(dst []byte, r rune) []byte { + if r1, r2 := utf16.EncodeRune(r); r1 != '\ufffd' && r2 != '\ufffd' { + dst = appendEscapedUTF16(dst, uint16(r1)) + dst = appendEscapedUTF16(dst, uint16(r2)) + } else { + dst = appendEscapedUTF16(dst, uint16(r)) + } + return dst +} + +func appendEscapedUTF16(dst []byte, x uint16) []byte { + const hex = "0123456789abcdef" + return append(dst, '\\', 'u', hex[(x>>12)&0xf], hex[(x>>8)&0xf], hex[(x>>4)&0xf], hex[(x>>0)&0xf]) +} + +// ReformatString consumes a JSON string from src and appends it to dst, +// reformatting it if necessary according to the specified flags. +// It returns the appended output and the number of consumed input bytes. +func ReformatString(dst, src []byte, flags *jsonflags.Flags) ([]byte, int, error) { + // TODO: Should this update ValueFlags as input? + var valFlags ValueFlags + n, err := ConsumeString(&valFlags, src, !flags.Get(jsonflags.AllowInvalidUTF8)) + if err != nil { + return dst, n, err + } + + // If the output requires no special escapes, and the input + // is already in canonical form or should be preserved verbatim, + // then directly copy the input to the output. + if !flags.Get(jsonflags.AnyEscape) && + (valFlags.IsCanonical() || flags.Get(jsonflags.PreserveRawStrings)) { + dst = append(dst, src[:n]...) // copy the string verbatim + return dst, n, nil + } + + // Under [jsonflags.PreserveRawStrings], any pre-escaped sequences + // remain escaped, however we still need to respect the + // [jsonflags.EscapeForHTML] and [jsonflags.EscapeForJS] options. + if flags.Get(jsonflags.PreserveRawStrings) { + var i, lastAppendIndex int + for i < n { + if c := src[i]; c < utf8.RuneSelf { + if (c == '<' || c == '>' || c == '&') && flags.Get(jsonflags.EscapeForHTML) { + dst = append(dst, src[lastAppendIndex:i]...) + dst = appendEscapedASCII(dst, c) + lastAppendIndex = i + 1 + } + i++ + } else { + r, rn := utf8.DecodeRune(truncateMaxUTF8(src[i:])) + if (r == '\u2028' || r == '\u2029') && flags.Get(jsonflags.EscapeForJS) { + dst = append(dst, src[lastAppendIndex:i]...) + dst = appendEscapedUnicode(dst, r) + lastAppendIndex = i + rn + } + i += rn + } + } + return append(dst, src[lastAppendIndex:n]...), n, nil + } + + // The input contains characters that might need escaping, + // unnecessary escape sequences, or invalid UTF-8. + // Perform a round-trip unquote and quote to properly reformat + // these sequences according the current flags. + b, _ := AppendUnquote(nil, src[:n]) + dst, _ = AppendQuote(dst, b, flags) + return dst, n, nil +} + +// AppendFloat appends src to dst as a JSON number per RFC 7159, section 6. +// It formats numbers similar to the ES6 number-to-string conversion. +// See https://go.dev/issue/14135. +// +// The output is identical to ECMA-262, 6th edition, section 7.1.12.1 and with +// RFC 8785, section 3.2.2.3 for 64-bit floating-point numbers except for -0, +// which is formatted as -0 instead of just 0. +// +// For 32-bit floating-point numbers, +// the output is a 32-bit equivalent of the algorithm. +// Note that ECMA-262 specifies no algorithm for 32-bit numbers. +func AppendFloat(dst []byte, src float64, bits int) []byte { + if bits == 32 { + src = float64(float32(src)) + } + + abs := math.Abs(src) + fmt := byte('f') + if abs != 0 { + if bits == 64 && (float64(abs) < 1e-6 || float64(abs) >= 1e21) || + bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { + fmt = 'e' + } + } + dst = strconv.AppendFloat(dst, src, fmt, -1, bits) + if fmt == 'e' { + // Clean up e-09 to e-9. + n := len(dst) + if n >= 4 && dst[n-4] == 'e' && dst[n-3] == '-' && dst[n-2] == '0' { + dst[n-2] = dst[n-1] + dst = dst[:n-1] + } + } + return dst +} + +// ReformatNumber consumes a JSON string from src and appends it to dst, +// canonicalizing it if specified. +// It returns the appended output and the number of consumed input bytes. +func ReformatNumber(dst, src []byte, flags *jsonflags.Flags) ([]byte, int, error) { + n, err := ConsumeNumber(src) + if err != nil { + return dst, n, err + } + if !flags.Get(jsonflags.CanonicalizeNumbers) { + dst = append(dst, src[:n]...) // copy the number verbatim + return dst, n, nil + } + + // Identify the kind of number. + var isFloat bool + for _, c := range src[:n] { + if c == '.' || c == 'e' || c == 'E' { + isFloat = true // has fraction or exponent + break + } + } + + // Check if need to canonicalize this kind of number. + switch { + case string(src[:n]) == "-0": + break // canonicalize -0 as 0 regardless of kind + case isFloat: + if !flags.Get(jsonflags.CanonicalizeRawFloats) { + dst = append(dst, src[:n]...) // copy the number verbatim + return dst, n, nil + } + default: + // As an optimization, we can copy integer numbers below 2⁵³ verbatim + // since the canonical form is always identical. + const maxExactIntegerDigits = 16 // len(strconv.AppendUint(nil, 1<<53, 10)) + if !flags.Get(jsonflags.CanonicalizeRawInts) || n < maxExactIntegerDigits { + dst = append(dst, src[:n]...) // copy the number verbatim + return dst, n, nil + } + } + + // Parse and reformat the number (which uses a canonical format). + fv, _ := strconv.ParseFloat(string(src[:n]), 64) + switch { + case fv == 0: + fv = 0 // normalize negative zero as just zero + case math.IsInf(fv, +1): + fv = +math.MaxFloat64 + case math.IsInf(fv, -1): + fv = -math.MaxFloat64 + } + return AppendFloat(dst, fv, 64), n, nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go new file mode 100644 index 00000000..1831a66b --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire/wire.go @@ -0,0 +1,215 @@ +// Copyright 2023 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 jsonwire implements stateless functionality for handling JSON text. +package jsonwire + +import ( + "cmp" + "errors" + "strconv" + "strings" + "unicode" + "unicode/utf16" + "unicode/utf8" +) + +// TrimSuffixWhitespace trims JSON from the end of b. +func TrimSuffixWhitespace(b []byte) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + n := len(b) - 1 + for n >= 0 && (b[n] == ' ' || b[n] == '\t' || b[n] == '\r' || b[n] == '\n') { + n-- + } + return b[:n+1] +} + +// TrimSuffixString trims a valid JSON string at the end of b. +// The behavior is undefined if there is not a valid JSON string present. +func TrimSuffixString(b []byte) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + if len(b) > 0 && b[len(b)-1] == '"' { + b = b[:len(b)-1] + } + for len(b) >= 2 && !(b[len(b)-1] == '"' && b[len(b)-2] != '\\') { + b = b[:len(b)-1] // trim all characters except an unescaped quote + } + if len(b) > 0 && b[len(b)-1] == '"' { + b = b[:len(b)-1] + } + return b +} + +// HasSuffixByte reports whether b ends with c. +func HasSuffixByte(b []byte, c byte) bool { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + return len(b) > 0 && b[len(b)-1] == c +} + +// TrimSuffixByte removes c from the end of b if it is present. +func TrimSuffixByte(b []byte, c byte) []byte { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + if len(b) > 0 && b[len(b)-1] == c { + return b[:len(b)-1] + } + return b +} + +// QuoteRune quotes the first rune in the input. +func QuoteRune[Bytes ~[]byte | ~string](b Bytes) string { + r, n := utf8.DecodeRuneInString(string(truncateMaxUTF8(b))) + if r == utf8.RuneError && n == 1 { + return `'\x` + strconv.FormatUint(uint64(b[0]), 16) + `'` + } + return strconv.QuoteRune(r) +} + +// CompareUTF16 lexicographically compares x to y according +// to the UTF-16 codepoints of the UTF-8 encoded input strings. +// This implements the ordering specified in RFC 8785, section 3.2.3. +func CompareUTF16[Bytes ~[]byte | ~string](x, y Bytes) int { + // NOTE: This is an optimized, mostly allocation-free implementation + // of CompareUTF16Simple in wire_test.go. FuzzCompareUTF16 verifies that the + // two implementations agree on the result of comparing any two strings. + isUTF16Self := func(r rune) bool { + return ('\u0000' <= r && r <= '\uD7FF') || ('\uE000' <= r && r <= '\uFFFF') + } + + for { + if len(x) == 0 || len(y) == 0 { + return cmp.Compare(len(x), len(y)) + } + + // ASCII fast-path. + if x[0] < utf8.RuneSelf || y[0] < utf8.RuneSelf { + if x[0] != y[0] { + return cmp.Compare(x[0], y[0]) + } + x, y = x[1:], y[1:] + continue + } + + // Decode next pair of runes as UTF-8. + rx, nx := utf8.DecodeRuneInString(string(truncateMaxUTF8(x))) + ry, ny := utf8.DecodeRuneInString(string(truncateMaxUTF8(y))) + + selfx := isUTF16Self(rx) + selfy := isUTF16Self(ry) + switch { + // The x rune is a single UTF-16 codepoint, while + // the y rune is a surrogate pair of UTF-16 codepoints. + case selfx && !selfy: + ry, _ = utf16.EncodeRune(ry) + // The y rune is a single UTF-16 codepoint, while + // the x rune is a surrogate pair of UTF-16 codepoints. + case selfy && !selfx: + rx, _ = utf16.EncodeRune(rx) + } + if rx != ry { + return cmp.Compare(rx, ry) + } + + // Check for invalid UTF-8, in which case, + // we just perform a byte-for-byte comparison. + if isInvalidUTF8(rx, nx) || isInvalidUTF8(ry, ny) { + if x[0] != y[0] { + return cmp.Compare(x[0], y[0]) + } + } + x, y = x[nx:], y[ny:] + } +} + +// truncateMaxUTF8 truncates b such it contains at least one rune. +// +// The utf8 package currently lacks generic variants, which complicates +// generic functions that operates on either []byte or string. +// As a hack, we always call the utf8 function operating on strings, +// but always truncate the input such that the result is identical. +// +// Example usage: +// +// utf8.DecodeRuneInString(string(truncateMaxUTF8(b))) +// +// Converting a []byte to a string is stack allocated since +// truncateMaxUTF8 guarantees that the []byte is short. +func truncateMaxUTF8[Bytes ~[]byte | ~string](b Bytes) Bytes { + // TODO(https://go.dev/issue/56948): Remove this function and + // instead directly call generic utf8 functions wherever used. + if len(b) > utf8.UTFMax { + return b[:utf8.UTFMax] + } + return b +} + +// TODO(https://go.dev/issue/70547): Use utf8.ErrInvalid instead. +var ErrInvalidUTF8 = errors.New("invalid UTF-8") + +func NewInvalidCharacterError[Bytes ~[]byte | ~string](prefix Bytes, where string) error { + what := QuoteRune(prefix) + return errors.New("invalid character " + what + " " + where) +} + +func NewInvalidEscapeSequenceError[Bytes ~[]byte | ~string](what Bytes) error { + label := "escape sequence" + if len(what) > 6 { + label = "surrogate pair" + } + needEscape := strings.IndexFunc(string(what), func(r rune) bool { + return r == '`' || r == utf8.RuneError || unicode.IsSpace(r) || !unicode.IsPrint(r) + }) >= 0 + if needEscape { + return errors.New("invalid " + label + " " + strconv.Quote(string(what)) + " in string") + } else { + return errors.New("invalid " + label + " `" + string(what) + "` in string") + } +} + +// TruncatePointer optionally truncates the JSON pointer, +// enforcing that the length roughly does not exceed n. +func TruncatePointer(s string, n int) string { + if len(s) <= n { + return s + } + i := n / 2 + j := len(s) - n/2 + + // Avoid truncating a name if there are multiple names present. + if k := strings.LastIndexByte(s[:i], '/'); k > 0 { + i = k + } + if k := strings.IndexByte(s[j:], '/'); k >= 0 { + j += k + len("/") + } + + // Avoid truncation in the middle of a UTF-8 rune. + for i > 0 && isInvalidUTF8(utf8.DecodeLastRuneInString(s[:i])) { + i-- + } + for j < len(s) && isInvalidUTF8(utf8.DecodeRuneInString(s[j:])) { + j++ + } + + // Determine the right middle fragment to use. + var middle string + switch strings.Count(s[i:j], "/") { + case 0: + middle = "…" + case 1: + middle = "…/…" + default: + middle = "…/…/…" + } + if strings.HasPrefix(s[i:j], "/") && middle != "…" { + middle = strings.TrimPrefix(middle, "…") + } + if strings.HasSuffix(s[i:j], "/") && middle != "…" { + middle = strings.TrimSuffix(middle, "…") + } + return s[:i] + middle + s[j:] +} + +func isInvalidUTF8(r rune, rn int) bool { + return r == utf8.RuneError && rn == 1 +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go new file mode 100644 index 00000000..96fd5c27 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/decode.go @@ -0,0 +1,1177 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsontext + +import ( + "bytes" + "errors" + "io" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" +) + +// NOTE: The logic for decoding is complicated by the fact that reading from +// an io.Reader into a temporary buffer means that the buffer may contain a +// truncated portion of some valid input, requiring the need to fetch more data. +// +// This file is structured in the following way: +// +// - consumeXXX functions parse an exact JSON token from a []byte. +// If the buffer appears truncated, then it returns io.ErrUnexpectedEOF. +// The consumeSimpleXXX functions are so named because they only handle +// a subset of the grammar for the JSON token being parsed. +// They do not handle the full grammar to keep these functions inlinable. +// +// - Decoder.consumeXXX methods parse the next JSON token from Decoder.buf, +// automatically fetching more input if necessary. These methods take +// a position relative to the start of Decoder.buf as an argument and +// return the end of the consumed JSON token as a position, +// also relative to the start of Decoder.buf. +// +// - In the event of an I/O errors or state machine violations, +// the implementation avoids mutating the state of Decoder +// (aside from the book-keeping needed to implement Decoder.fetch). +// For this reason, only Decoder.ReadToken and Decoder.ReadValue are +// responsible for updated Decoder.prevStart and Decoder.prevEnd. +// +// - For performance, much of the implementation uses the pattern of calling +// the inlinable consumeXXX functions first, and if more work is necessary, +// then it calls the slower Decoder.consumeXXX methods. +// TODO: Revisit this pattern if the Go compiler provides finer control +// over exactly which calls are inlined or not. + +// Decoder is a streaming decoder for raw JSON tokens and values. +// It is used to read a stream of top-level JSON values, +// each separated by optional whitespace characters. +// +// [Decoder.ReadToken] and [Decoder.ReadValue] calls may be interleaved. +// For example, the following JSON value: +// +// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} +// +// can be parsed with the following calls (ignoring errors for brevity): +// +// d.ReadToken() // { +// d.ReadToken() // "name" +// d.ReadToken() // "value" +// d.ReadValue() // "array" +// d.ReadToken() // [ +// d.ReadToken() // null +// d.ReadToken() // false +// d.ReadValue() // true +// d.ReadToken() // 3.14159 +// d.ReadToken() // ] +// d.ReadValue() // "object" +// d.ReadValue() // {"k":"v"} +// d.ReadToken() // } +// +// The above is one of many possible sequence of calls and +// may not represent the most sensible method to call for any given token/value. +// For example, it is probably more common to call [Decoder.ReadToken] to obtain a +// string token for object names. +type Decoder struct { + s decoderState +} + +// decoderState is the low-level state of Decoder. +// It has exported fields and method for use by the "json" package. +type decoderState struct { + state + decodeBuffer + jsonopts.Struct + + StringCache *[256]string // only used when unmarshaling; identical to json.stringCache +} + +// decodeBuffer is a buffer split into 4 segments: +// +// - buf[0:prevEnd] // already read portion of the buffer +// - buf[prevStart:prevEnd] // previously read value +// - buf[prevEnd:len(buf)] // unread portion of the buffer +// - buf[len(buf):cap(buf)] // unused portion of the buffer +// +// Invariants: +// +// 0 ≤ prevStart ≤ prevEnd ≤ len(buf) ≤ cap(buf) +type decodeBuffer struct { + peekPos int // non-zero if valid offset into buf for start of next token + peekErr error // implies peekPos is -1 + + buf []byte // may alias rd if it is a bytes.Buffer + prevStart int + prevEnd int + + // baseOffset is added to prevStart and prevEnd to obtain + // the absolute offset relative to the start of io.Reader stream. + baseOffset int64 + + rd io.Reader +} + +// NewDecoder constructs a new streaming decoder reading from r. +// +// If r is a [bytes.Buffer], then the decoder parses directly from the buffer +// without first copying the contents to an intermediate buffer. +// Additional writes to the buffer must not occur while the decoder is in use. +func NewDecoder(r io.Reader, opts ...Options) *Decoder { + d := new(Decoder) + d.Reset(r, opts...) + return d +} + +// Reset resets a decoder such that it is reading afresh from r and +// configured with the provided options. Reset must not be called on an +// a Decoder passed to the [encoding/json/v2.UnmarshalerFrom.UnmarshalJSONFrom] method +// or the [encoding/json/v2.UnmarshalFromFunc] function. +func (d *Decoder) Reset(r io.Reader, opts ...Options) { + switch { + case d == nil: + panic("jsontext: invalid nil Decoder") + case r == nil: + panic("jsontext: invalid nil io.Reader") + case d.s.Flags.Get(jsonflags.WithinArshalCall): + panic("jsontext: cannot reset Decoder passed to json.UnmarshalerFrom") + } + // Reuse the buffer if it does not alias a previous [bytes.Buffer]. + b := d.s.buf[:0] + if _, ok := d.s.rd.(*bytes.Buffer); ok { + b = nil + } + d.s.reset(b, r, opts...) +} + +func (d *decoderState) reset(b []byte, r io.Reader, opts ...Options) { + d.state.reset() + d.decodeBuffer = decodeBuffer{buf: b, rd: r} + opts2 := jsonopts.Struct{} // avoid mutating d.Struct in case it is part of opts + opts2.Join(opts...) + d.Struct = opts2 +} + +// Options returns the options used to construct the encoder and +// may additionally contain semantic options passed to a +// [encoding/json/v2.UnmarshalDecode] call. +// +// If operating within +// a [encoding/json/v2.UnmarshalerFrom.UnmarshalJSONFrom] method call or +// a [encoding/json/v2.UnmarshalFromFunc] function call, +// then the returned options are only valid within the call. +func (d *Decoder) Options() Options { + return &d.s.Struct +} + +var errBufferWriteAfterNext = errors.New("invalid bytes.Buffer.Write call after calling bytes.Buffer.Next") + +// fetch reads at least 1 byte from the underlying io.Reader. +// It returns io.ErrUnexpectedEOF if zero bytes were read and io.EOF was seen. +func (d *decoderState) fetch() error { + if d.rd == nil { + return io.ErrUnexpectedEOF + } + + // Inform objectNameStack that we are about to fetch new buffer content. + d.Names.copyQuotedBuffer(d.buf) + + // Specialize bytes.Buffer for better performance. + if bb, ok := d.rd.(*bytes.Buffer); ok { + switch { + case bb.Len() == 0: + return io.ErrUnexpectedEOF + case len(d.buf) == 0: + d.buf = bb.Next(bb.Len()) // "read" all data in the buffer + return nil + default: + // This only occurs if a partially filled bytes.Buffer was provided + // and more data is written to it while Decoder is reading from it. + // This practice will lead to data corruption since future writes + // may overwrite the contents of the current buffer. + // + // The user is trying to use a bytes.Buffer as a pipe, + // but a bytes.Buffer is poor implementation of a pipe, + // the purpose-built io.Pipe should be used instead. + return &ioError{action: "read", err: errBufferWriteAfterNext} + } + } + + // Allocate initial buffer if empty. + if cap(d.buf) == 0 { + d.buf = make([]byte, 0, 64) + } + + // Check whether to grow the buffer. + const maxBufferSize = 4 << 10 + const growthSizeFactor = 2 // higher value is faster + const growthRateFactor = 2 // higher value is slower + // By default, grow if below the maximum buffer size. + grow := cap(d.buf) <= maxBufferSize/growthSizeFactor + // Growing can be expensive, so only grow + // if a sufficient number of bytes have been processed. + grow = grow && int64(cap(d.buf)) < d.previousOffsetEnd()/growthRateFactor + // If prevStart==0, then fetch was called in order to fetch more data + // to finish consuming a large JSON value contiguously. + // Grow if less than 25% of the remaining capacity is available. + // Note that this may cause the input buffer to exceed maxBufferSize. + grow = grow || (d.prevStart == 0 && len(d.buf) >= 3*cap(d.buf)/4) + + if grow { + // Allocate a new buffer and copy the contents of the old buffer over. + // TODO: Provide a hard limit on the maximum internal buffer size? + buf := make([]byte, 0, cap(d.buf)*growthSizeFactor) + d.buf = append(buf, d.buf[d.prevStart:]...) + } else { + // Move unread portion of the data to the front. + n := copy(d.buf[:cap(d.buf)], d.buf[d.prevStart:]) + d.buf = d.buf[:n] + } + d.baseOffset += int64(d.prevStart) + d.prevEnd -= d.prevStart + d.prevStart = 0 + + // Read more data into the internal buffer. + for { + n, err := d.rd.Read(d.buf[len(d.buf):cap(d.buf)]) + switch { + case n > 0: + d.buf = d.buf[:len(d.buf)+n] + return nil // ignore errors if any bytes are read + case err == io.EOF: + return io.ErrUnexpectedEOF + case err != nil: + return &ioError{action: "read", err: err} + default: + continue // Read returned (0, nil) + } + } +} + +const invalidateBufferByte = '#' // invalid starting character for JSON grammar + +// invalidatePreviousRead invalidates buffers returned by Peek and Read calls +// so that the first byte is an invalid character. +// This Hyrum-proofs the API against faulty application code that assumes +// values returned by ReadValue remain valid past subsequent Read calls. +func (d *decodeBuffer) invalidatePreviousRead() { + // Avoid mutating the buffer if d.rd is nil which implies that d.buf + // is provided by the user code and may not expect mutations. + isBytesBuffer := func(r io.Reader) bool { + _, ok := r.(*bytes.Buffer) + return ok + } + if d.rd != nil && !isBytesBuffer(d.rd) && d.prevStart < d.prevEnd && uint(d.prevStart) < uint(len(d.buf)) { + d.buf[d.prevStart] = invalidateBufferByte + d.prevStart = d.prevEnd + } +} + +// needMore reports whether there are no more unread bytes. +func (d *decodeBuffer) needMore(pos int) bool { + // NOTE: The arguments and logic are kept simple to keep this inlinable. + return pos == len(d.buf) +} + +func (d *decodeBuffer) offsetAt(pos int) int64 { return d.baseOffset + int64(pos) } +func (d *decodeBuffer) previousOffsetStart() int64 { return d.baseOffset + int64(d.prevStart) } +func (d *decodeBuffer) previousOffsetEnd() int64 { return d.baseOffset + int64(d.prevEnd) } +func (d *decodeBuffer) previousBuffer() []byte { return d.buf[d.prevStart:d.prevEnd] } +func (d *decodeBuffer) unreadBuffer() []byte { return d.buf[d.prevEnd:len(d.buf)] } + +// PreviousTokenOrValue returns the previously read token or value +// unless it has been invalidated by a call to PeekKind. +// If a token is just a delimiter, then this returns a 1-byte buffer. +// This method is used for error reporting at the semantic layer. +func (d *decodeBuffer) PreviousTokenOrValue() []byte { + b := d.previousBuffer() + // If peek was called, then the previous token or buffer is invalidated. + if d.peekPos > 0 || len(b) > 0 && b[0] == invalidateBufferByte { + return nil + } + // ReadToken does not preserve the buffer for null, bools, or delimiters. + // Manually re-construct that buffer. + if len(b) == 0 { + b = d.buf[:d.prevEnd] // entirety of the previous buffer + for _, tok := range []string{"null", "false", "true", "{", "}", "[", "]"} { + if len(b) >= len(tok) && string(b[len(b)-len(tok):]) == tok { + return b[len(b)-len(tok):] + } + } + } + return b +} + +// PeekKind retrieves the next token kind, but does not advance the read offset. +// +// It returns 0 if an error occurs. Any such error is cached until +// the next read call and it is the caller's responsibility to eventually +// follow up a PeekKind call with a read call. +func (d *Decoder) PeekKind() Kind { + return d.s.PeekKind() +} +func (d *decoderState) PeekKind() Kind { + // Check whether we have a cached peek result. + if d.peekPos > 0 { + return Kind(d.buf[d.peekPos]).normalize() + } + + var err error + d.invalidatePreviousRead() + pos := d.prevEnd + + // Consume leading whitespace. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 { + err = io.EOF // EOF possibly if no Tokens present after top-level value + } + d.peekPos, d.peekErr = -1, wrapSyntacticError(d, err, pos, 0) + return invalidKind + } + } + + // Consume colon or comma. + var delim byte + if c := d.buf[pos]; c == ':' || c == ',' { + delim = c + pos += 1 + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + err = wrapSyntacticError(d, err, pos, 0) + d.peekPos, d.peekErr = -1, d.checkDelimBeforeIOError(delim, err) + return invalidKind + } + } + } + next := Kind(d.buf[pos]).normalize() + if d.Tokens.needDelim(next) != delim { + d.peekPos, d.peekErr = -1, d.checkDelim(delim, next) + return invalidKind + } + + // This may set peekPos to zero, which is indistinguishable from + // the uninitialized state. While a small hit to performance, it is correct + // since ReadValue and ReadToken will disregard the cached result and + // recompute the next kind. + d.peekPos, d.peekErr = pos, nil + return next +} + +// checkDelimBeforeIOError checks whether the delim is even valid +// before returning an IO error, which occurs after the delim. +func (d *decoderState) checkDelimBeforeIOError(delim byte, err error) error { + // Since an IO error occurred, we do not know what the next kind is. + // However, knowing the next kind is necessary to validate + // whether the current delim is at least potentially valid. + // Since a JSON string is always valid as the next token, + // conservatively assume that is the next kind for validation. + const next = Kind('"') + if d.Tokens.needDelim(next) != delim { + err = d.checkDelim(delim, next) + } + return err +} + +// CountNextDelimWhitespace counts the number of upcoming bytes of +// delimiter or whitespace characters. +// This method is used for error reporting at the semantic layer. +func (d *decoderState) CountNextDelimWhitespace() int { + d.PeekKind() // populate unreadBuffer + return len(d.unreadBuffer()) - len(bytes.TrimLeft(d.unreadBuffer(), ",: \n\r\t")) +} + +// checkDelim checks whether delim is valid for the given next kind. +func (d *decoderState) checkDelim(delim byte, next Kind) error { + where := "at start of value" + switch d.Tokens.needDelim(next) { + case delim: + return nil + case ':': + where = "after object name (expecting ':')" + case ',': + if d.Tokens.Last.isObject() { + where = "after object value (expecting ',' or '}')" + } else { + where = "after array element (expecting ',' or ']')" + } + } + pos := d.prevEnd // restore position to right after leading whitespace + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + err := jsonwire.NewInvalidCharacterError(d.buf[pos:], where) + return wrapSyntacticError(d, err, pos, 0) +} + +// SkipValue is semantically equivalent to calling [Decoder.ReadValue] and discarding +// the result except that memory is not wasted trying to hold the entire result. +func (d *Decoder) SkipValue() error { + return d.s.SkipValue() +} +func (d *decoderState) SkipValue() error { + switch d.PeekKind() { + case '{', '[': + // For JSON objects and arrays, keep skipping all tokens + // until the depth matches the starting depth. + depth := d.Tokens.Depth() + for { + if _, err := d.ReadToken(); err != nil { + return err + } + if depth >= d.Tokens.Depth() { + return nil + } + } + default: + // Trying to skip a value when the next token is a '}' or ']' + // will result in an error being returned here. + var flags jsonwire.ValueFlags + if _, err := d.ReadValue(&flags); err != nil { + return err + } + return nil + } +} + +// SkipValueRemainder skips the remainder of a value +// after reading a '{' or '[' token. +func (d *decoderState) SkipValueRemainder() error { + if d.Tokens.Depth()-1 > 0 && d.Tokens.Last.Length() == 0 { + for n := d.Tokens.Depth(); d.Tokens.Depth() >= n; { + if _, err := d.ReadToken(); err != nil { + return err + } + } + } + return nil +} + +// SkipUntil skips all tokens until the state machine +// is at or past the specified depth and length. +func (d *decoderState) SkipUntil(depth int, length int64) error { + for d.Tokens.Depth() > depth || (d.Tokens.Depth() == depth && d.Tokens.Last.Length() < length) { + if _, err := d.ReadToken(); err != nil { + return err + } + } + return nil +} + +// ReadToken reads the next [Token], advancing the read offset. +// The returned token is only valid until the next Peek, Read, or Skip call. +// It returns [io.EOF] if there are no more tokens. +func (d *Decoder) ReadToken() (Token, error) { + return d.s.ReadToken() +} +func (d *decoderState) ReadToken() (Token, error) { + // Determine the next kind. + var err error + var next Kind + pos := d.peekPos + if pos != 0 { + // Use cached peek result. + if d.peekErr != nil { + err := d.peekErr + d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error + return Token{}, err + } + next = Kind(d.buf[pos]).normalize() + d.peekPos = 0 // reset cache + } else { + d.invalidatePreviousRead() + pos = d.prevEnd + + // Consume leading whitespace. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 { + err = io.EOF // EOF possibly if no Tokens present after top-level value + } + return Token{}, wrapSyntacticError(d, err, pos, 0) + } + } + + // Consume colon or comma. + var delim byte + if c := d.buf[pos]; c == ':' || c == ',' { + delim = c + pos += 1 + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + err = wrapSyntacticError(d, err, pos, 0) + return Token{}, d.checkDelimBeforeIOError(delim, err) + } + } + } + next = Kind(d.buf[pos]).normalize() + if d.Tokens.needDelim(next) != delim { + return Token{}, d.checkDelim(delim, next) + } + } + + // Handle the next token. + var n int + switch next { + case 'n': + if jsonwire.ConsumeNull(d.buf[pos:]) == 0 { + pos, err = d.consumeLiteral(pos, "null") + if err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + } else { + pos += len("null") + } + if err = d.Tokens.appendLiteral(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos-len("null"), +1) // report position at start of literal + } + d.prevStart, d.prevEnd = pos, pos + return Null, nil + + case 'f': + if jsonwire.ConsumeFalse(d.buf[pos:]) == 0 { + pos, err = d.consumeLiteral(pos, "false") + if err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + } else { + pos += len("false") + } + if err = d.Tokens.appendLiteral(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos-len("false"), +1) // report position at start of literal + } + d.prevStart, d.prevEnd = pos, pos + return False, nil + + case 't': + if jsonwire.ConsumeTrue(d.buf[pos:]) == 0 { + pos, err = d.consumeLiteral(pos, "true") + if err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + } else { + pos += len("true") + } + if err = d.Tokens.appendLiteral(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos-len("true"), +1) // report position at start of literal + } + d.prevStart, d.prevEnd = pos, pos + return True, nil + + case '"': + var flags jsonwire.ValueFlags // TODO: Preserve this in Token? + if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 { + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeString(&flags, pos) + newAbsPos := d.baseOffset + int64(pos) + n = int(newAbsPos - oldAbsPos) + if err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + } else { + pos += n + } + if d.Tokens.Last.NeedObjectName() { + if !d.Flags.Get(jsonflags.AllowDuplicateNames) { + if !d.Tokens.Last.isValidNamespace() { + return Token{}, wrapSyntacticError(d, errInvalidNamespace, pos-n, +1) + } + if d.Tokens.Last.isActiveNamespace() && !d.Namespaces.Last().insertQuoted(d.buf[pos-n:pos], flags.IsVerbatim()) { + err = wrapWithObjectName(ErrDuplicateName, d.buf[pos-n:pos]) + return Token{}, wrapSyntacticError(d, err, pos-n, +1) // report position at start of string + } + } + d.Names.ReplaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds + } + if err = d.Tokens.appendString(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos-n, +1) // report position at start of string + } + d.prevStart, d.prevEnd = pos-n, pos + return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil + + case '0': + // NOTE: Since JSON numbers are not self-terminating, + // we need to make sure that the next byte is not part of a number. + if n = jsonwire.ConsumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeNumber(pos) + newAbsPos := d.baseOffset + int64(pos) + n = int(newAbsPos - oldAbsPos) + if err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + } else { + pos += n + } + if err = d.Tokens.appendNumber(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos-n, +1) // report position at start of number + } + d.prevStart, d.prevEnd = pos-n, pos + return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil + + case '{': + if err = d.Tokens.pushObject(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + d.Names.push() + if !d.Flags.Get(jsonflags.AllowDuplicateNames) { + d.Namespaces.push() + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return BeginObject, nil + + case '}': + if err = d.Tokens.popObject(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + d.Names.pop() + if !d.Flags.Get(jsonflags.AllowDuplicateNames) { + d.Namespaces.pop() + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return EndObject, nil + + case '[': + if err = d.Tokens.pushArray(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return BeginArray, nil + + case ']': + if err = d.Tokens.popArray(); err != nil { + return Token{}, wrapSyntacticError(d, err, pos, +1) + } + pos += 1 + d.prevStart, d.prevEnd = pos, pos + return EndArray, nil + + default: + err = jsonwire.NewInvalidCharacterError(d.buf[pos:], "at start of value") + return Token{}, wrapSyntacticError(d, err, pos, +1) + } +} + +// ReadValue returns the next raw JSON value, advancing the read offset. +// The value is stripped of any leading or trailing whitespace and +// contains the exact bytes of the input, which may contain invalid UTF-8 +// if [AllowInvalidUTF8] is specified. +// +// The returned value is only valid until the next Peek, Read, or Skip call and +// may not be mutated while the Decoder remains in use. +// If the decoder is currently at the end token for an object or array, +// then it reports a [SyntacticError] and the internal state remains unchanged. +// It returns [io.EOF] if there are no more values. +func (d *Decoder) ReadValue() (Value, error) { + var flags jsonwire.ValueFlags + return d.s.ReadValue(&flags) +} +func (d *decoderState) ReadValue(flags *jsonwire.ValueFlags) (Value, error) { + // Determine the next kind. + var err error + var next Kind + pos := d.peekPos + if pos != 0 { + // Use cached peek result. + if d.peekErr != nil { + err := d.peekErr + d.peekPos, d.peekErr = 0, nil // possibly a transient I/O error + return nil, err + } + next = Kind(d.buf[pos]).normalize() + d.peekPos = 0 // reset cache + } else { + d.invalidatePreviousRead() + pos = d.prevEnd + + // Consume leading whitespace. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 { + err = io.EOF // EOF possibly if no Tokens present after top-level value + } + return nil, wrapSyntacticError(d, err, pos, 0) + } + } + + // Consume colon or comma. + var delim byte + if c := d.buf[pos]; c == ':' || c == ',' { + delim = c + pos += 1 + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + err = wrapSyntacticError(d, err, pos, 0) + return nil, d.checkDelimBeforeIOError(delim, err) + } + } + } + next = Kind(d.buf[pos]).normalize() + if d.Tokens.needDelim(next) != delim { + return nil, d.checkDelim(delim, next) + } + } + + // Handle the next value. + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeValue(flags, pos, d.Tokens.Depth()) + newAbsPos := d.baseOffset + int64(pos) + n := int(newAbsPos - oldAbsPos) + if err != nil { + return nil, wrapSyntacticError(d, err, pos, +1) + } + switch next { + case 'n', 't', 'f': + err = d.Tokens.appendLiteral() + case '"': + if d.Tokens.Last.NeedObjectName() { + if !d.Flags.Get(jsonflags.AllowDuplicateNames) { + if !d.Tokens.Last.isValidNamespace() { + err = errInvalidNamespace + break + } + if d.Tokens.Last.isActiveNamespace() && !d.Namespaces.Last().insertQuoted(d.buf[pos-n:pos], flags.IsVerbatim()) { + err = wrapWithObjectName(ErrDuplicateName, d.buf[pos-n:pos]) + break + } + } + d.Names.ReplaceLastQuotedOffset(pos - n) // only replace if insertQuoted succeeds + } + err = d.Tokens.appendString() + case '0': + err = d.Tokens.appendNumber() + case '{': + if err = d.Tokens.pushObject(); err != nil { + break + } + if err = d.Tokens.popObject(); err != nil { + panic("BUG: popObject should never fail immediately after pushObject: " + err.Error()) + } + case '[': + if err = d.Tokens.pushArray(); err != nil { + break + } + if err = d.Tokens.popArray(); err != nil { + panic("BUG: popArray should never fail immediately after pushArray: " + err.Error()) + } + } + if err != nil { + return nil, wrapSyntacticError(d, err, pos-n, +1) // report position at start of value + } + d.prevEnd = pos + d.prevStart = pos - n + return d.buf[pos-n : pos : pos], nil +} + +// CheckNextValue checks whether the next value is syntactically valid, +// but does not advance the read offset. +// If last, it verifies that the stream cleanly terminates with [io.EOF]. +func (d *decoderState) CheckNextValue(last bool) error { + d.PeekKind() // populates d.peekPos and d.peekErr + pos, err := d.peekPos, d.peekErr + d.peekPos, d.peekErr = 0, nil + if err != nil { + return err + } + + var flags jsonwire.ValueFlags + if pos, err := d.consumeValue(&flags, pos, d.Tokens.Depth()); err != nil { + return wrapSyntacticError(d, err, pos, +1) + } else if last { + return d.checkEOF(pos) + } + return nil +} + +// CheckEOF verifies that the input has no more data. +func (d *decoderState) CheckEOF() error { + return d.checkEOF(d.prevEnd) +} +func (d *decoderState) checkEOF(pos int) error { + switch pos, err := d.consumeWhitespace(pos); err { + case nil: + err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after top-level value") + return wrapSyntacticError(d, err, pos, 0) + case io.ErrUnexpectedEOF: + return nil + default: + return err + } +} + +// consumeWhitespace consumes all whitespace starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the last whitespace. +// If it returns nil, there is guaranteed to at least be one unread byte. +// +// The following pattern is common in this implementation: +// +// pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) +// if d.needMore(pos) { +// if pos, err = d.consumeWhitespace(pos); err != nil { +// return ... +// } +// } +// +// It is difficult to simplify this without sacrificing performance since +// consumeWhitespace must be inlined. The body of the if statement is +// executed only in rare situations where we need to fetch more data. +// Since fetching may return an error, we also need to check the error. +func (d *decoderState) consumeWhitespace(pos int) (newPos int, err error) { + for { + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos, err + } + continue + } + return pos, nil + } +} + +// consumeValue consumes a single JSON value starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the value. +func (d *decoderState) consumeValue(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) { + for { + var n int + var err error + switch next := Kind(d.buf[pos]).normalize(); next { + case 'n': + if n = jsonwire.ConsumeNull(d.buf[pos:]); n == 0 { + n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "null") + } + case 'f': + if n = jsonwire.ConsumeFalse(d.buf[pos:]); n == 0 { + n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "false") + } + case 't': + if n = jsonwire.ConsumeTrue(d.buf[pos:]); n == 0 { + n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "true") + } + case '"': + if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 { + return d.consumeString(flags, pos) + } + case '0': + // NOTE: Since JSON numbers are not self-terminating, + // we need to make sure that the next byte is not part of a number. + if n = jsonwire.ConsumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { + return d.consumeNumber(pos) + } + case '{': + return d.consumeObject(flags, pos, depth) + case '[': + return d.consumeArray(flags, pos, depth) + default: + if (d.Tokens.Last.isObject() && next == ']') || (d.Tokens.Last.isArray() && next == '}') { + return pos, errMismatchDelim + } + return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "at start of value") + } + if err == io.ErrUnexpectedEOF { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos + n, err + } + continue + } + return pos + n, err + } +} + +// consumeLiteral consumes a single JSON literal starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the literal. +func (d *decoderState) consumeLiteral(pos int, lit string) (newPos int, err error) { + for { + n, err := jsonwire.ConsumeLiteral(d.buf[pos:], lit) + if err == io.ErrUnexpectedEOF { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos + n, err + } + continue + } + return pos + n, err + } +} + +// consumeString consumes a single JSON string starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the string. +func (d *decoderState) consumeString(flags *jsonwire.ValueFlags, pos int) (newPos int, err error) { + var n int + for { + n, err = jsonwire.ConsumeStringResumable(flags, d.buf[pos:], n, !d.Flags.Get(jsonflags.AllowInvalidUTF8)) + if err == io.ErrUnexpectedEOF { + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + return pos + n, err + } + continue + } + return pos + n, err + } +} + +// consumeNumber consumes a single JSON number starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the number. +func (d *decoderState) consumeNumber(pos int) (newPos int, err error) { + var n int + var state jsonwire.ConsumeNumberState + for { + n, state, err = jsonwire.ConsumeNumberResumable(d.buf[pos:], n, state) + // NOTE: Since JSON numbers are not self-terminating, + // we need to make sure that the next byte is not part of a number. + if err == io.ErrUnexpectedEOF || d.needMore(pos+n) { + mayTerminate := err == nil + absPos := d.baseOffset + int64(pos) + err = d.fetch() // will mutate d.buf and invalidate pos + pos = int(absPos - d.baseOffset) + if err != nil { + if mayTerminate && err == io.ErrUnexpectedEOF { + return pos + n, nil + } + return pos, err + } + continue + } + return pos + n, err + } +} + +// consumeObject consumes a single JSON object starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the object. +func (d *decoderState) consumeObject(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) { + var n int + var names *objectNamespace + if !d.Flags.Get(jsonflags.AllowDuplicateNames) { + d.Namespaces.push() + defer d.Namespaces.pop() + names = d.Namespaces.Last() + } + + // Handle before start. + if uint(pos) >= uint(len(d.buf)) || d.buf[pos] != '{' { + panic("BUG: consumeObject must be called with a buffer that starts with '{'") + } else if depth == maxNestingDepth+1 { + return pos, errMaxDepth + } + pos++ + + // Handle after start. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + if d.buf[pos] == '}' { + pos++ + return pos, nil + } + + depth++ + for { + // Handle before name. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + var flags2 jsonwire.ValueFlags + if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 { + oldAbsPos := d.baseOffset + int64(pos) + pos, err = d.consumeString(&flags2, pos) + newAbsPos := d.baseOffset + int64(pos) + n = int(newAbsPos - oldAbsPos) + flags.Join(flags2) + if err != nil { + return pos, err + } + } else { + pos += n + } + quotedName := d.buf[pos-n : pos] + if !d.Flags.Get(jsonflags.AllowDuplicateNames) && !names.insertQuoted(quotedName, flags2.IsVerbatim()) { + return pos - n, wrapWithObjectName(ErrDuplicateName, quotedName) + } + + // Handle after name. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, wrapWithObjectName(err, quotedName) + } + } + if d.buf[pos] != ':' { + err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after object name (expecting ':')") + return pos, wrapWithObjectName(err, quotedName) + } + pos++ + + // Handle before value. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, wrapWithObjectName(err, quotedName) + } + } + pos, err = d.consumeValue(flags, pos, depth) + if err != nil { + return pos, wrapWithObjectName(err, quotedName) + } + + // Handle after value. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + switch d.buf[pos] { + case ',': + pos++ + continue + case '}': + pos++ + return pos, nil + default: + return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "after object value (expecting ',' or '}')") + } + } +} + +// consumeArray consumes a single JSON array starting at d.buf[pos:]. +// It returns the new position in d.buf immediately after the array. +func (d *decoderState) consumeArray(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) { + // Handle before start. + if uint(pos) >= uint(len(d.buf)) || d.buf[pos] != '[' { + panic("BUG: consumeArray must be called with a buffer that starts with '['") + } else if depth == maxNestingDepth+1 { + return pos, errMaxDepth + } + pos++ + + // Handle after start. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + if d.buf[pos] == ']' { + pos++ + return pos, nil + } + + var idx int64 + depth++ + for { + // Handle before value. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + pos, err = d.consumeValue(flags, pos, depth) + if err != nil { + return pos, wrapWithArrayIndex(err, idx) + } + + // Handle after value. + pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) + if d.needMore(pos) { + if pos, err = d.consumeWhitespace(pos); err != nil { + return pos, err + } + } + switch d.buf[pos] { + case ',': + pos++ + idx++ + continue + case ']': + pos++ + return pos, nil + default: + return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "after array element (expecting ',' or ']')") + } + } +} + +// InputOffset returns the current input byte offset. It gives the location +// of the next byte immediately after the most recently returned token or value. +// The number of bytes actually read from the underlying [io.Reader] may be more +// than this offset due to internal buffering effects. +func (d *Decoder) InputOffset() int64 { + return d.s.previousOffsetEnd() +} + +// UnreadBuffer returns the data remaining in the unread buffer, +// which may contain zero or more bytes. +// The returned buffer must not be mutated while Decoder continues to be used. +// The buffer contents are valid until the next Peek, Read, or Skip call. +func (d *Decoder) UnreadBuffer() []byte { + return d.s.unreadBuffer() +} + +// StackDepth returns the depth of the state machine for read JSON data. +// Each level on the stack represents a nested JSON object or array. +// It is incremented whenever an [BeginObject] or [BeginArray] token is encountered +// and decremented whenever an [EndObject] or [EndArray] token is encountered. +// The depth is zero-indexed, where zero represents the top-level JSON value. +func (d *Decoder) StackDepth() int { + // NOTE: Keep in sync with Encoder.StackDepth. + return d.s.Tokens.Depth() - 1 +} + +// StackIndex returns information about the specified stack level. +// It must be a number between 0 and [Decoder.StackDepth], inclusive. +// For each level, it reports the kind: +// +// - 0 for a level of zero, +// - '{' for a level representing a JSON object, and +// - '[' for a level representing a JSON array. +// +// It also reports the length of that JSON object or array. +// Each name and value in a JSON object is counted separately, +// so the effective number of members would be half the length. +// A complete JSON object must have an even length. +func (d *Decoder) StackIndex(i int) (Kind, int64) { + // NOTE: Keep in sync with Encoder.StackIndex. + switch s := d.s.Tokens.index(i); { + case i > 0 && s.isObject(): + return '{', s.Length() + case i > 0 && s.isArray(): + return '[', s.Length() + default: + return 0, s.Length() + } +} + +// StackPointer returns a JSON Pointer (RFC 6901) to the most recently read value. +func (d *Decoder) StackPointer() Pointer { + return Pointer(d.s.AppendStackPointer(nil, -1)) +} + +func (d *decoderState) AppendStackPointer(b []byte, where int) []byte { + d.Names.copyQuotedBuffer(d.buf) + return d.state.appendStackPointer(b, where) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go new file mode 100644 index 00000000..bea3ccd3 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/doc.go @@ -0,0 +1,109 @@ +// Copyright 2023 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 jsontext implements syntactic processing of JSON +// as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785. +// JSON is a simple data interchange format that can represent +// primitive data types such as booleans, strings, and numbers, +// in addition to structured data types such as objects and arrays. +// +// The [Encoder] and [Decoder] types are used to encode or decode +// a stream of JSON tokens or values. +// +// # Tokens and Values +// +// A JSON token refers to the basic structural elements of JSON: +// +// - a JSON literal (i.e., null, true, or false) +// - a JSON string (e.g., "hello, world!") +// - a JSON number (e.g., 123.456) +// - a begin or end delimiter for a JSON object (i.e., '{' or '}') +// - a begin or end delimiter for a JSON array (i.e., '[' or ']') +// +// A JSON token is represented by the [Token] type in Go. Technically, +// there are two additional structural characters (i.e., ':' and ','), +// but there is no [Token] representation for them since their presence +// can be inferred by the structure of the JSON grammar itself. +// For example, there must always be an implicit colon between +// the name and value of a JSON object member. +// +// A JSON value refers to a complete unit of JSON data: +// +// - a JSON literal, string, or number +// - a JSON object (e.g., `{"name":"value"}`) +// - a JSON array (e.g., `[1,2,3,]`) +// +// A JSON value is represented by the [Value] type in Go and is a []byte +// containing the raw textual representation of the value. There is some overlap +// between tokens and values as both contain literals, strings, and numbers. +// However, only a value can represent the entirety of a JSON object or array. +// +// The [Encoder] and [Decoder] types contain methods to read or write the next +// [Token] or [Value] in a sequence. They maintain a state machine to validate +// whether the sequence of JSON tokens and/or values produces a valid JSON. +// [Options] may be passed to the [NewEncoder] or [NewDecoder] constructors +// to configure the syntactic behavior of encoding and decoding. +// +// # Terminology +// +// The terms "encode" and "decode" are used for syntactic functionality +// that is concerned with processing JSON based on its grammar, and +// the terms "marshal" and "unmarshal" are used for semantic functionality +// that determines the meaning of JSON values as Go values and vice-versa. +// This package (i.e., [jsontext]) deals with JSON at a syntactic layer, +// while [encoding/json/v2] deals with JSON at a semantic layer. +// The goal is to provide a clear distinction between functionality that +// is purely concerned with encoding versus that of marshaling. +// For example, one can directly encode a stream of JSON tokens without +// needing to marshal a concrete Go value representing them. +// Similarly, one can decode a stream of JSON tokens without +// needing to unmarshal them into a concrete Go value. +// +// This package uses JSON terminology when discussing JSON, which may differ +// from related concepts in Go or elsewhere in computing literature. +// +// - a JSON "object" refers to an unordered collection of name/value members. +// - a JSON "array" refers to an ordered sequence of elements. +// - a JSON "value" refers to either a literal (i.e., null, false, or true), +// string, number, object, or array. +// +// See RFC 8259 for more information. +// +// # Specifications +// +// Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259, +// and RFC 8785. Each RFC is generally a stricter subset of another RFC. +// In increasing order of strictness: +// +// - RFC 4627 and RFC 7159 do not require (but recommend) the use of UTF-8 +// and also do not require (but recommend) that object names be unique. +// - RFC 8259 requires the use of UTF-8, +// but does not require (but recommends) that object names be unique. +// - RFC 7493 requires the use of UTF-8 +// and also requires that object names be unique. +// - RFC 8785 defines a canonical representation. It requires the use of UTF-8 +// and also requires that object names be unique and in a specific ordering. +// It specifies exactly how strings and numbers must be formatted. +// +// The primary difference between RFC 4627 and RFC 7159 is that the former +// restricted top-level values to only JSON objects and arrays, while +// RFC 7159 and subsequent RFCs permit top-level values to additionally be +// JSON nulls, booleans, strings, or numbers. +// +// By default, this package operates on RFC 7493, but can be configured +// to operate according to the other RFC specifications. +// RFC 7493 is a stricter subset of RFC 8259 and fully compliant with it. +// In particular, it makes specific choices about behavior that RFC 8259 +// leaves as undefined in order to ensure greater interoperability. +// +// # Security Considerations +// +// See the "Security Considerations" section in [encoding/json/v2]. +package jsontext + +// requireKeyedLiterals can be embedded in a struct to require keyed literals. +type requireKeyedLiterals struct{} + +// nonComparable can be embedded in a struct to prevent comparability. +type nonComparable [0]func() diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go new file mode 100644 index 00000000..36bf7efd --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/encode.go @@ -0,0 +1,975 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsontext + +import ( + "bytes" + "io" + "math/bits" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" +) + +// Encoder is a streaming encoder from raw JSON tokens and values. +// It is used to write a stream of top-level JSON values, +// each terminated with a newline character. +// +// [Encoder.WriteToken] and [Encoder.WriteValue] calls may be interleaved. +// For example, the following JSON value: +// +// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}} +// +// can be composed with the following calls (ignoring errors for brevity): +// +// e.WriteToken(BeginObject) // { +// e.WriteToken(String("name")) // "name" +// e.WriteToken(String("value")) // "value" +// e.WriteValue(Value(`"array"`)) // "array" +// e.WriteToken(BeginArray) // [ +// e.WriteToken(Null) // null +// e.WriteToken(False) // false +// e.WriteValue(Value("true")) // true +// e.WriteToken(Float(3.14159)) // 3.14159 +// e.WriteToken(EndArray) // ] +// e.WriteValue(Value(`"object"`)) // "object" +// e.WriteValue(Value(`{"k":"v"}`)) // {"k":"v"} +// e.WriteToken(EndObject) // } +// +// The above is one of many possible sequence of calls and +// may not represent the most sensible method to call for any given token/value. +// For example, it is probably more common to call [Encoder.WriteToken] with a string +// for object names. +type Encoder struct { + s encoderState +} + +// encoderState is the low-level state of Encoder. +// It has exported fields and method for use by the "json" package. +type encoderState struct { + state + encodeBuffer + jsonopts.Struct + + SeenPointers map[any]struct{} // only used when marshaling; identical to json.seenPointers +} + +// encodeBuffer is a buffer split into 2 segments: +// +// - buf[0:len(buf)] // written (but unflushed) portion of the buffer +// - buf[len(buf):cap(buf)] // unused portion of the buffer +type encodeBuffer struct { + Buf []byte // may alias wr if it is a bytes.Buffer + + // baseOffset is added to len(buf) to obtain the absolute offset + // relative to the start of io.Writer stream. + baseOffset int64 + + wr io.Writer + + // maxValue is the approximate maximum Value size passed to WriteValue. + maxValue int + // availBuffer is the buffer returned by the AvailableBuffer method. + availBuffer []byte // always has zero length + // bufStats is statistics about buffer utilization. + // It is only used with pooled encoders in pools.go. + bufStats bufferStatistics +} + +// NewEncoder constructs a new streaming encoder writing to w +// configured with the provided options. +// It flushes the internal buffer when the buffer is sufficiently full or +// when a top-level value has been written. +// +// If w is a [bytes.Buffer], then the encoder appends directly into the buffer +// without copying the contents from an intermediate buffer. +func NewEncoder(w io.Writer, opts ...Options) *Encoder { + e := new(Encoder) + e.Reset(w, opts...) + return e +} + +// Reset resets an encoder such that it is writing afresh to w and +// configured with the provided options. Reset must not be called on +// a Encoder passed to the [encoding/json/v2.MarshalerTo.MarshalJSONTo] method +// or the [encoding/json/v2.MarshalToFunc] function. +func (e *Encoder) Reset(w io.Writer, opts ...Options) { + switch { + case e == nil: + panic("jsontext: invalid nil Encoder") + case w == nil: + panic("jsontext: invalid nil io.Writer") + case e.s.Flags.Get(jsonflags.WithinArshalCall): + panic("jsontext: cannot reset Encoder passed to json.MarshalerTo") + } + // Reuse the buffer if it does not alias a previous [bytes.Buffer]. + b := e.s.Buf[:0] + if _, ok := e.s.wr.(*bytes.Buffer); ok { + b = nil + } + e.s.reset(b, w, opts...) +} + +func (e *encoderState) reset(b []byte, w io.Writer, opts ...Options) { + e.state.reset() + e.encodeBuffer = encodeBuffer{Buf: b, wr: w, availBuffer: e.availBuffer, bufStats: e.bufStats} + if bb, ok := w.(*bytes.Buffer); ok && bb != nil { + e.Buf = bb.AvailableBuffer() // alias the unused buffer of bb + } + opts2 := jsonopts.Struct{} // avoid mutating e.Struct in case it is part of opts + opts2.Join(opts...) + e.Struct = opts2 + if e.Flags.Get(jsonflags.Multiline) { + if !e.Flags.Has(jsonflags.SpaceAfterColon) { + e.Flags.Set(jsonflags.SpaceAfterColon | 1) + } + if !e.Flags.Has(jsonflags.SpaceAfterComma) { + e.Flags.Set(jsonflags.SpaceAfterComma | 0) + } + if !e.Flags.Has(jsonflags.Indent) { + e.Flags.Set(jsonflags.Indent | 1) + e.Indent = "\t" + } + } +} + +// Options returns the options used to construct the decoder and +// may additionally contain semantic options passed to a +// [encoding/json/v2.MarshalEncode] call. +// +// If operating within +// a [encoding/json/v2.MarshalerTo.MarshalJSONTo] method call or +// a [encoding/json/v2.MarshalToFunc] function call, +// then the returned options are only valid within the call. +func (e *Encoder) Options() Options { + return &e.s.Struct +} + +// NeedFlush determines whether to flush at this point. +func (e *encoderState) NeedFlush() bool { + // NOTE: This function is carefully written to be inlinable. + + // Avoid flushing if e.wr is nil since there is no underlying writer. + // Flush if less than 25% of the capacity remains. + // Flushing at some constant fraction ensures that the buffer stops growing + // so long as the largest Token or Value fits within that unused capacity. + return e.wr != nil && (e.Tokens.Depth() == 1 || len(e.Buf) > 3*cap(e.Buf)/4) +} + +// Flush flushes the buffer to the underlying io.Writer. +// It may append a trailing newline after the top-level value. +func (e *encoderState) Flush() error { + if e.wr == nil || e.avoidFlush() { + return nil + } + + // In streaming mode, always emit a newline after the top-level value. + if e.Tokens.Depth() == 1 && !e.Flags.Get(jsonflags.OmitTopLevelNewline) { + e.Buf = append(e.Buf, '\n') + } + + // Inform objectNameStack that we are about to flush the buffer content. + e.Names.copyQuotedBuffer(e.Buf) + + // Specialize bytes.Buffer for better performance. + if bb, ok := e.wr.(*bytes.Buffer); ok { + // If e.buf already aliases the internal buffer of bb, + // then the Write call simply increments the internal offset, + // otherwise Write operates as expected. + // See https://go.dev/issue/42986. + n, _ := bb.Write(e.Buf) // never fails unless bb is nil + e.baseOffset += int64(n) + + // If the internal buffer of bytes.Buffer is too small, + // append operations elsewhere in the Encoder may grow the buffer. + // This would be semantically correct, but hurts performance. + // As such, ensure 25% of the current length is always available + // to reduce the probability that other appends must allocate. + if avail := bb.Available(); avail < bb.Len()/4 { + bb.Grow(avail + 1) + } + + e.Buf = bb.AvailableBuffer() + return nil + } + + // Flush the internal buffer to the underlying io.Writer. + n, err := e.wr.Write(e.Buf) + e.baseOffset += int64(n) + if err != nil { + // In the event of an error, preserve the unflushed portion. + // Thus, write errors aren't fatal so long as the io.Writer + // maintains consistent state after errors. + if n > 0 { + e.Buf = e.Buf[:copy(e.Buf, e.Buf[n:])] + } + return &ioError{action: "write", err: err} + } + e.Buf = e.Buf[:0] + + // Check whether to grow the buffer. + // Note that cap(e.buf) may already exceed maxBufferSize since + // an append elsewhere already grew it to store a large token. + const maxBufferSize = 4 << 10 + const growthSizeFactor = 2 // higher value is faster + const growthRateFactor = 2 // higher value is slower + // By default, grow if below the maximum buffer size. + grow := cap(e.Buf) <= maxBufferSize/growthSizeFactor + // Growing can be expensive, so only grow + // if a sufficient number of bytes have been processed. + grow = grow && int64(cap(e.Buf)) < e.previousOffsetEnd()/growthRateFactor + if grow { + e.Buf = make([]byte, 0, cap(e.Buf)*growthSizeFactor) + } + + return nil +} +func (d *encodeBuffer) offsetAt(pos int) int64 { return d.baseOffset + int64(pos) } +func (e *encodeBuffer) previousOffsetEnd() int64 { return e.baseOffset + int64(len(e.Buf)) } +func (e *encodeBuffer) unflushedBuffer() []byte { return e.Buf } + +// avoidFlush indicates whether to avoid flushing to ensure there is always +// enough in the buffer to unwrite the last object member if it were empty. +func (e *encoderState) avoidFlush() bool { + switch { + case e.Tokens.Last.Length() == 0: + // Never flush after BeginObject or BeginArray since we don't know yet + // if the object or array will end up being empty. + return true + case e.Tokens.Last.needObjectValue(): + // Never flush before the object value since we don't know yet + // if the object value will end up being empty. + return true + case e.Tokens.Last.NeedObjectName() && len(e.Buf) >= 2: + // Never flush after the object value if it does turn out to be empty. + switch string(e.Buf[len(e.Buf)-2:]) { + case `ll`, `""`, `{}`, `[]`: // last two bytes of every empty value + return true + } + } + return false +} + +// UnwriteEmptyObjectMember unwrites the last object member if it is empty +// and reports whether it performed an unwrite operation. +func (e *encoderState) UnwriteEmptyObjectMember(prevName *string) bool { + if last := e.Tokens.Last; !last.isObject() || !last.NeedObjectName() || last.Length() == 0 { + panic("BUG: must be called on an object after writing a value") + } + + // The flushing logic is modified to never flush a trailing empty value. + // The encoder never writes trailing whitespace eagerly. + b := e.unflushedBuffer() + + // Detect whether the last value was empty. + var n int + if len(b) >= 3 { + switch string(b[len(b)-2:]) { + case "ll": // last two bytes of `null` + n = len(`null`) + case `""`: + // It is possible for a non-empty string to have `""` as a suffix + // if the second to the last quote was escaped. + if b[len(b)-3] == '\\' { + return false // e.g., `"\""` is not empty + } + n = len(`""`) + case `{}`: + n = len(`{}`) + case `[]`: + n = len(`[]`) + } + } + if n == 0 { + return false + } + + // Unwrite the value, whitespace, colon, name, whitespace, and comma. + b = b[:len(b)-n] + b = jsonwire.TrimSuffixWhitespace(b) + b = jsonwire.TrimSuffixByte(b, ':') + b = jsonwire.TrimSuffixString(b) + b = jsonwire.TrimSuffixWhitespace(b) + b = jsonwire.TrimSuffixByte(b, ',') + e.Buf = b // store back truncated unflushed buffer + + // Undo state changes. + e.Tokens.Last.decrement() // for object member value + e.Tokens.Last.decrement() // for object member name + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + if e.Tokens.Last.isActiveNamespace() { + e.Namespaces.Last().removeLast() + } + } + e.Names.clearLast() + if prevName != nil { + e.Names.copyQuotedBuffer(e.Buf) // required by objectNameStack.replaceLastUnquotedName + e.Names.replaceLastUnquotedName(*prevName) + } + return true +} + +// UnwriteOnlyObjectMemberName unwrites the only object member name +// and returns the unquoted name. +func (e *encoderState) UnwriteOnlyObjectMemberName() string { + if last := e.Tokens.Last; !last.isObject() || last.Length() != 1 { + panic("BUG: must be called on an object after writing first name") + } + + // Unwrite the name and whitespace. + b := jsonwire.TrimSuffixString(e.Buf) + isVerbatim := bytes.IndexByte(e.Buf[len(b):], '\\') < 0 + name := string(jsonwire.UnquoteMayCopy(e.Buf[len(b):], isVerbatim)) + e.Buf = jsonwire.TrimSuffixWhitespace(b) + + // Undo state changes. + e.Tokens.Last.decrement() + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + if e.Tokens.Last.isActiveNamespace() { + e.Namespaces.Last().removeLast() + } + } + e.Names.clearLast() + return name +} + +// WriteToken writes the next token and advances the internal write offset. +// +// The provided token kind must be consistent with the JSON grammar. +// For example, it is an error to provide a number when the encoder +// is expecting an object name (which is always a string), or +// to provide an end object delimiter when the encoder is finishing an array. +// If the provided token is invalid, then it reports a [SyntacticError] and +// the internal state remains unchanged. The offset reported +// in [SyntacticError] will be relative to the [Encoder.OutputOffset]. +func (e *Encoder) WriteToken(t Token) error { + return e.s.WriteToken(t) +} +func (e *encoderState) WriteToken(t Token) error { + k := t.Kind() + b := e.Buf // use local variable to avoid mutating e in case of error + + // Append any delimiters or optional whitespace. + b = e.Tokens.MayAppendDelim(b, k) + if e.Flags.Get(jsonflags.AnyWhitespace) { + b = e.appendWhitespace(b, k) + } + pos := len(b) // offset before the token + + // Append the token to the output and to the state machine. + var err error + switch k { + case 'n': + b = append(b, "null"...) + err = e.Tokens.appendLiteral() + case 'f': + b = append(b, "false"...) + err = e.Tokens.appendLiteral() + case 't': + b = append(b, "true"...) + err = e.Tokens.appendLiteral() + case '"': + if b, err = t.appendString(b, &e.Flags); err != nil { + break + } + if e.Tokens.Last.NeedObjectName() { + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + if !e.Tokens.Last.isValidNamespace() { + err = errInvalidNamespace + break + } + if e.Tokens.Last.isActiveNamespace() && !e.Namespaces.Last().insertQuoted(b[pos:], false) { + err = wrapWithObjectName(ErrDuplicateName, b[pos:]) + break + } + } + e.Names.ReplaceLastQuotedOffset(pos) // only replace if insertQuoted succeeds + } + err = e.Tokens.appendString() + case '0': + if b, err = t.appendNumber(b, &e.Flags); err != nil { + break + } + err = e.Tokens.appendNumber() + case '{': + b = append(b, '{') + if err = e.Tokens.pushObject(); err != nil { + break + } + e.Names.push() + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + e.Namespaces.push() + } + case '}': + b = append(b, '}') + if err = e.Tokens.popObject(); err != nil { + break + } + e.Names.pop() + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + e.Namespaces.pop() + } + case '[': + b = append(b, '[') + err = e.Tokens.pushArray() + case ']': + b = append(b, ']') + err = e.Tokens.popArray() + default: + err = errInvalidToken + } + if err != nil { + return wrapSyntacticError(e, err, pos, +1) + } + + // Finish off the buffer and store it back into e. + e.Buf = b + if e.NeedFlush() { + return e.Flush() + } + return nil +} + +// AppendRaw appends either a raw string (without double quotes) or number. +// Specify safeASCII if the string output is guaranteed to be ASCII +// without any characters (including '<', '>', and '&') that need escaping, +// otherwise this will validate whether the string needs escaping. +// The appended bytes for a JSON number must be valid. +// +// This is a specialized implementation of Encoder.WriteValue +// that allows appending directly into the buffer. +// It is only called from marshal logic in the "json" package. +func (e *encoderState) AppendRaw(k Kind, safeASCII bool, appendFn func([]byte) ([]byte, error)) error { + b := e.Buf // use local variable to avoid mutating e in case of error + + // Append any delimiters or optional whitespace. + b = e.Tokens.MayAppendDelim(b, k) + if e.Flags.Get(jsonflags.AnyWhitespace) { + b = e.appendWhitespace(b, k) + } + pos := len(b) // offset before the token + + var err error + switch k { + case '"': + // Append directly into the encoder buffer by assuming that + // most of the time none of the characters need escaping. + b = append(b, '"') + if b, err = appendFn(b); err != nil { + return err + } + b = append(b, '"') + + // Check whether we need to escape the string and if necessary + // copy it to a scratch buffer and then escape it back. + isVerbatim := safeASCII || !jsonwire.NeedEscape(b[pos+len(`"`):len(b)-len(`"`)]) + if !isVerbatim { + var err error + b2 := append(e.availBuffer, b[pos+len(`"`):len(b)-len(`"`)]...) + b, err = jsonwire.AppendQuote(b[:pos], string(b2), &e.Flags) + e.availBuffer = b2[:0] + if err != nil { + return wrapSyntacticError(e, err, pos, +1) + } + } + + // Update the state machine. + if e.Tokens.Last.NeedObjectName() { + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + if !e.Tokens.Last.isValidNamespace() { + return wrapSyntacticError(e, err, pos, +1) + } + if e.Tokens.Last.isActiveNamespace() && !e.Namespaces.Last().insertQuoted(b[pos:], isVerbatim) { + err = wrapWithObjectName(ErrDuplicateName, b[pos:]) + return wrapSyntacticError(e, err, pos, +1) + } + } + e.Names.ReplaceLastQuotedOffset(pos) // only replace if insertQuoted succeeds + } + if err := e.Tokens.appendString(); err != nil { + return wrapSyntacticError(e, err, pos, +1) + } + case '0': + if b, err = appendFn(b); err != nil { + return err + } + if err := e.Tokens.appendNumber(); err != nil { + return wrapSyntacticError(e, err, pos, +1) + } + default: + panic("BUG: invalid kind") + } + + // Finish off the buffer and store it back into e. + e.Buf = b + if e.NeedFlush() { + return e.Flush() + } + return nil +} + +// WriteValue writes the next raw value and advances the internal write offset. +// The Encoder does not simply copy the provided value verbatim, but +// parses it to ensure that it is syntactically valid and reformats it +// according to how the Encoder is configured to format whitespace and strings. +// If [AllowInvalidUTF8] is specified, then any invalid UTF-8 is mangled +// as the Unicode replacement character, U+FFFD. +// +// The provided value kind must be consistent with the JSON grammar +// (see examples on [Encoder.WriteToken]). If the provided value is invalid, +// then it reports a [SyntacticError] and the internal state remains unchanged. +// The offset reported in [SyntacticError] will be relative to the +// [Encoder.OutputOffset] plus the offset into v of any encountered syntax error. +func (e *Encoder) WriteValue(v Value) error { + return e.s.WriteValue(v) +} +func (e *encoderState) WriteValue(v Value) error { + e.maxValue |= len(v) // bitwise OR is a fast approximation of max + + k := v.Kind() + b := e.Buf // use local variable to avoid mutating e in case of error + + // Append any delimiters or optional whitespace. + b = e.Tokens.MayAppendDelim(b, k) + if e.Flags.Get(jsonflags.AnyWhitespace) { + b = e.appendWhitespace(b, k) + } + pos := len(b) // offset before the value + + // Append the value the output. + var n int + n += jsonwire.ConsumeWhitespace(v[n:]) + b, m, err := e.reformatValue(b, v[n:], e.Tokens.Depth()) + if err != nil { + return wrapSyntacticError(e, err, pos+n+m, +1) + } + n += m + n += jsonwire.ConsumeWhitespace(v[n:]) + if len(v) > n { + err = jsonwire.NewInvalidCharacterError(v[n:], "after top-level value") + return wrapSyntacticError(e, err, pos+n, 0) + } + + // Append the kind to the state machine. + switch k { + case 'n', 'f', 't': + err = e.Tokens.appendLiteral() + case '"': + if e.Tokens.Last.NeedObjectName() { + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + if !e.Tokens.Last.isValidNamespace() { + err = errInvalidNamespace + break + } + if e.Tokens.Last.isActiveNamespace() && !e.Namespaces.Last().insertQuoted(b[pos:], false) { + err = wrapWithObjectName(ErrDuplicateName, b[pos:]) + break + } + } + e.Names.ReplaceLastQuotedOffset(pos) // only replace if insertQuoted succeeds + } + err = e.Tokens.appendString() + case '0': + err = e.Tokens.appendNumber() + case '{': + if err = e.Tokens.pushObject(); err != nil { + break + } + if err = e.Tokens.popObject(); err != nil { + panic("BUG: popObject should never fail immediately after pushObject: " + err.Error()) + } + if e.Flags.Get(jsonflags.ReorderRawObjects) { + mustReorderObjects(b[pos:]) + } + case '[': + if err = e.Tokens.pushArray(); err != nil { + break + } + if err = e.Tokens.popArray(); err != nil { + panic("BUG: popArray should never fail immediately after pushArray: " + err.Error()) + } + if e.Flags.Get(jsonflags.ReorderRawObjects) { + mustReorderObjects(b[pos:]) + } + } + if err != nil { + return wrapSyntacticError(e, err, pos, +1) + } + + // Finish off the buffer and store it back into e. + e.Buf = b + if e.NeedFlush() { + return e.Flush() + } + return nil +} + +// CountNextDelimWhitespace counts the number of bytes of delimiter and +// whitespace bytes assuming the upcoming token is a JSON value. +// This method is used for error reporting at the semantic layer. +func (e *encoderState) CountNextDelimWhitespace() (n int) { + const next = Kind('"') // arbitrary kind as next JSON value + delim := e.Tokens.needDelim(next) + if delim > 0 { + n += len(",") | len(":") + } + if delim == ':' { + if e.Flags.Get(jsonflags.SpaceAfterColon) { + n += len(" ") + } + } else { + if delim == ',' && e.Flags.Get(jsonflags.SpaceAfterComma) { + n += len(" ") + } + if e.Flags.Get(jsonflags.Multiline) { + if m := e.Tokens.NeedIndent(next); m > 0 { + n += len("\n") + len(e.IndentPrefix) + (m-1)*len(e.Indent) + } + } + } + return n +} + +// appendWhitespace appends whitespace that immediately precedes the next token. +func (e *encoderState) appendWhitespace(b []byte, next Kind) []byte { + if delim := e.Tokens.needDelim(next); delim == ':' { + if e.Flags.Get(jsonflags.SpaceAfterColon) { + b = append(b, ' ') + } + } else { + if delim == ',' && e.Flags.Get(jsonflags.SpaceAfterComma) { + b = append(b, ' ') + } + if e.Flags.Get(jsonflags.Multiline) { + b = e.AppendIndent(b, e.Tokens.NeedIndent(next)) + } + } + return b +} + +// AppendIndent appends the appropriate number of indentation characters +// for the current nested level, n. +func (e *encoderState) AppendIndent(b []byte, n int) []byte { + if n == 0 { + return b + } + b = append(b, '\n') + b = append(b, e.IndentPrefix...) + for ; n > 1; n-- { + b = append(b, e.Indent...) + } + return b +} + +// reformatValue parses a JSON value from the start of src and +// appends it to the end of dst, reformatting whitespace and strings as needed. +// It returns the extended dst buffer and the number of consumed input bytes. +func (e *encoderState) reformatValue(dst []byte, src Value, depth int) ([]byte, int, error) { + // TODO: Should this update ValueFlags as input? + if len(src) == 0 { + return dst, 0, io.ErrUnexpectedEOF + } + switch k := Kind(src[0]).normalize(); k { + case 'n': + if jsonwire.ConsumeNull(src) == 0 { + n, err := jsonwire.ConsumeLiteral(src, "null") + return dst, n, err + } + return append(dst, "null"...), len("null"), nil + case 'f': + if jsonwire.ConsumeFalse(src) == 0 { + n, err := jsonwire.ConsumeLiteral(src, "false") + return dst, n, err + } + return append(dst, "false"...), len("false"), nil + case 't': + if jsonwire.ConsumeTrue(src) == 0 { + n, err := jsonwire.ConsumeLiteral(src, "true") + return dst, n, err + } + return append(dst, "true"...), len("true"), nil + case '"': + if n := jsonwire.ConsumeSimpleString(src); n > 0 { + dst = append(dst, src[:n]...) // copy simple strings verbatim + return dst, n, nil + } + return jsonwire.ReformatString(dst, src, &e.Flags) + case '0': + if n := jsonwire.ConsumeSimpleNumber(src); n > 0 && !e.Flags.Get(jsonflags.CanonicalizeNumbers) { + dst = append(dst, src[:n]...) // copy simple numbers verbatim + return dst, n, nil + } + return jsonwire.ReformatNumber(dst, src, &e.Flags) + case '{': + return e.reformatObject(dst, src, depth) + case '[': + return e.reformatArray(dst, src, depth) + default: + return dst, 0, jsonwire.NewInvalidCharacterError(src, "at start of value") + } +} + +// reformatObject parses a JSON object from the start of src and +// appends it to the end of src, reformatting whitespace and strings as needed. +// It returns the extended dst buffer and the number of consumed input bytes. +func (e *encoderState) reformatObject(dst []byte, src Value, depth int) ([]byte, int, error) { + // Append object begin. + if len(src) == 0 || src[0] != '{' { + panic("BUG: reformatObject must be called with a buffer that starts with '{'") + } else if depth == maxNestingDepth+1 { + return dst, 0, errMaxDepth + } + dst = append(dst, '{') + n := len("{") + + // Append (possible) object end. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, io.ErrUnexpectedEOF + } + if src[n] == '}' { + dst = append(dst, '}') + n += len("}") + return dst, n, nil + } + + var err error + var names *objectNamespace + if !e.Flags.Get(jsonflags.AllowDuplicateNames) { + e.Namespaces.push() + defer e.Namespaces.pop() + names = e.Namespaces.Last() + } + depth++ + for { + // Append optional newline and indentation. + if e.Flags.Get(jsonflags.Multiline) { + dst = e.AppendIndent(dst, depth) + } + + // Append object name. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, io.ErrUnexpectedEOF + } + m := jsonwire.ConsumeSimpleString(src[n:]) + isVerbatim := m > 0 + if isVerbatim { + dst = append(dst, src[n:n+m]...) + } else { + dst, m, err = jsonwire.ReformatString(dst, src[n:], &e.Flags) + if err != nil { + return dst, n + m, err + } + } + quotedName := src[n : n+m] + if !e.Flags.Get(jsonflags.AllowDuplicateNames) && !names.insertQuoted(quotedName, isVerbatim) { + return dst, n, wrapWithObjectName(ErrDuplicateName, quotedName) + } + n += m + + // Append colon. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, wrapWithObjectName(io.ErrUnexpectedEOF, quotedName) + } + if src[n] != ':' { + err = jsonwire.NewInvalidCharacterError(src[n:], "after object name (expecting ':')") + return dst, n, wrapWithObjectName(err, quotedName) + } + dst = append(dst, ':') + n += len(":") + if e.Flags.Get(jsonflags.SpaceAfterColon) { + dst = append(dst, ' ') + } + + // Append object value. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, wrapWithObjectName(io.ErrUnexpectedEOF, quotedName) + } + dst, m, err = e.reformatValue(dst, src[n:], depth) + if err != nil { + return dst, n + m, wrapWithObjectName(err, quotedName) + } + n += m + + // Append comma or object end. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, io.ErrUnexpectedEOF + } + switch src[n] { + case ',': + dst = append(dst, ',') + if e.Flags.Get(jsonflags.SpaceAfterComma) { + dst = append(dst, ' ') + } + n += len(",") + continue + case '}': + if e.Flags.Get(jsonflags.Multiline) { + dst = e.AppendIndent(dst, depth-1) + } + dst = append(dst, '}') + n += len("}") + return dst, n, nil + default: + return dst, n, jsonwire.NewInvalidCharacterError(src[n:], "after object value (expecting ',' or '}')") + } + } +} + +// reformatArray parses a JSON array from the start of src and +// appends it to the end of dst, reformatting whitespace and strings as needed. +// It returns the extended dst buffer and the number of consumed input bytes. +func (e *encoderState) reformatArray(dst []byte, src Value, depth int) ([]byte, int, error) { + // Append array begin. + if len(src) == 0 || src[0] != '[' { + panic("BUG: reformatArray must be called with a buffer that starts with '['") + } else if depth == maxNestingDepth+1 { + return dst, 0, errMaxDepth + } + dst = append(dst, '[') + n := len("[") + + // Append (possible) array end. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, io.ErrUnexpectedEOF + } + if src[n] == ']' { + dst = append(dst, ']') + n += len("]") + return dst, n, nil + } + + var idx int64 + var err error + depth++ + for { + // Append optional newline and indentation. + if e.Flags.Get(jsonflags.Multiline) { + dst = e.AppendIndent(dst, depth) + } + + // Append array value. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, io.ErrUnexpectedEOF + } + var m int + dst, m, err = e.reformatValue(dst, src[n:], depth) + if err != nil { + return dst, n + m, wrapWithArrayIndex(err, idx) + } + n += m + + // Append comma or array end. + n += jsonwire.ConsumeWhitespace(src[n:]) + if uint(len(src)) <= uint(n) { + return dst, n, io.ErrUnexpectedEOF + } + switch src[n] { + case ',': + dst = append(dst, ',') + if e.Flags.Get(jsonflags.SpaceAfterComma) { + dst = append(dst, ' ') + } + n += len(",") + idx++ + continue + case ']': + if e.Flags.Get(jsonflags.Multiline) { + dst = e.AppendIndent(dst, depth-1) + } + dst = append(dst, ']') + n += len("]") + return dst, n, nil + default: + return dst, n, jsonwire.NewInvalidCharacterError(src[n:], "after array value (expecting ',' or ']')") + } + } +} + +// OutputOffset returns the current output byte offset. It gives the location +// of the next byte immediately after the most recently written token or value. +// The number of bytes actually written to the underlying [io.Writer] may be less +// than this offset due to internal buffering effects. +func (e *Encoder) OutputOffset() int64 { + return e.s.previousOffsetEnd() +} + +// AvailableBuffer returns a zero-length buffer with a possible non-zero capacity. +// This buffer is intended to be used to populate a [Value] +// being passed to an immediately succeeding [Encoder.WriteValue] call. +// +// Example usage: +// +// b := d.AvailableBuffer() +// b = append(b, '"') +// b = appendString(b, v) // append the string formatting of v +// b = append(b, '"') +// ... := d.WriteValue(b) +// +// It is the user's responsibility to ensure that the value is valid JSON. +func (e *Encoder) AvailableBuffer() []byte { + // NOTE: We don't return e.buf[len(e.buf):cap(e.buf)] since WriteValue would + // need to take special care to avoid mangling the data while reformatting. + // WriteValue can't easily identify whether the input Value aliases e.buf + // without using unsafe.Pointer. Thus, we just return a different buffer. + // Should this ever alias e.buf, we need to consider how it operates with + // the specialized performance optimization for bytes.Buffer. + n := 1 << bits.Len(uint(e.s.maxValue|63)) // fast approximation for max length + if cap(e.s.availBuffer) < n { + e.s.availBuffer = make([]byte, 0, n) + } + return e.s.availBuffer +} + +// StackDepth returns the depth of the state machine for written JSON data. +// Each level on the stack represents a nested JSON object or array. +// It is incremented whenever an [BeginObject] or [BeginArray] token is encountered +// and decremented whenever an [EndObject] or [EndArray] token is encountered. +// The depth is zero-indexed, where zero represents the top-level JSON value. +func (e *Encoder) StackDepth() int { + // NOTE: Keep in sync with Decoder.StackDepth. + return e.s.Tokens.Depth() - 1 +} + +// StackIndex returns information about the specified stack level. +// It must be a number between 0 and [Encoder.StackDepth], inclusive. +// For each level, it reports the kind: +// +// - 0 for a level of zero, +// - '{' for a level representing a JSON object, and +// - '[' for a level representing a JSON array. +// +// It also reports the length of that JSON object or array. +// Each name and value in a JSON object is counted separately, +// so the effective number of members would be half the length. +// A complete JSON object must have an even length. +func (e *Encoder) StackIndex(i int) (Kind, int64) { + // NOTE: Keep in sync with Decoder.StackIndex. + switch s := e.s.Tokens.index(i); { + case i > 0 && s.isObject(): + return '{', s.Length() + case i > 0 && s.isArray(): + return '[', s.Length() + default: + return 0, s.Length() + } +} + +// StackPointer returns a JSON Pointer (RFC 6901) to the most recently written value. +func (e *Encoder) StackPointer() Pointer { + return Pointer(e.s.AppendStackPointer(nil, -1)) +} + +func (e *encoderState) AppendStackPointer(b []byte, where int) []byte { + e.Names.copyQuotedBuffer(e.Buf) + return e.state.appendStackPointer(b, where) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go new file mode 100644 index 00000000..1af86d5b --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/errors.go @@ -0,0 +1,180 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsontext + +import ( + "bytes" + "io" + "strconv" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" +) + +const errorPrefix = "jsontext: " + +type ioError struct { + action string // either "read" or "write" + err error +} + +func (e *ioError) Error() string { + return errorPrefix + e.action + " error: " + e.err.Error() +} +func (e *ioError) Unwrap() error { + return e.err +} + +// SyntacticError is a description of a syntactic error that occurred when +// encoding or decoding JSON according to the grammar. +// +// The contents of this error as produced by this package may change over time. +type SyntacticError struct { + requireKeyedLiterals + nonComparable + + // ByteOffset indicates that an error occurred after this byte offset. + ByteOffset int64 + // JSONPointer indicates that an error occurred within this JSON value + // as indicated using the JSON Pointer notation (see RFC 6901). + JSONPointer Pointer + + // Err is the underlying error. + Err error +} + +// wrapSyntacticError wraps an error and annotates it with a precise location +// using the provided [encoderState] or [decoderState]. +// If err is an [ioError] or [io.EOF], then it is not wrapped. +// +// It takes a relative offset pos that can be resolved into +// an absolute offset using state.offsetAt. +// +// It takes a where that specify how the JSON pointer is derived. +// If the underlying error is a [pointerSuffixError], +// then the suffix is appended to the derived pointer. +func wrapSyntacticError(state interface { + offsetAt(pos int) int64 + AppendStackPointer(b []byte, where int) []byte +}, err error, pos, where int) error { + if _, ok := err.(*ioError); err == io.EOF || ok { + return err + } + offset := state.offsetAt(pos) + ptr := state.AppendStackPointer(nil, where) + if serr, ok := err.(*pointerSuffixError); ok { + ptr = serr.appendPointer(ptr) + err = serr.error + } + if d, ok := state.(*decoderState); ok && err == errMismatchDelim { + where := "at start of value" + if len(d.Tokens.Stack) > 0 && d.Tokens.Last.Length() > 0 { + switch { + case d.Tokens.Last.isArray(): + where = "after array element (expecting ',' or ']')" + ptr = []byte(Pointer(ptr).Parent()) // problem is with parent array + case d.Tokens.Last.isObject(): + where = "after object value (expecting ',' or '}')" + ptr = []byte(Pointer(ptr).Parent()) // problem is with parent object + } + } + err = jsonwire.NewInvalidCharacterError(d.buf[pos:], where) + } + return &SyntacticError{ByteOffset: offset, JSONPointer: Pointer(ptr), Err: err} +} + +func (e *SyntacticError) Error() string { + pointer := e.JSONPointer + offset := e.ByteOffset + b := []byte(errorPrefix) + if e.Err != nil { + b = append(b, e.Err.Error()...) + if e.Err == ErrDuplicateName { + b = strconv.AppendQuote(append(b, ' '), pointer.LastToken()) + pointer = pointer.Parent() + offset = 0 // not useful to print offset for duplicate names + } + } else { + b = append(b, "syntactic error"...) + } + if pointer != "" { + b = strconv.AppendQuote(append(b, " within "...), jsonwire.TruncatePointer(string(pointer), 100)) + } + if offset > 0 { + b = strconv.AppendInt(append(b, " after offset "...), offset, 10) + } + return string(b) +} + +func (e *SyntacticError) Unwrap() error { + return e.Err +} + +// pointerSuffixError represents a JSON pointer suffix to be appended +// to [SyntacticError.JSONPointer]. It is an internal error type +// used within this package and does not appear in the public API. +// +// This type is primarily used to annotate errors in Encoder.WriteValue +// and Decoder.ReadValue with precise positions. +// At the time WriteValue or ReadValue is called, a JSON pointer to the +// upcoming value can be constructed using the Encoder/Decoder state. +// However, tracking pointers within values during normal operation +// would incur a performance penalty in the error-free case. +// +// To provide precise error locations without this overhead, +// the error is wrapped with object names or array indices +// as the call stack is popped when an error occurs. +// Since this happens in reverse order, pointerSuffixError holds +// the pointer in reverse and is only later reversed when appending to +// the pointer prefix. +// +// For example, if the encoder is at "/alpha/bravo/charlie" +// and an error occurs in WriteValue at "/xray/yankee/zulu", then +// the final pointer should be "/alpha/bravo/charlie/xray/yankee/zulu". +// +// As pointerSuffixError is populated during the error return path, +// it first contains "/zulu", then "/zulu/yankee", +// and finally "/zulu/yankee/xray". +// These tokens are reversed and concatenated to "/alpha/bravo/charlie" +// to form the full pointer. +type pointerSuffixError struct { + error + + // reversePointer is a JSON pointer, but with each token in reverse order. + reversePointer []byte +} + +// wrapWithObjectName wraps err with a JSON object name access, +// which must be a valid quoted JSON string. +func wrapWithObjectName(err error, quotedName []byte) error { + serr, _ := err.(*pointerSuffixError) + if serr == nil { + serr = &pointerSuffixError{error: err} + } + name := jsonwire.UnquoteMayCopy(quotedName, false) + serr.reversePointer = appendEscapePointerName(append(serr.reversePointer, '/'), name) + return serr +} + +// wrapWithArrayIndex wraps err with a JSON array index access. +func wrapWithArrayIndex(err error, index int64) error { + serr, _ := err.(*pointerSuffixError) + if serr == nil { + serr = &pointerSuffixError{error: err} + } + serr.reversePointer = strconv.AppendUint(append(serr.reversePointer, '/'), uint64(index), 10) + return serr +} + +// appendPointer appends the path encoded in e to the end of pointer. +func (e *pointerSuffixError) appendPointer(pointer []byte) []byte { + // Copy each token in reversePointer to the end of pointer in reverse order. + // Double reversal means that the appended suffix is now in forward order. + bi, bo := e.reversePointer, pointer + for len(bi) > 0 { + i := bytes.LastIndexByte(bi, '/') + bi, bo = bi[:i], append(bo, bi[i:]...) + } + return bo +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go new file mode 100644 index 00000000..b30bb99e --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/export.go @@ -0,0 +1,75 @@ +// Copyright 2023 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 jsontext + +import ( + "io" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" +) + +// Internal is for internal use only. +// This is exempt from the Go compatibility agreement. +var Internal exporter + +type exporter struct{} + +// Export exposes internal functionality from "jsontext" to "json". +// This cannot be dynamically called by other packages since +// they cannot obtain a reference to the internal.AllowInternalUse value. +func (exporter) Export(p *internal.NotForPublicUse) export { + if p != &internal.AllowInternalUse { + panic("unauthorized call to Export") + } + return export{} +} + +// The export type exposes functionality to packages with visibility to +// the internal.AllowInternalUse variable. The "json" package uses this +// to modify low-level state in the Encoder and Decoder types. +// It mutates the state directly instead of calling ReadToken or WriteToken +// since this is more performant. The public APIs need to track state to ensure +// that users are constructing a valid JSON value, but the "json" implementation +// guarantees that it emits valid JSON by the structure of the code itself. +type export struct{} + +// Encoder returns a pointer to the underlying encoderState. +func (export) Encoder(e *Encoder) *encoderState { return &e.s } + +// Decoder returns a pointer to the underlying decoderState. +func (export) Decoder(d *Decoder) *decoderState { return &d.s } + +func (export) GetBufferedEncoder(o ...Options) *Encoder { + return getBufferedEncoder(o...) +} +func (export) PutBufferedEncoder(e *Encoder) { + putBufferedEncoder(e) +} + +func (export) GetStreamingEncoder(w io.Writer, o ...Options) *Encoder { + return getStreamingEncoder(w, o...) +} +func (export) PutStreamingEncoder(e *Encoder) { + putStreamingEncoder(e) +} + +func (export) GetBufferedDecoder(b []byte, o ...Options) *Decoder { + return getBufferedDecoder(b, o...) +} +func (export) PutBufferedDecoder(d *Decoder) { + putBufferedDecoder(d) +} + +func (export) GetStreamingDecoder(r io.Reader, o ...Options) *Decoder { + return getStreamingDecoder(r, o...) +} +func (export) PutStreamingDecoder(d *Decoder) { + putStreamingDecoder(d) +} + +func (export) IsIOError(err error) bool { + _, ok := err.(*ioError) + return ok +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go new file mode 100644 index 00000000..e973b58d --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/options.go @@ -0,0 +1,302 @@ +// Copyright 2023 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 jsontext + +import ( + "strings" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" +) + +// Options configures [NewEncoder], [Encoder.Reset], [NewDecoder], +// and [Decoder.Reset] with specific features. +// Each function takes in a variadic list of options, where properties +// set in latter options override the value of previously set properties. +// +// There is a single Options type, which is used with both encoding and decoding. +// Some options affect both operations, while others only affect one operation: +// +// - [AllowDuplicateNames] affects encoding and decoding +// - [AllowInvalidUTF8] affects encoding and decoding +// - [EscapeForHTML] affects encoding only +// - [EscapeForJS] affects encoding only +// - [PreserveRawStrings] affects encoding only +// - [CanonicalizeRawInts] affects encoding only +// - [CanonicalizeRawFloats] affects encoding only +// - [ReorderRawObjects] affects encoding only +// - [SpaceAfterColon] affects encoding only +// - [SpaceAfterComma] affects encoding only +// - [Multiline] affects encoding only +// - [WithIndent] affects encoding only +// - [WithIndentPrefix] affects encoding only +// +// Options that do not affect a particular operation are ignored. +// +// The Options type is identical to [encoding/json.Options] and +// [encoding/json/v2.Options]. Options from the other packages may +// be passed to functionality in this package, but are ignored. +// Options from this package may be used with the other packages. +type Options = jsonopts.Options + +// AllowDuplicateNames specifies that JSON objects may contain +// duplicate member names. Disabling the duplicate name check may provide +// performance benefits, but breaks compliance with RFC 7493, section 2.3. +// The input or output will still be compliant with RFC 8259, +// which leaves the handling of duplicate names as unspecified behavior. +// +// This affects either encoding or decoding. +func AllowDuplicateNames(v bool) Options { + if v { + return jsonflags.AllowDuplicateNames | 1 + } else { + return jsonflags.AllowDuplicateNames | 0 + } +} + +// AllowInvalidUTF8 specifies that JSON strings may contain invalid UTF-8, +// which will be mangled as the Unicode replacement character, U+FFFD. +// This causes the encoder or decoder to break compliance with +// RFC 7493, section 2.1, and RFC 8259, section 8.1. +// +// This affects either encoding or decoding. +func AllowInvalidUTF8(v bool) Options { + if v { + return jsonflags.AllowInvalidUTF8 | 1 + } else { + return jsonflags.AllowInvalidUTF8 | 0 + } +} + +// EscapeForHTML specifies that '<', '>', and '&' characters within JSON strings +// should be escaped as a hexadecimal Unicode codepoint (e.g., \u003c) so that +// the output is safe to embed within HTML. +// +// This only affects encoding and is ignored when decoding. +func EscapeForHTML(v bool) Options { + if v { + return jsonflags.EscapeForHTML | 1 + } else { + return jsonflags.EscapeForHTML | 0 + } +} + +// EscapeForJS specifies that U+2028 and U+2029 characters within JSON strings +// should be escaped as a hexadecimal Unicode codepoint (e.g., \u2028) so that +// the output is valid to embed within JavaScript. See RFC 8259, section 12. +// +// This only affects encoding and is ignored when decoding. +func EscapeForJS(v bool) Options { + if v { + return jsonflags.EscapeForJS | 1 + } else { + return jsonflags.EscapeForJS | 0 + } +} + +// PreserveRawStrings specifies that when encoding a raw JSON string in a +// [Token] or [Value], pre-escaped sequences +// in a JSON string are preserved to the output. +// However, raw strings still respect [EscapeForHTML] and [EscapeForJS] +// such that the relevant characters are escaped. +// If [AllowInvalidUTF8] is enabled, bytes of invalid UTF-8 +// are preserved to the output. +// +// This only affects encoding and is ignored when decoding. +func PreserveRawStrings(v bool) Options { + if v { + return jsonflags.PreserveRawStrings | 1 + } else { + return jsonflags.PreserveRawStrings | 0 + } +} + +// CanonicalizeRawInts specifies that when encoding a raw JSON +// integer number (i.e., a number without a fraction and exponent) in a +// [Token] or [Value], the number is canonicalized +// according to RFC 8785, section 3.2.2.3. As a special case, +// the number -0 is canonicalized as 0. +// +// JSON numbers are treated as IEEE 754 double precision numbers. +// Any numbers with precision beyond what is representable by that form +// will lose their precision when canonicalized. For example, +// integer values beyond ±2⁵³ will lose their precision. +// For example, 1234567890123456789 is formatted as 1234567890123456800. +// +// This only affects encoding and is ignored when decoding. +func CanonicalizeRawInts(v bool) Options { + if v { + return jsonflags.CanonicalizeRawInts | 1 + } else { + return jsonflags.CanonicalizeRawInts | 0 + } +} + +// CanonicalizeRawFloats specifies that when encoding a raw JSON +// floating-point number (i.e., a number with a fraction or exponent) in a +// [Token] or [Value], the number is canonicalized +// according to RFC 8785, section 3.2.2.3. As a special case, +// the number -0 is canonicalized as 0. +// +// JSON numbers are treated as IEEE 754 double precision numbers. +// It is safe to canonicalize a serialized single precision number and +// parse it back as a single precision number and expect the same value. +// If a number exceeds ±1.7976931348623157e+308, which is the maximum +// finite number, then it saturated at that value and formatted as such. +// +// This only affects encoding and is ignored when decoding. +func CanonicalizeRawFloats(v bool) Options { + if v { + return jsonflags.CanonicalizeRawFloats | 1 + } else { + return jsonflags.CanonicalizeRawFloats | 0 + } +} + +// ReorderRawObjects specifies that when encoding a raw JSON object in a +// [Value], the object members are reordered according to +// RFC 8785, section 3.2.3. +// +// This only affects encoding and is ignored when decoding. +func ReorderRawObjects(v bool) Options { + if v { + return jsonflags.ReorderRawObjects | 1 + } else { + return jsonflags.ReorderRawObjects | 0 + } +} + +// SpaceAfterColon specifies that the JSON output should emit a space character +// after each colon separator following a JSON object name. +// If false, then no space character appears after the colon separator. +// +// This only affects encoding and is ignored when decoding. +func SpaceAfterColon(v bool) Options { + if v { + return jsonflags.SpaceAfterColon | 1 + } else { + return jsonflags.SpaceAfterColon | 0 + } +} + +// SpaceAfterComma specifies that the JSON output should emit a space character +// after each comma separator following a JSON object value or array element. +// If false, then no space character appears after the comma separator. +// +// This only affects encoding and is ignored when decoding. +func SpaceAfterComma(v bool) Options { + if v { + return jsonflags.SpaceAfterComma | 1 + } else { + return jsonflags.SpaceAfterComma | 0 + } +} + +// Multiline specifies that the JSON output should expand to multiple lines, +// where every JSON object member or JSON array element appears on +// a new, indented line according to the nesting depth. +// +// If [SpaceAfterColon] is not specified, then the default is true. +// If [SpaceAfterComma] is not specified, then the default is false. +// If [WithIndent] is not specified, then the default is "\t". +// +// If set to false, then the output is a single-line, +// where the only whitespace emitted is determined by the current +// values of [SpaceAfterColon] and [SpaceAfterComma]. +// +// This only affects encoding and is ignored when decoding. +func Multiline(v bool) Options { + if v { + return jsonflags.Multiline | 1 + } else { + return jsonflags.Multiline | 0 + } +} + +// WithIndent specifies that the encoder should emit multiline output +// where each element in a JSON object or array begins on a new, indented line +// beginning with the indent prefix (see [WithIndentPrefix]) +// followed by one or more copies of indent according to the nesting depth. +// The indent must only be composed of space or tab characters. +// +// If the intent to emit indented output without a preference for +// the particular indent string, then use [Multiline] instead. +// +// This only affects encoding and is ignored when decoding. +// Use of this option implies [Multiline] being set to true. +func WithIndent(indent string) Options { + // Fast-path: Return a constant for common indents, which avoids allocating. + // These are derived from analyzing the Go module proxy on 2023-07-01. + switch indent { + case "\t": + return jsonopts.Indent("\t") // ~14k usages + case " ": + return jsonopts.Indent(" ") // ~18k usages + case " ": + return jsonopts.Indent(" ") // ~1.7k usages + case " ": + return jsonopts.Indent(" ") // ~52k usages + case " ": + return jsonopts.Indent(" ") // ~12k usages + case "": + return jsonopts.Indent("") // ~1.5k usages + } + + // Otherwise, allocate for this unique value. + if s := strings.Trim(indent, " \t"); len(s) > 0 { + panic("json: invalid character " + jsonwire.QuoteRune(s) + " in indent") + } + return jsonopts.Indent(indent) +} + +// WithIndentPrefix specifies that the encoder should emit multiline output +// where each element in a JSON object or array begins on a new, indented line +// beginning with the indent prefix followed by one or more copies of indent +// (see [WithIndent]) according to the nesting depth. +// The prefix must only be composed of space or tab characters. +// +// This only affects encoding and is ignored when decoding. +// Use of this option implies [Multiline] being set to true. +func WithIndentPrefix(prefix string) Options { + if s := strings.Trim(prefix, " \t"); len(s) > 0 { + panic("json: invalid character " + jsonwire.QuoteRune(s) + " in indent prefix") + } + return jsonopts.IndentPrefix(prefix) +} + +/* +// TODO(https://go.dev/issue/56733): Implement WithByteLimit and WithDepthLimit. +// Remember to also update the "Security Considerations" section. + +// WithByteLimit sets a limit on the number of bytes of input or output bytes +// that may be consumed or produced for each top-level JSON value. +// If a [Decoder] or [Encoder] method call would need to consume/produce +// more than a total of n bytes to make progress on the top-level JSON value, +// then the call will report an error. +// Whitespace before and within the top-level value are counted against the limit. +// Whitespace after a top-level value are counted against the limit +// for the next top-level value. +// +// A non-positive limit is equivalent to no limit at all. +// If unspecified, the default limit is no limit at all. +// This affects either encoding or decoding. +func WithByteLimit(n int64) Options { + return jsonopts.ByteLimit(max(n, 0)) +} + +// WithDepthLimit sets a limit on the maximum depth of JSON nesting +// that may be consumed or produced for each top-level JSON value. +// If a [Decoder] or [Encoder] method call would need to consume or produce +// a depth greater than n to make progress on the top-level JSON value, +// then the call will report an error. +// +// A non-positive limit is equivalent to no limit at all. +// If unspecified, the default limit is 10000. +// This affects either encoding or decoding. +func WithDepthLimit(n int) Options { + return jsonopts.DepthLimit(max(n, 0)) +} +*/ diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/pools.go similarity index 64% rename from vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go rename to vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/pools.go index 60e93270..63941baa 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/pools.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package json +package jsontext import ( "bytes" "io" "math/bits" - "sort" "sync" ) @@ -40,16 +39,16 @@ type bufferStatistics struct { prevLen int // length of previous buffer } -func getBufferedEncoder(o EncodeOptions) *Encoder { +func getBufferedEncoder(opts ...Options) *Encoder { e := bufferedEncoderPool.Get().(*Encoder) - if e.buf == nil { + if e.s.Buf == nil { // Round up to nearest 2ⁿ to make best use of malloc size classes. // See runtime/sizeclasses.go on Go1.15. // Logical OR with 63 to ensure 64 as the minimum buffer size. - n := 1 << bits.Len(uint(e.bufStats.prevLen|63)) - e.buf = make([]byte, 0, n) + n := 1 << bits.Len(uint(e.s.bufStats.prevLen|63)) + e.s.Buf = make([]byte, 0, n) } - e.reset(e.buf[:0], nil, o) + e.s.reset(e.s.Buf[:0], nil, opts...) return e } func putBufferedEncoder(e *Encoder) { @@ -68,37 +67,37 @@ func putBufferedEncoder(e *Encoder) { // // See https://go.dev/issue/27735. switch { - case cap(e.buf) <= 4<<10: // always recycle buffers smaller than 4KiB - e.bufStats.strikes = 0 - case cap(e.buf)/4 <= len(e.buf): // at least 25% utilization - e.bufStats.strikes = 0 - case e.bufStats.strikes < 4: // at most 4 strikes - e.bufStats.strikes++ + case cap(e.s.Buf) <= 4<<10: // always recycle buffers smaller than 4KiB + e.s.bufStats.strikes = 0 + case cap(e.s.Buf)/4 <= len(e.s.Buf): // at least 25% utilization + e.s.bufStats.strikes = 0 + case e.s.bufStats.strikes < 4: // at most 4 strikes + e.s.bufStats.strikes++ default: // discard the buffer; too large and too often under-utilized - e.bufStats.strikes = 0 - e.bufStats.prevLen = len(e.buf) // heuristic for size to allocate next time - e.buf = nil + e.s.bufStats.strikes = 0 + e.s.bufStats.prevLen = len(e.s.Buf) // heuristic for size to allocate next time + e.s.Buf = nil } bufferedEncoderPool.Put(e) } -func getStreamingEncoder(w io.Writer, o EncodeOptions) *Encoder { +func getStreamingEncoder(w io.Writer, opts ...Options) *Encoder { if _, ok := w.(*bytes.Buffer); ok { e := bytesBufferEncoderPool.Get().(*Encoder) - e.reset(nil, w, o) // buffer taken from bytes.Buffer + e.s.reset(nil, w, opts...) // buffer taken from bytes.Buffer return e } else { e := streamingEncoderPool.Get().(*Encoder) - e.reset(e.buf[:0], w, o) // preserve existing buffer + e.s.reset(e.s.Buf[:0], w, opts...) // preserve existing buffer return e } } func putStreamingEncoder(e *Encoder) { - if _, ok := e.wr.(*bytes.Buffer); ok { + if _, ok := e.s.wr.(*bytes.Buffer); ok { bytesBufferEncoderPool.Put(e) } else { - if cap(e.buf) > 64<<10 { - e.buf = nil // avoid pinning arbitrarily large amounts of memory + if cap(e.s.Buf) > 64<<10 { + e.s.Buf = nil // avoid pinning arbitrarily large amounts of memory } streamingEncoderPool.Put(e) } @@ -119,64 +118,33 @@ var ( bytesBufferDecoderPool = bufferedDecoderPool ) -func getBufferedDecoder(b []byte, o DecodeOptions) *Decoder { +func getBufferedDecoder(b []byte, opts ...Options) *Decoder { d := bufferedDecoderPool.Get().(*Decoder) - d.reset(b, nil, o) + d.s.reset(b, nil, opts...) return d } func putBufferedDecoder(d *Decoder) { bufferedDecoderPool.Put(d) } -func getStreamingDecoder(r io.Reader, o DecodeOptions) *Decoder { +func getStreamingDecoder(r io.Reader, opts ...Options) *Decoder { if _, ok := r.(*bytes.Buffer); ok { d := bytesBufferDecoderPool.Get().(*Decoder) - d.reset(nil, r, o) // buffer taken from bytes.Buffer + d.s.reset(nil, r, opts...) // buffer taken from bytes.Buffer return d } else { d := streamingDecoderPool.Get().(*Decoder) - d.reset(d.buf[:0], r, o) // preserve existing buffer + d.s.reset(d.s.buf[:0], r, opts...) // preserve existing buffer return d } } func putStreamingDecoder(d *Decoder) { - if _, ok := d.rd.(*bytes.Buffer); ok { + if _, ok := d.s.rd.(*bytes.Buffer); ok { bytesBufferDecoderPool.Put(d) } else { - if cap(d.buf) > 64<<10 { - d.buf = nil // avoid pinning arbitrarily large amounts of memory + if cap(d.s.buf) > 64<<10 { + d.s.buf = nil // avoid pinning arbitrarily large amounts of memory } streamingDecoderPool.Put(d) } } - -var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }} - -type stringSlice []string - -// getStrings returns a non-nil pointer to a slice with length n. -func getStrings(n int) *stringSlice { - s := stringsPools.Get().(*stringSlice) - if cap(*s) < n { - *s = make([]string, n) - } - *s = (*s)[:n] - return s -} - -func putStrings(s *stringSlice) { - if cap(*s) > 1<<10 { - *s = nil // avoid pinning arbitrarily large amounts of memory - } - stringsPools.Put(s) -} - -// Sort sorts the string slice according to RFC 8785, section 3.2.3. -func (ss *stringSlice) Sort() { - // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. - sort.Sort(ss) -} - -func (ss *stringSlice) Len() int { return len(*ss) } -func (ss *stringSlice) Less(i, j int) bool { return lessUTF16((*ss)[i], (*ss)[j]) } -func (ss *stringSlice) Swap(i, j int) { (*ss)[i], (*ss)[j] = (*ss)[j], (*ss)[i] } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go new file mode 100644 index 00000000..77897b43 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/quote.go @@ -0,0 +1,39 @@ +// Copyright 2023 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 jsontext + +import ( + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" +) + +// AppendQuote appends a double-quoted JSON string literal representing src +// to dst and returns the extended buffer. +// It uses the minimal string representation per RFC 8785, section 3.2.2.2. +// Invalid UTF-8 bytes are replaced with the Unicode replacement character +// and an error is returned at the end indicating the presence of invalid UTF-8. +// The dst must not overlap with the src. +func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) { + dst, err := jsonwire.AppendQuote(dst, src, &jsonflags.Flags{}) + if err != nil { + err = &SyntacticError{Err: err} + } + return dst, err +} + +// AppendUnquote appends the decoded interpretation of src as a +// double-quoted JSON string literal to dst and returns the extended buffer. +// The input src must be a JSON string without any surrounding whitespace. +// Invalid UTF-8 bytes are replaced with the Unicode replacement character +// and an error is returned at the end indicating the presence of invalid UTF-8. +// Any trailing bytes after the JSON string literal results in an error. +// The dst must not overlap with the src. +func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) { + dst, err := jsonwire.AppendUnquote(dst, src) + if err != nil { + err = &SyntacticError{Err: err} + } + return dst, err +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/state.go similarity index 63% rename from vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go rename to vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/state.go index ee14c753..fdbfd5d3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/state.go @@ -2,81 +2,214 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package json +package jsontext import ( + "errors" + "iter" "math" "strconv" + "strings" + "unicode/utf8" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" ) +// ErrDuplicateName indicates that a JSON token could not be +// encoded or decoded because it results in a duplicate JSON object name. +// This error is directly wrapped within a [SyntacticError] when produced. +// +// The name of a duplicate JSON object member can be extracted as: +// +// err := ... +// var serr jsontext.SyntacticError +// if errors.As(err, &serr) && serr.Err == jsontext.ErrDuplicateName { +// ptr := serr.JSONPointer // JSON pointer to duplicate name +// name := ptr.LastToken() // duplicate name itself +// ... +// } +// +// This error is only returned if [AllowDuplicateNames] is false. +var ErrDuplicateName = errors.New("duplicate object member name") + +// ErrNonStringName indicates that a JSON token could not be +// encoded or decoded because it is not a string, +// as required for JSON object names according to RFC 8259, section 4. +// This error is directly wrapped within a [SyntacticError] when produced. +var ErrNonStringName = errors.New("object member name must be a string") + var ( - errMissingName = &SyntacticError{str: "missing string for object name"} - errMissingColon = &SyntacticError{str: "missing character ':' after object name"} - errMissingValue = &SyntacticError{str: "missing value after object name"} - errMissingComma = &SyntacticError{str: "missing character ',' after object or array value"} - errMismatchDelim = &SyntacticError{str: "mismatching structural token for object or array"} + errMissingValue = errors.New("missing value after object name") + errMismatchDelim = errors.New("mismatching structural token for object or array") + errMaxDepth = errors.New("exceeded max depth") + + errInvalidNamespace = errors.New("object namespace is in an invalid state") ) -const errInvalidNamespace = jsonError("object namespace is in an invalid state") +// Per RFC 8259, section 9, implementations may enforce a maximum depth. +// Such a limit is necessary to prevent stack overflows. +const maxNestingDepth = 10000 type state struct { - // tokens validates whether the next token kind is valid. - tokens stateMachine + // Tokens validates whether the next token kind is valid. + Tokens stateMachine - // names is a stack of object names. - // Not used if AllowDuplicateNames is true. - names objectNameStack + // Names is a stack of object names. + Names objectNameStack - // namespaces is a stack of object namespaces. + // Namespaces is a stack of object namespaces. // For performance reasons, Encoder or Decoder may not update this // if Marshal or Unmarshal is able to track names in a more efficient way. // See makeMapArshaler and makeStructArshaler. // Not used if AllowDuplicateNames is true. - namespaces objectNamespaceStack + Namespaces objectNamespaceStack +} + +// needObjectValue reports whether the next token should be an object value. +// This method is used by [wrapSyntacticError]. +func (s *state) needObjectValue() bool { + return s.Tokens.Last.needObjectValue() } func (s *state) reset() { - s.tokens.reset() - s.names.reset() - s.namespaces.reset() + s.Tokens.reset() + s.Names.reset() + s.Namespaces.reset() +} + +// Pointer is a JSON Pointer (RFC 6901) that references a particular JSON value +// relative to the root of the top-level JSON value. +// +// A Pointer is a slash-separated list of tokens, where each token is +// either a JSON object name or an index to a JSON array element +// encoded as a base-10 integer value. +// It is impossible to distinguish between an array index and an object name +// (that happens to be an base-10 encoded integer) without also knowing +// the structure of the top-level JSON value that the pointer refers to. +// +// There is exactly one representation of a pointer to a particular value, +// so comparability of Pointer values is equivalent to checking whether +// they both point to the exact same value. +type Pointer string + +// IsValid reports whether p is a valid JSON Pointer according to RFC 6901. +// Note that the concatenation of two valid pointers produces a valid pointer. +func (p Pointer) IsValid() bool { + for i, r := range p { + switch { + case r == '~' && (i+1 == len(p) || (p[i+1] != '0' && p[i+1] != '1')): + return false // invalid escape + case r == '\ufffd' && !strings.HasPrefix(string(p[i:]), "\ufffd"): + return false // invalid UTF-8 + } + } + return len(p) == 0 || p[0] == '/' +} + +// Contains reports whether the JSON value that p points to +// is equal to or contains the JSON value that pc points to. +func (p Pointer) Contains(pc Pointer) bool { + // Invariant: len(p) <= len(pc) if p.Contains(pc) + suffix, ok := strings.CutPrefix(string(pc), string(p)) + return ok && (suffix == "" || suffix[0] == '/') +} + +// Parent strips off the last token and returns the remaining pointer. +// The parent of an empty p is an empty string. +func (p Pointer) Parent() Pointer { + return p[:max(strings.LastIndexByte(string(p), '/'), 0)] +} + +// LastToken returns the last token in the pointer. +// The last token of an empty p is an empty string. +func (p Pointer) LastToken() string { + last := p[max(strings.LastIndexByte(string(p), '/'), 0):] + return unescapePointerToken(strings.TrimPrefix(string(last), "/")) +} + +// AppendToken appends a token to the end of p and returns the full pointer. +func (p Pointer) AppendToken(tok string) Pointer { + return Pointer(appendEscapePointerName([]byte(p+"/"), tok)) +} + +// TODO: Add Pointer.AppendTokens, +// but should this take in a ...string or an iter.Seq[string]? + +// Tokens returns an iterator over the reference tokens in the JSON pointer, +// starting from the first token until the last token (unless stopped early). +func (p Pointer) Tokens() iter.Seq[string] { + return func(yield func(string) bool) { + for len(p) > 0 { + p = Pointer(strings.TrimPrefix(string(p), "/")) + i := min(uint(strings.IndexByte(string(p), '/')), uint(len(p))) + if !yield(unescapePointerToken(string(p)[:i])) { + return + } + p = p[i:] + } + } +} + +func unescapePointerToken(token string) string { + if strings.Contains(token, "~") { + // Per RFC 6901, section 3, unescape '~' and '/' characters. + token = strings.ReplaceAll(token, "~1", "/") + token = strings.ReplaceAll(token, "~0", "~") + } + return token } // appendStackPointer appends a JSON Pointer (RFC 6901) to the current value. -// The returned pointer is only accurate if s.names is populated, -// otherwise it uses the numeric index as the object member name. +// +// - If where is -1, then it points to the previously processed token. +// +// - If where is 0, then it points to the parent JSON object or array, +// or an object member if in-between an object member key and value. +// This is useful when the position is ambiguous whether +// we are interested in the previous or next token, or +// when we are uncertain whether the next token +// continues or terminates the current object or array. +// +// - If where is +1, then it points to the next expected value, +// assuming that it continues the current JSON object or array. +// As a special case, if the next token is a JSON object name, +// then it points to the parent JSON object. // // Invariant: Must call s.names.copyQuotedBuffer beforehand. -func (s state) appendStackPointer(b []byte) []byte { +func (s state) appendStackPointer(b []byte, where int) []byte { var objectDepth int - for i := 1; i < s.tokens.depth(); i++ { - e := s.tokens.index(i) - if e.length() == 0 { - break // empty object or array + for i := 1; i < s.Tokens.Depth(); i++ { + e := s.Tokens.index(i) + arrayDelta := -1 // by default point to previous array element + if isLast := i == s.Tokens.Depth()-1; isLast { + switch { + case where < 0 && e.Length() == 0 || where == 0 && !e.needObjectValue() || where > 0 && e.NeedObjectName(): + return b + case where > 0 && e.isArray(): + arrayDelta = 0 // point to next array element + } } - b = append(b, '/') switch { case e.isObject(): - if objectDepth < s.names.length() { - for _, c := range s.names.getUnquoted(objectDepth) { - // Per RFC 6901, section 3, escape '~' and '/' characters. - switch c { - case '~': - b = append(b, "~0"...) - case '/': - b = append(b, "~1"...) - default: - b = append(b, c) - } - } - } else { - // Since the names stack is unpopulated, the name is unknown. - // As a best-effort replacement, use the numeric member index. - // While inaccurate, it produces a syntactically valid pointer. - b = strconv.AppendUint(b, uint64((e.length()-1)/2), 10) - } + b = appendEscapePointerName(append(b, '/'), s.Names.getUnquoted(objectDepth)) objectDepth++ case e.isArray(): - b = strconv.AppendUint(b, uint64(e.length()-1), 10) + b = strconv.AppendUint(append(b, '/'), uint64(e.Length()+int64(arrayDelta)), 10) + } + } + return b +} + +func appendEscapePointerName[Bytes ~[]byte | ~string](b []byte, name Bytes) []byte { + for _, r := range string(name) { + // Per RFC 6901, section 3, escape '~' and '/' characters. + switch r { + case '~': + b = append(b, "~0"...) + case '/': + b = append(b, "~1"...) + default: + b = utf8.AppendRune(b, r) } } return b @@ -92,54 +225,54 @@ func (s state) appendStackPointer(b []byte) []byte { // The top-level virtual JSON array is special in that it doesn't require commas // between each JSON value. // -// For performance, most methods are carefully written to be inlineable. +// For performance, most methods are carefully written to be inlinable. // The zero value is a valid state machine ready for use. type stateMachine struct { - stack []stateEntry - last stateEntry + Stack []stateEntry + Last stateEntry } // reset resets the state machine. // The machine always starts with a minimum depth of 1. func (m *stateMachine) reset() { - m.stack = m.stack[:0] - if cap(m.stack) > 1<<10 { - m.stack = nil + m.Stack = m.Stack[:0] + if cap(m.Stack) > 1<<10 { + m.Stack = nil } - m.last = stateTypeArray + m.Last = stateTypeArray } -// depth is the current nested depth of JSON objects and arrays. +// Depth is the current nested depth of JSON objects and arrays. // It is one-indexed (i.e., top-level values have a depth of 1). -func (m stateMachine) depth() int { - return len(m.stack) + 1 +func (m stateMachine) Depth() int { + return len(m.Stack) + 1 } // index returns a reference to the ith entry. // It is only valid until the next push method call. func (m *stateMachine) index(i int) *stateEntry { - if i == len(m.stack) { - return &m.last + if i == len(m.Stack) { + return &m.Last } - return &m.stack[i] + return &m.Stack[i] } -// depthLength reports the current nested depth and +// DepthLength reports the current nested depth and // the length of the last JSON object or array. -func (m stateMachine) depthLength() (int, int) { - return m.depth(), m.last.length() +func (m stateMachine) DepthLength() (int, int64) { + return m.Depth(), m.Last.Length() } // appendLiteral appends a JSON literal as the next token in the sequence. // If an error is returned, the state is not mutated. func (m *stateMachine) appendLiteral() error { switch { - case m.last.needObjectName(): - return errMissingName - case !m.last.isValidNamespace(): + case m.Last.NeedObjectName(): + return ErrNonStringName + case !m.Last.isValidNamespace(): return errInvalidNamespace default: - m.last.increment() + m.Last.Increment() return nil } } @@ -148,10 +281,10 @@ func (m *stateMachine) appendLiteral() error { // If an error is returned, the state is not mutated. func (m *stateMachine) appendString() error { switch { - case !m.last.isValidNamespace(): + case !m.Last.isValidNamespace(): return errInvalidNamespace default: - m.last.increment() + m.Last.Increment() return nil } } @@ -162,18 +295,20 @@ func (m *stateMachine) appendNumber() error { return m.appendLiteral() } -// pushObject appends a JSON start object token as next in the sequence. +// pushObject appends a JSON begin object token as next in the sequence. // If an error is returned, the state is not mutated. func (m *stateMachine) pushObject() error { switch { - case m.last.needObjectName(): - return errMissingName - case !m.last.isValidNamespace(): + case m.Last.NeedObjectName(): + return ErrNonStringName + case !m.Last.isValidNamespace(): return errInvalidNamespace + case len(m.Stack) == maxNestingDepth: + return errMaxDepth default: - m.last.increment() - m.stack = append(m.stack, m.last) - m.last = stateTypeObject + m.Last.Increment() + m.Stack = append(m.Stack, m.Last) + m.Last = stateTypeObject return nil } } @@ -182,31 +317,33 @@ func (m *stateMachine) pushObject() error { // If an error is returned, the state is not mutated. func (m *stateMachine) popObject() error { switch { - case !m.last.isObject(): + case !m.Last.isObject(): return errMismatchDelim - case m.last.needObjectValue(): + case m.Last.needObjectValue(): return errMissingValue - case !m.last.isValidNamespace(): + case !m.Last.isValidNamespace(): return errInvalidNamespace default: - m.last = m.stack[len(m.stack)-1] - m.stack = m.stack[:len(m.stack)-1] + m.Last = m.Stack[len(m.Stack)-1] + m.Stack = m.Stack[:len(m.Stack)-1] return nil } } -// pushArray appends a JSON start array token as next in the sequence. +// pushArray appends a JSON begin array token as next in the sequence. // If an error is returned, the state is not mutated. func (m *stateMachine) pushArray() error { switch { - case m.last.needObjectName(): - return errMissingName - case !m.last.isValidNamespace(): + case m.Last.NeedObjectName(): + return ErrNonStringName + case !m.Last.isValidNamespace(): return errInvalidNamespace + case len(m.Stack) == maxNestingDepth: + return errMaxDepth default: - m.last.increment() - m.stack = append(m.stack, m.last) - m.last = stateTypeArray + m.Last.Increment() + m.Stack = append(m.Stack, m.Last) + m.Last = stateTypeArray return nil } } @@ -215,43 +352,43 @@ func (m *stateMachine) pushArray() error { // If an error is returned, the state is not mutated. func (m *stateMachine) popArray() error { switch { - case !m.last.isArray() || len(m.stack) == 0: // forbid popping top-level virtual JSON array + case !m.Last.isArray() || len(m.Stack) == 0: // forbid popping top-level virtual JSON array return errMismatchDelim - case !m.last.isValidNamespace(): + case !m.Last.isValidNamespace(): return errInvalidNamespace default: - m.last = m.stack[len(m.stack)-1] - m.stack = m.stack[:len(m.stack)-1] + m.Last = m.Stack[len(m.Stack)-1] + m.Stack = m.Stack[:len(m.Stack)-1] return nil } } -// needIndent reports whether indent whitespace should be injected. +// NeedIndent reports whether indent whitespace should be injected. // A zero value means that no whitespace should be injected. // A positive value means '\n', indentPrefix, and (n-1) copies of indentBody // should be appended to the output immediately before the next token. -func (m stateMachine) needIndent(next Kind) (n int) { +func (m stateMachine) NeedIndent(next Kind) (n int) { willEnd := next == '}' || next == ']' switch { - case m.depth() == 1: + case m.Depth() == 1: return 0 // top-level values are never indented - case m.last.length() == 0 && willEnd: + case m.Last.Length() == 0 && willEnd: return 0 // an empty object or array is never indented - case m.last.length() == 0 || m.last.needImplicitComma(next): - return m.depth() + case m.Last.Length() == 0 || m.Last.needImplicitComma(next): + return m.Depth() case willEnd: - return m.depth() - 1 + return m.Depth() - 1 default: return 0 } } -// mayAppendDelim appends a colon or comma that may precede the next token. -func (m stateMachine) mayAppendDelim(b []byte, next Kind) []byte { +// MayAppendDelim appends a colon or comma that may precede the next token. +func (m stateMachine) MayAppendDelim(b []byte, next Kind) []byte { switch { - case m.last.needImplicitColon(): + case m.Last.needImplicitColon(): return append(b, ':') - case m.last.needImplicitComma(next) && len(m.stack) != 0: // comma not needed for top-level values + case m.Last.needImplicitComma(next) && len(m.Stack) != 0: // comma not needed for top-level values return append(b, ',') default: return b @@ -263,39 +400,24 @@ func (m stateMachine) mayAppendDelim(b []byte, next Kind) []byte { // A zero value means no delimiter should be emitted. func (m stateMachine) needDelim(next Kind) (delim byte) { switch { - case m.last.needImplicitColon(): + case m.Last.needImplicitColon(): return ':' - case m.last.needImplicitComma(next) && len(m.stack) != 0: // comma not needed for top-level values + case m.Last.needImplicitComma(next) && len(m.Stack) != 0: // comma not needed for top-level values return ',' default: return 0 } } -// checkDelim reports whether the specified delimiter should be there given -// the kind of the next token that appears immediately afterwards. -func (m stateMachine) checkDelim(delim byte, next Kind) error { - switch needDelim := m.needDelim(next); { - case needDelim == delim: - return nil - case needDelim == ':': - return errMissingColon - case needDelim == ',': - return errMissingComma - default: - return newInvalidCharacterError([]byte{delim}, "before next token") - } -} - -// invalidateDisabledNamespaces marks all disabled namespaces as invalid. +// InvalidateDisabledNamespaces marks all disabled namespaces as invalid. // // For efficiency, Marshal and Unmarshal may disable namespaces since there are // more efficient ways to track duplicate names. However, if an error occurs, // the namespaces in Encoder or Decoder will be left in an inconsistent state. // Mark the namespaces as invalid so that future method calls on // Encoder or Decoder will return an error. -func (m *stateMachine) invalidateDisabledNamespaces() { - for i := 0; i < m.depth(); i++ { +func (m *stateMachine) InvalidateDisabledNamespaces() { + for i := range m.Depth() { e := m.index(i) if !e.isActiveNamespace() { e.invalidateNamespace() @@ -329,10 +451,10 @@ const ( stateCountEven stateEntry = 0x0000_0000_0000_0000 ) -// length reports the number of elements in the JSON object or array. +// Length reports the number of elements in the JSON object or array. // Each name and value in an object entry is treated as a separate element. -func (e stateEntry) length() int { - return int(e & stateCountMask) +func (e stateEntry) Length() int64 { + return int64(e & stateCountMask) } // isObject reports whether this is a JSON object. @@ -345,9 +467,9 @@ func (e stateEntry) isArray() bool { return e&stateTypeMask == stateTypeArray } -// needObjectName reports whether the next token must be a JSON string, +// NeedObjectName reports whether the next token must be a JSON string, // which is necessary for JSON object names. -func (e stateEntry) needObjectName() bool { +func (e stateEntry) NeedObjectName() bool { return e&(stateTypeMask|stateCountLSBMask) == stateTypeObject|stateCountEven } @@ -367,13 +489,13 @@ func (e stateEntry) needObjectValue() bool { // which always occurs after a value in a JSON object or array // before the next value (or name). func (e stateEntry) needImplicitComma(next Kind) bool { - return !e.needObjectValue() && e.length() > 0 && next != '}' && next != ']' + return !e.needObjectValue() && e.Length() > 0 && next != '}' && next != ']' } -// increment increments the number of elements for the current object or array. +// Increment increments the number of elements for the current object or array. // This assumes that overflow won't practically be an issue since // 1< 0 { startOffset = ns.offsets[i-1] } - if n := consumeSimpleString(quotedName); n > 0 { + if n := jsonwire.ConsumeSimpleString(quotedName); n > 0 { ns.unquotedNames = append(ns.unquotedNames[:startOffset], quotedName[len(`"`):n-len(`"`)]...) } else { - ns.unquotedNames, _ = unescapeString(ns.unquotedNames[:startOffset], quotedName) + ns.unquotedNames, _ = jsonwire.AppendUnquote(ns.unquotedNames[:startOffset], quotedName) } ns.offsets[i] = len(ns.unquotedNames) } @@ -565,14 +687,14 @@ func (nss *objectNamespaceStack) reset() { func (nss *objectNamespaceStack) push() { if cap(*nss) > len(*nss) { *nss = (*nss)[:len(*nss)+1] - nss.last().reset() + nss.Last().reset() } else { *nss = append(*nss, objectNamespace{}) } } -// last returns a pointer to the last JSON object namespace. -func (nss objectNamespaceStack) last() *objectNamespace { +// Last returns a pointer to the last JSON object namespace. +func (nss objectNamespaceStack) Last() *objectNamespace { return &nss[len(nss)-1] } @@ -641,13 +763,13 @@ func (ns *objectNamespace) insertQuoted(name []byte, isVerbatim bool) bool { } return ns.insert(name, !isVerbatim) } -func (ns *objectNamespace) insertUnquoted(name []byte) bool { +func (ns *objectNamespace) InsertUnquoted(name []byte) bool { return ns.insert(name, false) } func (ns *objectNamespace) insert(name []byte, quoted bool) bool { var allNames []byte if quoted { - allNames, _ = unescapeString(ns.allUnquotedNames, name) + allNames, _ = jsonwire.AppendUnquote(ns.allUnquotedNames, name) } else { allNames = append(ns.allUnquotedNames, name...) } @@ -702,46 +824,3 @@ func (ns *objectNamespace) removeLast() { ns.allUnquotedNames = ns.allUnquotedNames[:ns.endOffsets[ns.length()-1]] } } - -type uintSet64 uint64 - -func (s uintSet64) has(i uint) bool { return s&(1< 0 } -func (s *uintSet64) set(i uint) { *s |= 1 << i } - -// uintSet is a set of unsigned integers. -// It is optimized for most integers being close to zero. -type uintSet struct { - lo uintSet64 - hi []uintSet64 -} - -// has reports whether i is in the set. -func (s *uintSet) has(i uint) bool { - if i < 64 { - return s.lo.has(i) - } else { - i -= 64 - iHi, iLo := int(i/64), i%64 - return iHi < len(s.hi) && s.hi[iHi].has(iLo) - } -} - -// insert inserts i into the set and reports whether it was the first insertion. -func (s *uintSet) insert(i uint) bool { - // TODO: Make this inlineable at least for the lower 64-bit case. - if i < 64 { - has := s.lo.has(i) - s.lo.set(i) - return !has - } else { - i -= 64 - iHi, iLo := int(i/64), i%64 - if iHi >= len(s.hi) { - s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...) - s.hi = s.hi[:cap(s.hi)] - } - has := s.hi[iHi].has(iLo) - s.hi[iHi].set(iLo) - return !has - } -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/token.go similarity index 87% rename from vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go rename to vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/token.go index 9acba7da..ea8c30eb 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/token.go @@ -2,11 +2,16 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package json +package jsontext import ( + "bytes" + "errors" "math" "strconv" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" ) // NOTE: Token is analogous to v1 json.Token. @@ -17,17 +22,19 @@ const ( maxUint64 = math.MaxUint64 minUint64 = 0 // for consistency and readability purposes - invalidTokenPanic = "invalid json.Token; it has been voided by a subsequent json.Decoder call" + invalidTokenPanic = "invalid jsontext.Token; it has been voided by a subsequent json.Decoder call" ) +var errInvalidToken = errors.New("invalid jsontext.Token") + // Token represents a lexical JSON token, which may be one of the following: // - a JSON literal (i.e., null, true, or false) // - a JSON string (e.g., "hello, world!") // - a JSON number (e.g., 123.456) -// - a start or end delimiter for a JSON object (i.e., { or } ) -// - a start or end delimiter for a JSON array (i.e., [ or ] ) +// - a begin or end delimiter for a JSON object (i.e., { or } ) +// - a begin or end delimiter for a JSON array (i.e., [ or ] ) // -// A Token cannot represent entire array or object values, while a RawValue can. +// A Token cannot represent entire array or object values, while a [Value] can. // There is no Token to represent commas and colons since // these structural tokens can be inferred from the surrounding context. type Token struct { @@ -87,10 +94,10 @@ var ( False Token = rawToken("false") True Token = rawToken("true") - ObjectStart Token = rawToken("{") - ObjectEnd Token = rawToken("}") - ArrayStart Token = rawToken("[") - ArrayEnd Token = rawToken("]") + BeginObject Token = rawToken("{") + EndObject Token = rawToken("}") + BeginArray Token = rawToken("[") + EndArray Token = rawToken("]") zeroString Token = rawToken(`""`) zeroNumber Token = rawToken(`0`) @@ -156,7 +163,7 @@ func Uint(n uint64) Token { } // Clone makes a copy of the Token such that its value remains valid -// even after a subsequent Decoder.Read call. +// even after a subsequent [Decoder.Read] call. func (t Token) Clone() Token { // TODO: Allow caller to avoid any allocations? if raw := t.raw; raw != nil { @@ -169,22 +176,21 @@ func (t Token) Clone() Token { return False case True.raw: return True - case ObjectStart.raw: - return ObjectStart - case ObjectEnd.raw: - return ObjectEnd - case ArrayStart.raw: - return ArrayStart - case ArrayEnd.raw: - return ArrayEnd + case BeginObject.raw: + return BeginObject + case EndObject.raw: + return EndObject + case BeginArray.raw: + return BeginArray + case EndArray.raw: + return EndArray } } if uint64(raw.previousOffsetStart()) != t.num { panic(invalidTokenPanic) } - // TODO(https://go.dev/issue/45038): Use bytes.Clone. - buf := append([]byte(nil), raw.previousBuffer()...) + buf := bytes.Clone(raw.previousBuffer()) return Token{raw: &decodeBuffer{buf: buf, prevStart: 0, prevEnd: len(buf)}} } return t @@ -205,20 +211,20 @@ func (t Token) Bool() bool { // appendString appends a JSON string to dst and returns it. // It panics if t is not a JSON string. -func (t Token) appendString(dst []byte, validateUTF8, preserveRaw bool, escapeRune func(rune) bool) ([]byte, error) { +func (t Token) appendString(dst []byte, flags *jsonflags.Flags) ([]byte, error) { if raw := t.raw; raw != nil { // Handle raw string value. buf := raw.previousBuffer() if Kind(buf[0]) == '"' { - if escapeRune == nil && consumeSimpleString(buf) == len(buf) { + if jsonwire.ConsumeSimpleString(buf) == len(buf) { return append(dst, buf...), nil } - dst, _, err := reformatString(dst, buf, validateUTF8, preserveRaw, escapeRune) + dst, _, err := jsonwire.ReformatString(dst, buf, flags) return dst, err } } else if len(t.str) != 0 && t.num == 0 { // Handle exact string value. - return appendString(dst, t.str, validateUTF8, escapeRune) + return jsonwire.AppendQuote(dst, t.str, flags) } panic("invalid JSON token kind: " + t.Kind().String()) @@ -244,9 +250,9 @@ func (t Token) string() (string, []byte) { } buf := raw.previousBuffer() if buf[0] == '"' { - // TODO: Preserve valueFlags in Token? - isVerbatim := consumeSimpleString(buf) == len(buf) - return "", unescapeStringMayCopy(buf, isVerbatim) + // TODO: Preserve ValueFlags in Token? + isVerbatim := jsonwire.ConsumeSimpleString(buf) == len(buf) + return "", jsonwire.UnquoteMayCopy(buf, isVerbatim) } // Handle tokens that are not JSON strings for fmt.Stringer. return "", buf @@ -258,34 +264,31 @@ func (t Token) string() (string, []byte) { if t.num > 0 { switch t.str[0] { case 'f': - return string(appendNumber(nil, math.Float64frombits(t.num), 64)), nil + return string(jsonwire.AppendFloat(nil, math.Float64frombits(t.num), 64)), nil case 'i': return strconv.FormatInt(int64(t.num), 10), nil case 'u': return strconv.FormatUint(uint64(t.num), 10), nil } } - return "", nil + return "", nil } // appendNumber appends a JSON number to dst and returns it. // It panics if t is not a JSON number. -func (t Token) appendNumber(dst []byte, canonicalize bool) ([]byte, error) { +func (t Token) appendNumber(dst []byte, flags *jsonflags.Flags) ([]byte, error) { if raw := t.raw; raw != nil { // Handle raw number value. buf := raw.previousBuffer() if Kind(buf[0]).normalize() == '0' { - if !canonicalize { - return append(dst, buf...), nil - } - dst, _, err := reformatNumber(dst, buf, canonicalize) + dst, _, err := jsonwire.ReformatNumber(dst, buf, flags) return dst, err } } else if t.num != 0 { // Handle exact number value. switch t.str[0] { case 'f': - return appendNumber(dst, math.Float64frombits(t.num), 64), nil + return jsonwire.AppendFloat(dst, math.Float64frombits(t.num), 64), nil case 'i': return strconv.AppendInt(dst, int64(t.num), 10), nil case 'u': @@ -308,7 +311,7 @@ func (t Token) Float() float64 { } buf := raw.previousBuffer() if Kind(buf[0]).normalize() == '0' { - fv, _ := parseFloat(buf, 64) + fv, _ := jsonwire.ParseFloat(buf, 64) return fv } } else if t.num != 0 { @@ -354,7 +357,7 @@ func (t Token) Int() int64 { if len(buf) > 0 && buf[0] == '-' { neg, buf = true, buf[1:] } - if numAbs, ok := parseDecUint(buf); ok { + if numAbs, ok := jsonwire.ParseUint(buf); ok { if neg { if numAbs > -minInt64 { return minInt64 @@ -415,7 +418,7 @@ func (t Token) Uint() uint64 { if len(buf) > 0 && buf[0] == '-' { neg, buf = true, buf[1:] } - if num, ok := parseDecUint(buf); ok { + if num, ok := jsonwire.ParseUint(buf); ok { if neg { return minUint64 } @@ -476,9 +479,9 @@ func (t Token) Kind() Kind { // - 't': true // - '"': string // - '0': number -// - '{': object start +// - '{': object begin // - '}': object end -// - '[': array start +// - '[': array begin // - ']': array end // // An invalid kind is usually represented using 0, @@ -509,7 +512,7 @@ func (k Kind) String() string { case ']': return "]" default: - return "" + return "" } } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go new file mode 100644 index 00000000..3ea05d3a --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext/value.go @@ -0,0 +1,393 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsontext + +import ( + "bytes" + "errors" + "io" + "slices" + "sync" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire" +) + +// NOTE: Value is analogous to v1 json.RawMessage. + +// AppendFormat formats the JSON value in src and appends it to dst +// according to the specified options. +// See [Value.Format] for more details about the formatting behavior. +// +// The dst and src may overlap. +// If an error is reported, then the entirety of src is appended to dst. +func AppendFormat(dst, src []byte, opts ...Options) ([]byte, error) { + e := getBufferedEncoder(opts...) + defer putBufferedEncoder(e) + e.s.Flags.Set(jsonflags.OmitTopLevelNewline | 1) + if err := e.s.WriteValue(src); err != nil { + return append(dst, src...), err + } + return append(dst, e.s.Buf...), nil +} + +// Value represents a single raw JSON value, which may be one of the following: +// - a JSON literal (i.e., null, true, or false) +// - a JSON string (e.g., "hello, world!") +// - a JSON number (e.g., 123.456) +// - an entire JSON object (e.g., {"fizz":"buzz"} ) +// - an entire JSON array (e.g., [1,2,3] ) +// +// Value can represent entire array or object values, while [Token] cannot. +// Value may contain leading and/or trailing whitespace. +type Value []byte + +// Clone returns a copy of v. +func (v Value) Clone() Value { + return bytes.Clone(v) +} + +// String returns the string formatting of v. +func (v Value) String() string { + if v == nil { + return "null" + } + return string(v) +} + +// IsValid reports whether the raw JSON value is syntactically valid +// according to the specified options. +// +// By default (if no options are specified), it validates according to RFC 7493. +// It verifies whether the input is properly encoded as UTF-8, +// that escape sequences within strings decode to valid Unicode codepoints, and +// that all names in each object are unique. +// It does not verify whether numbers are representable within the limits +// of any common numeric type (e.g., float64, int64, or uint64). +// +// Relevant options include: +// - [AllowDuplicateNames] +// - [AllowInvalidUTF8] +// +// All other options are ignored. +func (v Value) IsValid(opts ...Options) bool { + // TODO: Document support for [WithByteLimit] and [WithDepthLimit]. + d := getBufferedDecoder(v, opts...) + defer putBufferedDecoder(d) + _, errVal := d.ReadValue() + _, errEOF := d.ReadToken() + return errVal == nil && errEOF == io.EOF +} + +// Format formats the raw JSON value in place. +// +// By default (if no options are specified), it validates according to RFC 7493 +// and produces the minimal JSON representation, where +// all whitespace is elided and JSON strings use the shortest encoding. +// +// Relevant options include: +// - [AllowDuplicateNames] +// - [AllowInvalidUTF8] +// - [EscapeForHTML] +// - [EscapeForJS] +// - [PreserveRawStrings] +// - [CanonicalizeRawInts] +// - [CanonicalizeRawFloats] +// - [ReorderRawObjects] +// - [SpaceAfterColon] +// - [SpaceAfterComma] +// - [Multiline] +// - [WithIndent] +// - [WithIndentPrefix] +// +// All other options are ignored. +// +// It is guaranteed to succeed if the value is valid according to the same options. +// If the value is already formatted, then the buffer is not mutated. +func (v *Value) Format(opts ...Options) error { + // TODO: Document support for [WithByteLimit] and [WithDepthLimit]. + return v.format(opts, nil) +} + +// format accepts two []Options to avoid the allocation appending them together. +// It is equivalent to v.Format(append(opts1, opts2...)...). +func (v *Value) format(opts1, opts2 []Options) error { + e := getBufferedEncoder(opts1...) + defer putBufferedEncoder(e) + e.s.Join(opts2...) + e.s.Flags.Set(jsonflags.OmitTopLevelNewline | 1) + if err := e.s.WriteValue(*v); err != nil { + return err + } + if !bytes.Equal(*v, e.s.Buf) { + *v = append((*v)[:0], e.s.Buf...) + } + return nil +} + +// Compact removes all whitespace from the raw JSON value. +// +// It does not reformat JSON strings or numbers to use any other representation. +// To maximize the set of JSON values that can be formatted, +// this permits values with duplicate names and invalid UTF-8. +// +// Compact is equivalent to calling [Value.Format] with the following options: +// - [AllowDuplicateNames](true) +// - [AllowInvalidUTF8](true) +// - [PreserveRawStrings](true) +// +// Any options specified by the caller are applied after the initial set +// and may deliberately override prior options. +func (v *Value) Compact(opts ...Options) error { + return v.format([]Options{ + AllowDuplicateNames(true), + AllowInvalidUTF8(true), + PreserveRawStrings(true), + }, opts) +} + +// Indent reformats the whitespace in the raw JSON value so that each element +// in a JSON object or array begins on a indented line according to the nesting. +// +// It does not reformat JSON strings or numbers to use any other representation. +// To maximize the set of JSON values that can be formatted, +// this permits values with duplicate names and invalid UTF-8. +// +// Indent is equivalent to calling [Value.Format] with the following options: +// - [AllowDuplicateNames](true) +// - [AllowInvalidUTF8](true) +// - [PreserveRawStrings](true) +// - [Multiline](true) +// +// Any options specified by the caller are applied after the initial set +// and may deliberately override prior options. +func (v *Value) Indent(opts ...Options) error { + return v.format([]Options{ + AllowDuplicateNames(true), + AllowInvalidUTF8(true), + PreserveRawStrings(true), + Multiline(true), + }, opts) +} + +// Canonicalize canonicalizes the raw JSON value according to the +// JSON Canonicalization Scheme (JCS) as defined by RFC 8785 +// where it produces a stable representation of a JSON value. +// +// JSON strings are formatted to use their minimal representation, +// JSON numbers are formatted as double precision numbers according +// to some stable serialization algorithm. +// JSON object members are sorted in ascending order by name. +// All whitespace is removed. +// +// The output stability is dependent on the stability of the application data +// (see RFC 8785, Appendix E). It cannot produce stable output from +// fundamentally unstable input. For example, if the JSON value +// contains ephemeral data (e.g., a frequently changing timestamp), +// then the value is still unstable regardless of whether this is called. +// +// Canonicalize is equivalent to calling [Value.Format] with the following options: +// - [CanonicalizeRawInts](true) +// - [CanonicalizeRawFloats](true) +// - [ReorderRawObjects](true) +// +// Any options specified by the caller are applied after the initial set +// and may deliberately override prior options. +// +// Note that JCS treats all JSON numbers as IEEE 754 double precision numbers. +// Any numbers with precision beyond what is representable by that form +// will lose their precision when canonicalized. For example, integer values +// beyond ±2⁵³ will lose their precision. To preserve the original representation +// of JSON integers, additionally set [CanonicalizeRawInts] to false: +// +// v.Canonicalize(jsontext.CanonicalizeRawInts(false)) +func (v *Value) Canonicalize(opts ...Options) error { + return v.format([]Options{ + CanonicalizeRawInts(true), + CanonicalizeRawFloats(true), + ReorderRawObjects(true), + }, opts) +} + +// MarshalJSON returns v as the JSON encoding of v. +// It returns the stored value as the raw JSON output without any validation. +// If v is nil, then this returns a JSON null. +func (v Value) MarshalJSON() ([]byte, error) { + // NOTE: This matches the behavior of v1 json.RawMessage.MarshalJSON. + if v == nil { + return []byte("null"), nil + } + return v, nil +} + +// UnmarshalJSON sets v as the JSON encoding of b. +// It stores a copy of the provided raw JSON input without any validation. +func (v *Value) UnmarshalJSON(b []byte) error { + // NOTE: This matches the behavior of v1 json.RawMessage.UnmarshalJSON. + if v == nil { + return errors.New("jsontext.Value: UnmarshalJSON on nil pointer") + } + *v = append((*v)[:0], b...) + return nil +} + +// Kind returns the starting token kind. +// For a valid value, this will never include '}' or ']'. +func (v Value) Kind() Kind { + if v := v[jsonwire.ConsumeWhitespace(v):]; len(v) > 0 { + return Kind(v[0]).normalize() + } + return invalidKind +} + +const commaAndWhitespace = ", \n\r\t" + +type objectMember struct { + // name is the unquoted name. + name []byte // e.g., "name" + // buffer is the entirety of the raw JSON object member + // starting from right after the previous member (or opening '{') + // until right after the member value. + buffer []byte // e.g., `, \n\r\t"name": "value"` +} + +func (x objectMember) Compare(y objectMember) int { + if c := jsonwire.CompareUTF16(x.name, y.name); c != 0 { + return c + } + // With [AllowDuplicateNames] or [AllowInvalidUTF8], + // names could be identical, so also sort using the member value. + return jsonwire.CompareUTF16( + bytes.TrimLeft(x.buffer, commaAndWhitespace), + bytes.TrimLeft(y.buffer, commaAndWhitespace)) +} + +var objectMemberPool = sync.Pool{New: func() any { return new([]objectMember) }} + +func getObjectMembers() *[]objectMember { + ns := objectMemberPool.Get().(*[]objectMember) + *ns = (*ns)[:0] + return ns +} +func putObjectMembers(ns *[]objectMember) { + if cap(*ns) < 1<<10 { + clear(*ns) // avoid pinning name and buffer + objectMemberPool.Put(ns) + } +} + +// mustReorderObjects reorders in-place all object members in a JSON value, +// which must be valid otherwise it panics. +func mustReorderObjects(b []byte) { + // Obtain a buffered encoder just to use its internal buffer as + // a scratch buffer for reordering object members. + e2 := getBufferedEncoder() + defer putBufferedEncoder(e2) + + // Disable unnecessary checks to syntactically parse the JSON value. + d := getBufferedDecoder(b) + defer putBufferedDecoder(d) + d.s.Flags.Set(jsonflags.AllowDuplicateNames | jsonflags.AllowInvalidUTF8 | 1) + mustReorderObjectsFromDecoder(d, &e2.s.Buf) // per RFC 8785, section 3.2.3 +} + +// mustReorderObjectsFromDecoder recursively reorders all object members in place +// according to the ordering specified in RFC 8785, section 3.2.3. +// +// Pre-conditions: +// - The value is valid (i.e., no decoder errors should ever occur). +// - Initial call is provided a Decoder reading from the start of v. +// +// Post-conditions: +// - Exactly one JSON value is read from the Decoder. +// - All fully-parsed JSON objects are reordered by directly moving +// the members in the value buffer. +// +// The runtime is approximately O(n·log(n)) + O(m·log(m)), +// where n is len(v) and m is the total number of object members. +func mustReorderObjectsFromDecoder(d *Decoder, scratch *[]byte) { + switch tok, err := d.ReadToken(); tok.Kind() { + case '{': + // Iterate and collect the name and offsets for every object member. + members := getObjectMembers() + defer putObjectMembers(members) + var prevMember objectMember + isSorted := true + + beforeBody := d.InputOffset() // offset after '{' + for d.PeekKind() != '}' { + beforeName := d.InputOffset() + var flags jsonwire.ValueFlags + name, _ := d.s.ReadValue(&flags) + name = jsonwire.UnquoteMayCopy(name, flags.IsVerbatim()) + mustReorderObjectsFromDecoder(d, scratch) + afterValue := d.InputOffset() + + currMember := objectMember{name, d.s.buf[beforeName:afterValue]} + if isSorted && len(*members) > 0 { + isSorted = objectMember.Compare(prevMember, currMember) < 0 + } + *members = append(*members, currMember) + prevMember = currMember + } + afterBody := d.InputOffset() // offset before '}' + d.ReadToken() + + // Sort the members; return early if it's already sorted. + if isSorted { + return + } + firstBufferBeforeSorting := (*members)[0].buffer + slices.SortFunc(*members, objectMember.Compare) + firstBufferAfterSorting := (*members)[0].buffer + + // Append the reordered members to a new buffer, + // then copy the reordered members back over the original members. + // Avoid swapping in place since each member may be a different size + // where moving a member over a smaller member may corrupt the data + // for subsequent members before they have been moved. + // + // The following invariant must hold: + // sum([m.after-m.before for m in members]) == afterBody-beforeBody + commaAndWhitespacePrefix := func(b []byte) []byte { + return b[:len(b)-len(bytes.TrimLeft(b, commaAndWhitespace))] + } + sorted := (*scratch)[:0] + for i, member := range *members { + switch { + case i == 0 && &member.buffer[0] != &firstBufferBeforeSorting[0]: + // First member after sorting is not the first member before sorting, + // so use the prefix of the first member before sorting. + sorted = append(sorted, commaAndWhitespacePrefix(firstBufferBeforeSorting)...) + sorted = append(sorted, bytes.TrimLeft(member.buffer, commaAndWhitespace)...) + case i != 0 && &member.buffer[0] == &firstBufferBeforeSorting[0]: + // Later member after sorting is the first member before sorting, + // so use the prefix of the first member after sorting. + sorted = append(sorted, commaAndWhitespacePrefix(firstBufferAfterSorting)...) + sorted = append(sorted, bytes.TrimLeft(member.buffer, commaAndWhitespace)...) + default: + sorted = append(sorted, member.buffer...) + } + } + if int(afterBody-beforeBody) != len(sorted) { + panic("BUG: length invariant violated") + } + copy(d.s.buf[beforeBody:afterBody], sorted) + + // Update scratch buffer to the largest amount ever used. + if len(sorted) > len(*scratch) { + *scratch = sorted + } + case '[': + for d.PeekKind() != ']' { + mustReorderObjectsFromDecoder(d, scratch) + } + d.ReadToken() + default: + if err != nil { + panic("BUG: " + err.Error()) + } + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/migrate.sh b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/migrate.sh new file mode 100644 index 00000000..9c34f26e --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/migrate.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +GOROOT=${1:-../go} +JSONROOT="." + +cp $JSONROOT/alias_gen.go $JSONROOT/alias_gen.go.bak +rm -r $JSONROOT/*.go $JSONROOT/internal $JSONROOT/jsontext $JSONROOT/v1 +mv $JSONROOT/alias_gen.go.bak $JSONROOT/alias_gen.go +cp -r $GOROOT/src/encoding/json/v2/*.go $JSONROOT/ +cp -r $GOROOT/src/encoding/json/internal/ $JSONROOT/internal/ +cp -r $GOROOT/src/encoding/json/jsontext/ $JSONROOT/jsontext/ +mkdir $JSONROOT/v1 +for X in $GOROOT/src/encoding/json/v2_*.go; do + cp $X $JSONROOT/v1/$(basename $X | sed "s/v2_//") +done +cd $JSONROOT +for X in $(git ls-files --cached --others --exclude-standard | grep ".*[.]go$"); do + if [ ! -e "$X" ]; then + continue + fi + sed -i 's/go:build goexperiment.jsonv2$/go:build !goexperiment.jsonv2 || !go1.25/' $X + sed -i 's|"encoding/json/v2"|"github.com/go-json-experiment/json"|' $X + sed -i 's|"encoding/json/internal"|"github.com/go-json-experiment/json/internal"|' $X + sed -i 's|"encoding/json/internal/jsonflags"|"github.com/go-json-experiment/json/internal/jsonflags"|' $X + sed -i 's|"encoding/json/internal/jsonopts"|"github.com/go-json-experiment/json/internal/jsonopts"|' $X + sed -i 's|"encoding/json/internal/jsontest"|"github.com/go-json-experiment/json/internal/jsontest"|' $X + sed -i 's|"encoding/json/internal/jsonwire"|"github.com/go-json-experiment/json/internal/jsonwire"|' $X + sed -i 's|"encoding/json/jsontext"|"github.com/go-json-experiment/json/jsontext"|' $X + sed -i 's|"encoding/json"|"github.com/go-json-experiment/json/v1"|' $X + sed -i 's|"internal/zstd"|"github.com/go-json-experiment/json/internal/zstd"|' $X + goimports -w $X +done +sed -i 's/v2[.]struct/json.struct/' $JSONROOT/errors_test.go +sed -i 's|jsonv1 "github.com/go-json-experiment/json/v1"|jsonv1 "encoding/json"|' $JSONROOT/bench_test.go + +# TODO(go1.25): Remove test that relies on "synctest" that is not available yet. +sed -i '/Issue #73733/,+17d' $JSONROOT/v1/encode_test.go +goimports -w $JSONROOT/v1/encode_test.go + +# Remove documentation that only makes sense within the stdlib. +sed -i '/This package .* is experimental/,+4d' $JSONROOT/doc.go +sed -i '/This package .* is experimental/,+4d' $JSONROOT/jsontext/doc.go + +git checkout internal/zstd # we still need local copy of zstd for testing + +go run alias_gen.go "encoding/json" $JSONROOT/v1 +go run alias_gen.go "encoding/json/v2" $JSONROOT +go run alias_gen.go "encoding/json/jsontext" $JSONROOT/jsontext diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go new file mode 100644 index 00000000..2f474498 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/options.go @@ -0,0 +1,287 @@ +// Copyright 2023 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 json + +import ( + "fmt" + + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts" +) + +// Options configure [Marshal], [MarshalWrite], [MarshalEncode], +// [Unmarshal], [UnmarshalRead], and [UnmarshalDecode] with specific features. +// Each function takes in a variadic list of options, where properties +// set in later options override the value of previously set properties. +// +// The Options type is identical to [encoding/json.Options] and +// [encoding/json/jsontext.Options]. Options from the other packages can +// be used interchangeably with functionality in this package. +// +// Options represent either a singular option or a set of options. +// It can be functionally thought of as a Go map of option properties +// (even though the underlying implementation avoids Go maps for performance). +// +// The constructors (e.g., [Deterministic]) return a singular option value: +// +// opt := Deterministic(true) +// +// which is analogous to creating a single entry map: +// +// opt := Options{"Deterministic": true} +// +// [JoinOptions] composes multiple options values to together: +// +// out := JoinOptions(opts...) +// +// which is analogous to making a new map and copying the options over: +// +// out := make(Options) +// for _, m := range opts { +// for k, v := range m { +// out[k] = v +// } +// } +// +// [GetOption] looks up the value of options parameter: +// +// v, ok := GetOption(opts, Deterministic) +// +// which is analogous to a Go map lookup: +// +// v, ok := Options["Deterministic"] +// +// There is a single Options type, which is used with both marshal and unmarshal. +// Some options affect both operations, while others only affect one operation: +// +// - [StringifyNumbers] affects marshaling and unmarshaling +// - [Deterministic] affects marshaling only +// - [FormatNilSliceAsNull] affects marshaling only +// - [FormatNilMapAsNull] affects marshaling only +// - [OmitZeroStructFields] affects marshaling only +// - [MatchCaseInsensitiveNames] affects marshaling and unmarshaling +// - [DiscardUnknownMembers] affects marshaling only +// - [RejectUnknownMembers] affects unmarshaling only +// - [WithMarshalers] affects marshaling only +// - [WithUnmarshalers] affects unmarshaling only +// +// Options that do not affect a particular operation are ignored. +type Options = jsonopts.Options + +// JoinOptions coalesces the provided list of options into a single Options. +// Properties set in later options override the value of previously set properties. +func JoinOptions(srcs ...Options) Options { + var dst jsonopts.Struct + dst.Join(srcs...) + return &dst +} + +// GetOption returns the value stored in opts with the provided setter, +// reporting whether the value is present. +// +// Example usage: +// +// v, ok := json.GetOption(opts, json.Deterministic) +// +// Options are most commonly introspected to alter the JSON representation of +// [MarshalerTo.MarshalJSONTo] and [UnmarshalerFrom.UnmarshalJSONFrom] methods, and +// [MarshalToFunc] and [UnmarshalFromFunc] functions. +// In such cases, the presence bit should generally be ignored. +func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { + return jsonopts.GetOption(opts, setter) +} + +// DefaultOptionsV2 is the full set of all options that define v2 semantics. +// It is equivalent to all options under [Options], [encoding/json.Options], +// and [encoding/json/jsontext.Options] being set to false or the zero value, +// except for the options related to whitespace formatting. +func DefaultOptionsV2() Options { + return &jsonopts.DefaultOptionsV2 +} + +// StringifyNumbers specifies that numeric Go types should be marshaled +// as a JSON string containing the equivalent JSON number value. +// When unmarshaling, numeric Go types are parsed from a JSON string +// containing the JSON number without any surrounding whitespace. +// +// According to RFC 8259, section 6, a JSON implementation may choose to +// limit the representation of a JSON number to an IEEE 754 binary64 value. +// This may cause decoders to lose precision for int64 and uint64 types. +// Quoting JSON numbers as a JSON string preserves the exact precision. +// +// This affects either marshaling or unmarshaling. +func StringifyNumbers(v bool) Options { + if v { + return jsonflags.StringifyNumbers | 1 + } else { + return jsonflags.StringifyNumbers | 0 + } +} + +// Deterministic specifies that the same input value will be serialized +// as the exact same output bytes. Different processes of +// the same program will serialize equal values to the same bytes, +// but different versions of the same program are not guaranteed +// to produce the exact same sequence of bytes. +// +// This only affects marshaling and is ignored when unmarshaling. +func Deterministic(v bool) Options { + if v { + return jsonflags.Deterministic | 1 + } else { + return jsonflags.Deterministic | 0 + } +} + +// FormatNilSliceAsNull specifies that a nil Go slice should marshal as a +// JSON null instead of the default representation as an empty JSON array +// (or an empty JSON string in the case of ~[]byte). +// Slice fields explicitly marked with `format:emitempty` still marshal +// as an empty JSON array. +// +// This only affects marshaling and is ignored when unmarshaling. +func FormatNilSliceAsNull(v bool) Options { + if v { + return jsonflags.FormatNilSliceAsNull | 1 + } else { + return jsonflags.FormatNilSliceAsNull | 0 + } +} + +// FormatNilMapAsNull specifies that a nil Go map should marshal as a +// JSON null instead of the default representation as an empty JSON object. +// Map fields explicitly marked with `format:emitempty` still marshal +// as an empty JSON object. +// +// This only affects marshaling and is ignored when unmarshaling. +func FormatNilMapAsNull(v bool) Options { + if v { + return jsonflags.FormatNilMapAsNull | 1 + } else { + return jsonflags.FormatNilMapAsNull | 0 + } +} + +// OmitZeroStructFields specifies that a Go struct should marshal in such a way +// that all struct fields that are zero are omitted from the marshaled output +// if the value is zero as determined by the "IsZero() bool" method if present, +// otherwise based on whether the field is the zero Go value. +// This is semantically equivalent to specifying the `omitzero` tag option +// on every field in a Go struct. +// +// This only affects marshaling and is ignored when unmarshaling. +func OmitZeroStructFields(v bool) Options { + if v { + return jsonflags.OmitZeroStructFields | 1 + } else { + return jsonflags.OmitZeroStructFields | 0 + } +} + +// MatchCaseInsensitiveNames specifies that JSON object members are matched +// against Go struct fields using a case-insensitive match of the name. +// Go struct fields explicitly marked with `case:strict` or `case:ignore` +// always use case-sensitive (or case-insensitive) name matching, +// regardless of the value of this option. +// +// This affects either marshaling or unmarshaling. +// For marshaling, this option may alter the detection of duplicate names +// (assuming [jsontext.AllowDuplicateNames] is false) from inlined fields +// if it matches one of the declared fields in the Go struct. +func MatchCaseInsensitiveNames(v bool) Options { + if v { + return jsonflags.MatchCaseInsensitiveNames | 1 + } else { + return jsonflags.MatchCaseInsensitiveNames | 0 + } +} + +// DiscardUnknownMembers specifies that marshaling should ignore any +// JSON object members stored in Go struct fields dedicated to storing +// unknown JSON object members. +// +// This only affects marshaling and is ignored when unmarshaling. +func DiscardUnknownMembers(v bool) Options { + if v { + return jsonflags.DiscardUnknownMembers | 1 + } else { + return jsonflags.DiscardUnknownMembers | 0 + } +} + +// RejectUnknownMembers specifies that unknown members should be rejected +// when unmarshaling a JSON object, regardless of whether there is a field +// to store unknown members. +// +// This only affects unmarshaling and is ignored when marshaling. +func RejectUnknownMembers(v bool) Options { + if v { + return jsonflags.RejectUnknownMembers | 1 + } else { + return jsonflags.RejectUnknownMembers | 0 + } +} + +// WithMarshalers specifies a list of type-specific marshalers to use, +// which can be used to override the default marshal behavior for values +// of particular types. +// +// This only affects marshaling and is ignored when unmarshaling. +func WithMarshalers(v *Marshalers) Options { + return (*marshalersOption)(v) +} + +// WithUnmarshalers specifies a list of type-specific unmarshalers to use, +// which can be used to override the default unmarshal behavior for values +// of particular types. +// +// This only affects unmarshaling and is ignored when marshaling. +func WithUnmarshalers(v *Unmarshalers) Options { + return (*unmarshalersOption)(v) +} + +// These option types are declared here instead of "jsonopts" +// to avoid a dependency on "reflect" from "jsonopts". +type ( + marshalersOption Marshalers + unmarshalersOption Unmarshalers +) + +func (*marshalersOption) JSONOptions(internal.NotForPublicUse) {} +func (*unmarshalersOption) JSONOptions(internal.NotForPublicUse) {} + +// Inject support into "jsonopts" to handle these types. +func init() { + jsonopts.GetUnknownOption = func(src jsonopts.Struct, zero jsonopts.Options) (any, bool) { + switch zero.(type) { + case *marshalersOption: + if !src.Flags.Has(jsonflags.Marshalers) { + return (*Marshalers)(nil), false + } + return src.Marshalers.(*Marshalers), true + case *unmarshalersOption: + if !src.Flags.Has(jsonflags.Unmarshalers) { + return (*Unmarshalers)(nil), false + } + return src.Unmarshalers.(*Unmarshalers), true + default: + panic(fmt.Sprintf("unknown option %T", zero)) + } + } + jsonopts.JoinUnknownOption = func(dst jsonopts.Struct, src jsonopts.Options) jsonopts.Struct { + switch src := src.(type) { + case *marshalersOption: + dst.Flags.Set(jsonflags.Marshalers | 1) + dst.Marshalers = (*Marshalers)(src) + case *unmarshalersOption: + dst.Flags.Set(jsonflags.Unmarshalers | 1) + dst.Unmarshalers = (*Unmarshalers)(src) + default: + panic(fmt.Sprintf("unknown option %T", src)) + } + return dst + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go deleted file mode 100644 index e0bd1b31..00000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go +++ /dev/null @@ -1,381 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package json - -import ( - "bytes" - "errors" - "io" - "sort" - "sync" - "unicode/utf16" - "unicode/utf8" -) - -// NOTE: RawValue is analogous to v1 json.RawMessage. - -// RawValue represents a single raw JSON value, which may be one of the following: -// - a JSON literal (i.e., null, true, or false) -// - a JSON string (e.g., "hello, world!") -// - a JSON number (e.g., 123.456) -// - an entire JSON object (e.g., {"fizz":"buzz"} ) -// - an entire JSON array (e.g., [1,2,3] ) -// -// RawValue can represent entire array or object values, while Token cannot. -// RawValue may contain leading and/or trailing whitespace. -type RawValue []byte - -// Clone returns a copy of v. -func (v RawValue) Clone() RawValue { - if v == nil { - return nil - } - return append(RawValue{}, v...) -} - -// String returns the string formatting of v. -func (v RawValue) String() string { - if v == nil { - return "null" - } - return string(v) -} - -// IsValid reports whether the raw JSON value is syntactically valid -// according to RFC 7493. -// -// It verifies whether the input is properly encoded as UTF-8, -// that escape sequences within strings decode to valid Unicode codepoints, and -// that all names in each object are unique. -// It does not verify whether numbers are representable within the limits -// of any common numeric type (e.g., float64, int64, or uint64). -func (v RawValue) IsValid() bool { - d := getBufferedDecoder(v, DecodeOptions{}) - defer putBufferedDecoder(d) - _, errVal := d.ReadValue() - _, errEOF := d.ReadToken() - return errVal == nil && errEOF == io.EOF -} - -// Compact removes all whitespace from the raw JSON value. -// -// It does not reformat JSON strings to use any other representation. -// It is guaranteed to succeed if the input is valid. -// If the value is already compacted, then the buffer is not mutated. -func (v *RawValue) Compact() error { - return v.reformat(false, false, "", "") -} - -// Indent reformats the whitespace in the raw JSON value so that each element -// in a JSON object or array begins on a new, indented line beginning with -// prefix followed by one or more copies of indent according to the nesting. -// The value does not begin with the prefix nor any indention, -// to make it easier to embed inside other formatted JSON data. -// -// It does not reformat JSON strings to use any other representation. -// It is guaranteed to succeed if the input is valid. -// If the value is already indented properly, then the buffer is not mutated. -func (v *RawValue) Indent(prefix, indent string) error { - return v.reformat(false, true, prefix, indent) -} - -// Canonicalize canonicalizes the raw JSON value according to the -// JSON Canonicalization Scheme (JCS) as defined by RFC 8785 -// where it produces a stable representation of a JSON value. -// -// The output stability is dependent on the stability of the application data -// (see RFC 8785, Appendix E). It cannot produce stable output from -// fundamentally unstable input. For example, if the JSON value -// contains ephemeral data (e.g., a frequently changing timestamp), -// then the value is still unstable regardless of whether this is called. -// -// Note that JCS treats all JSON numbers as IEEE 754 double precision numbers. -// Any numbers with precision beyond what is representable by that form -// will lose their precision when canonicalized. For example, integer values -// beyond ±2⁵³ will lose their precision. It is recommended that -// int64 and uint64 data types be represented as a JSON string. -// -// It is guaranteed to succeed if the input is valid. -// If the value is already canonicalized, then the buffer is not mutated. -func (v *RawValue) Canonicalize() error { - return v.reformat(true, false, "", "") -} - -// TODO: Instead of implementing the v1 Marshaler/Unmarshaler, -// consider implementing the v2 versions instead. - -// MarshalJSON returns v as the JSON encoding of v. -// It returns the stored value as the raw JSON output without any validation. -// If v is nil, then this returns a JSON null. -func (v RawValue) MarshalJSON() ([]byte, error) { - // NOTE: This matches the behavior of v1 json.RawMessage.MarshalJSON. - if v == nil { - return []byte("null"), nil - } - return v, nil -} - -// UnmarshalJSON sets v as the JSON encoding of b. -// It stores a copy of the provided raw JSON input without any validation. -func (v *RawValue) UnmarshalJSON(b []byte) error { - // NOTE: This matches the behavior of v1 json.RawMessage.UnmarshalJSON. - if v == nil { - return errors.New("json.RawValue: UnmarshalJSON on nil pointer") - } - *v = append((*v)[:0], b...) - return nil -} - -// Kind returns the starting token kind. -// For a valid value, this will never include '}' or ']'. -func (v RawValue) Kind() Kind { - if v := v[consumeWhitespace(v):]; len(v) > 0 { - return Kind(v[0]).normalize() - } - return invalidKind -} - -func (v *RawValue) reformat(canonical, multiline bool, prefix, indent string) error { - var eo EncodeOptions - if canonical { - eo.AllowInvalidUTF8 = false // per RFC 8785, section 3.2.4 - eo.AllowDuplicateNames = false // per RFC 8785, section 3.1 - eo.canonicalizeNumbers = true // per RFC 8785, section 3.2.2.3 - eo.EscapeRune = nil // per RFC 8785, section 3.2.2.2 - eo.multiline = false // per RFC 8785, section 3.2.1 - } else { - if s := trimLeftSpaceTab(prefix); len(s) > 0 { - panic("json: invalid character " + quoteRune([]byte(s)) + " in indent prefix") - } - if s := trimLeftSpaceTab(indent); len(s) > 0 { - panic("json: invalid character " + quoteRune([]byte(s)) + " in indent") - } - eo.AllowInvalidUTF8 = true - eo.AllowDuplicateNames = true - eo.preserveRawStrings = true - eo.multiline = multiline // in case indent is empty - eo.IndentPrefix = prefix - eo.Indent = indent - } - eo.omitTopLevelNewline = true - - // Write the entire value to reformat all tokens and whitespace. - e := getBufferedEncoder(eo) - defer putBufferedEncoder(e) - if err := e.WriteValue(*v); err != nil { - return err - } - - // For canonical output, we may need to reorder object members. - if canonical { - // Obtain a buffered encoder just to use its internal buffer as - // a scratch buffer in reorderObjects for reordering object members. - e2 := getBufferedEncoder(EncodeOptions{}) - defer putBufferedEncoder(e2) - - // Disable redundant checks performed earlier during encoding. - d := getBufferedDecoder(e.buf, DecodeOptions{AllowInvalidUTF8: true, AllowDuplicateNames: true}) - defer putBufferedDecoder(d) - reorderObjects(d, &e2.buf) // per RFC 8785, section 3.2.3 - } - - // Store the result back into the value if different. - if !bytes.Equal(*v, e.buf) { - *v = append((*v)[:0], e.buf...) - } - return nil -} - -func trimLeftSpaceTab(s string) string { - for i, r := range s { - switch r { - case ' ', '\t': - default: - return s[i:] - } - } - return "" -} - -type memberName struct { - // name is the unescaped name. - name []byte - // before and after are byte offsets into Decoder.buf that represents - // the entire name/value pair. It may contain leading commas. - before, after int64 -} - -var memberNamePool = sync.Pool{New: func() any { return new(memberNames) }} - -func getMemberNames() *memberNames { - ns := memberNamePool.Get().(*memberNames) - *ns = (*ns)[:0] - return ns -} -func putMemberNames(ns *memberNames) { - if cap(*ns) < 1<<10 { - for i := range *ns { - (*ns)[i] = memberName{} // avoid pinning name - } - memberNamePool.Put(ns) - } -} - -type memberNames []memberName - -func (m *memberNames) Len() int { return len(*m) } -func (m *memberNames) Less(i, j int) bool { return lessUTF16((*m)[i].name, (*m)[j].name) } -func (m *memberNames) Swap(i, j int) { (*m)[i], (*m)[j] = (*m)[j], (*m)[i] } - -// reorderObjects recursively reorders all object members in place -// according to the ordering specified in RFC 8785, section 3.2.3. -// -// Pre-conditions: -// - The value is valid (i.e., no decoder errors should ever occur). -// - The value is compact (i.e., no whitespace is present). -// - Initial call is provided a Decoder reading from the start of v. -// -// Post-conditions: -// - Exactly one JSON value is read from the Decoder. -// - All fully-parsed JSON objects are reordered by directly moving -// the members in the value buffer. -// -// The runtime is approximately O(n·log(n)) + O(m·log(m)), -// where n is len(v) and m is the total number of object members. -func reorderObjects(d *Decoder, scratch *[]byte) { - switch tok, _ := d.ReadToken(); tok.Kind() { - case '{': - // Iterate and collect the name and offsets for every object member. - members := getMemberNames() - defer putMemberNames(members) - var prevName []byte - isSorted := true - - beforeBody := d.InputOffset() // offset after '{' - for d.PeekKind() != '}' { - beforeName := d.InputOffset() - var flags valueFlags - name, _ := d.readValue(&flags) - name = unescapeStringMayCopy(name, flags.isVerbatim()) - reorderObjects(d, scratch) - afterValue := d.InputOffset() - - if isSorted && len(*members) > 0 { - isSorted = lessUTF16(prevName, []byte(name)) - } - *members = append(*members, memberName{name, beforeName, afterValue}) - prevName = name - } - afterBody := d.InputOffset() // offset before '}' - d.ReadToken() - - // Sort the members; return early if it's already sorted. - if isSorted { - return - } - // TODO(https://go.dev/issue/47619): Use slices.Sort. - sort.Sort(members) - - // Append the reordered members to a new buffer, - // then copy the reordered members back over the original members. - // Avoid swapping in place since each member may be a different size - // where moving a member over a smaller member may corrupt the data - // for subsequent members before they have been moved. - // - // The following invariant must hold: - // sum([m.after-m.before for m in members]) == afterBody-beforeBody - sorted := (*scratch)[:0] - for i, member := range *members { - if d.buf[member.before] == ',' { - member.before++ // trim leading comma - } - sorted = append(sorted, d.buf[member.before:member.after]...) - if i < len(*members)-1 { - sorted = append(sorted, ',') // append trailing comma - } - } - if int(afterBody-beforeBody) != len(sorted) { - panic("BUG: length invariant violated") - } - copy(d.buf[beforeBody:afterBody], sorted) - - // Update scratch buffer to the largest amount ever used. - if len(sorted) > len(*scratch) { - *scratch = sorted - } - case '[': - for d.PeekKind() != ']' { - reorderObjects(d, scratch) - } - d.ReadToken() - } -} - -// lessUTF16 reports whether x is lexicographically less than y according -// to the UTF-16 codepoints of the UTF-8 encoded input strings. -// This implements the ordering specified in RFC 8785, section 3.2.3. -// The inputs must be valid UTF-8, otherwise this may panic. -func lessUTF16[Bytes []byte | string](x, y Bytes) bool { - // NOTE: This is an optimized, allocation-free implementation - // of lessUTF16Simple in fuzz_test.go. FuzzLessUTF16 verifies that the - // two implementations agree on the result of comparing any two strings. - - isUTF16Self := func(r rune) bool { - return ('\u0000' <= r && r <= '\uD7FF') || ('\uE000' <= r && r <= '\uFFFF') - } - - var invalidUTF8 bool - x0, y0 := x, y - for { - if len(x) == 0 || len(y) == 0 { - if len(x) == len(y) && invalidUTF8 { - return string(x0) < string(y0) - } - return len(x) < len(y) - } - - // ASCII fast-path. - if x[0] < utf8.RuneSelf || y[0] < utf8.RuneSelf { - if x[0] != y[0] { - return x[0] < y[0] - } - x, y = x[1:], y[1:] - continue - } - - // Decode next pair of runes as UTF-8. - // TODO(https://go.dev/issue/56948): Use a generic implementation - // of utf8.DecodeRune, or rely on a compiler optimization to statically - // hide the cost of a type switch (https://go.dev/issue/57072). - var rx, ry rune - var nx, ny int - switch any(x).(type) { - case string: - rx, nx = utf8.DecodeRuneInString(string(x)) - ry, ny = utf8.DecodeRuneInString(string(y)) - case []byte: - rx, nx = utf8.DecodeRune([]byte(x)) - ry, ny = utf8.DecodeRune([]byte(y)) - } - - selfx := isUTF16Self(rx) - selfy := isUTF16Self(ry) - switch { - // The x rune is a single UTF-16 codepoint, while - // the y rune is a surrogate pair of UTF-16 codepoints. - case selfx && !selfy: - ry, _ = utf16.EncodeRune(ry) - // The y rune is a single UTF-16 codepoint, while - // the x rune is a surrogate pair of UTF-16 codepoints. - case selfy && !selfx: - rx, _ = utf16.EncodeRune(rx) - } - if rx != ry { - return rx < ry - } - invalidUTF8 = invalidUTF8 || (rx == utf8.RuneError && nx == 1) || (ry == utf8.RuneError && ny == 1) - x, y = x[nx:], y[ny:] - } -} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go index 81280aae..06bcf0c3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go @@ -140,18 +140,20 @@ func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef { // to deduplicate) mapRelationship, err := getMapElementRelationship(specSchema.Extensions) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) } if len(mapRelationship) > 0 { return schema.TypeRef{ NamedType: &n, ElementRelationship: &mapRelationship, + Nullable: specSchema.Nullable, } } return schema.TypeRef{ NamedType: &n, + Nullable: specSchema.Nullable, } } @@ -164,7 +166,8 @@ func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef { c.pop(c2) return schema.TypeRef{ - Inlined: inlined, + Inlined: inlined, + Nullable: specSchema.Nullable, } } @@ -212,7 +215,7 @@ func (c *convert) parseObject(s *spec.Schema) *schema.Map { relationship, err := getMapElementRelationship(s.Extensions) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) } return &schema.Map{ @@ -225,7 +228,7 @@ func (c *convert) parseObject(s *spec.Schema) *schema.Map { func (c *convert) parseList(s *spec.Schema) *schema.List { relationship, mapKeys, err := getListElementRelationship(s.Extensions) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) } elementType := func() schema.TypeRef { if s.Items != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go index e40f6056..6a8b9f44 100644 --- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go @@ -72,7 +72,7 @@ func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema mapRelationship, err := getMapElementRelationship(model.GetExtensions()) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) } // empty string means unset. @@ -114,7 +114,7 @@ func (c *convert) VisitKind(k *proto.Kind) { unions, err := makeUnions(k.GetExtensions()) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) return } // TODO: We should check that the fields and discriminator @@ -129,14 +129,14 @@ func (c *convert) VisitKind(k *proto.Kind) { a.Map.ElementRelationship, err = getMapElementRelationship(k.GetExtensions()) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) } } func (c *convert) VisitArray(a *proto.Array) { relationship, mapKeys, err := getListElementRelationship(a.GetExtensions()) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) } atom := c.top() @@ -150,7 +150,7 @@ func (c *convert) VisitArray(a *proto.Array) { func (c *convert) VisitMap(m *proto.Map) { relationship, err := getMapElementRelationship(m.GetExtensions()) if err != nil { - c.reportError(err.Error()) + c.reportError("%v", err) } a := c.top() diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go index 1f62c6e7..1b3dfff1 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -46,14 +47,14 @@ func (e *Encoding) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (e *Encoding) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (e *Encoding) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { EncodingProps encodingPropsOmitZero `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Extensions = internal.SanitizeExtensions(e.Extensions) x.EncodingProps = encodingPropsOmitZero(e.EncodingProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (e *Encoding) UnmarshalJSON(data []byte) error { @@ -69,12 +70,12 @@ func (e *Encoding) UnmarshalJSON(data []byte) error { return nil } -func (e *Encoding) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (e *Encoding) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` EncodingProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go index 8834a92e..3edb1049 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -53,16 +54,16 @@ func (e *Example) MarshalJSON() ([]byte, error) { } return swag.ConcatJSON(b1, b2, b3), nil } -func (e *Example) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (e *Example) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { Ref string `json:"$ref,omitempty"` ExampleProps `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Ref = e.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(e.Extensions) x.ExampleProps = e.ExampleProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (e *Example) UnmarshalJSON(data []byte) error { @@ -81,12 +82,12 @@ func (e *Example) UnmarshalJSON(data []byte) error { return nil } -func (e *Example) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (e *Example) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` ExampleProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := internal.JSONRefFromMap(&e.Ref.Ref, x.Extensions); err != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go index f0515496..7a83c53c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -53,14 +54,14 @@ func (e *ExternalDocumentation) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (e *ExternalDocumentation) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (e *ExternalDocumentation) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { ExternalDocumentationProps `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Extensions = internal.SanitizeExtensions(e.Extensions) x.ExternalDocumentationProps = e.ExternalDocumentationProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { @@ -76,12 +77,12 @@ func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { return nil } -func (e *ExternalDocumentation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (e *ExternalDocumentation) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` ExternalDocumentationProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } e.Extensions = internal.SanitizeExtensions(x.Extensions) diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go index 9ea30628..475817f6 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -54,16 +55,16 @@ func (h *Header) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (h *Header) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (h *Header) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { Ref string `json:"$ref,omitempty"` HeaderProps headerPropsOmitZero `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Ref = h.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(h.Extensions) x.HeaderProps = headerPropsOmitZero(h.HeaderProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (h *Header) UnmarshalJSON(data []byte) error { @@ -83,12 +84,12 @@ func (h *Header) UnmarshalJSON(data []byte) error { return nil } -func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (h *Header) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` HeaderProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := internal.JSONRefFromMap(&h.Ref.Ref, x.Extensions); err != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go index 47eef1ed..c9062b23 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -49,14 +50,14 @@ func (m *MediaType) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (e *MediaType) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (e *MediaType) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { MediaTypeProps mediaTypePropsOmitZero `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Extensions = internal.SanitizeExtensions(e.Extensions) x.MediaTypeProps = mediaTypePropsOmitZero(e.MediaTypeProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (m *MediaType) UnmarshalJSON(data []byte) error { @@ -72,12 +73,12 @@ func (m *MediaType) UnmarshalJSON(data []byte) error { return nil } -func (m *MediaType) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (m *MediaType) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` MediaTypeProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } m.Extensions = internal.SanitizeExtensions(x.Extensions) diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go index f1e10254..8219b29d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -49,14 +50,14 @@ func (o *Operation) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (o *Operation) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (o *Operation) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` OperationProps operationPropsOmitZero `json:",inline"` } x.Extensions = internal.SanitizeExtensions(o.Extensions) x.OperationProps = operationPropsOmitZero(o.OperationProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON hydrates this items instance with the data from JSON @@ -70,12 +71,12 @@ func (o *Operation) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &o.VendorExtensible) } -func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (o *Operation) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` OperationProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } o.Extensions = internal.SanitizeExtensions(x.Extensions) diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go index ada7edb6..a5e7d46c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -54,16 +55,16 @@ func (p *Parameter) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (p *Parameter) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (p *Parameter) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { Ref string `json:"$ref,omitempty"` ParameterProps parameterPropsOmitZero `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Ref = p.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(p.Extensions) x.ParameterProps = parameterPropsOmitZero(p.ParameterProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (p *Parameter) UnmarshalJSON(data []byte) error { @@ -84,12 +85,12 @@ func (p *Parameter) UnmarshalJSON(data []byte) error { return nil } -func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (p *Parameter) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` ParameterProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go index 16fbbb4d..cb04cf0f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go @@ -24,6 +24,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -57,7 +58,7 @@ func (p *Paths) MarshalJSON() ([]byte, error) { return concated, nil } -func (p *Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (p *Paths) MarshalJSONTo(enc *jsontext.Encoder) error { m := make(map[string]any, len(p.Extensions)+len(p.Paths)) for k, v := range p.Extensions { if internal.IsExtensionKey(k) { @@ -69,7 +70,7 @@ func (p *Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) m[k] = v } } - return opts.MarshalNext(enc, m) + return jsonv2.MarshalEncode(enc, m) } // UnmarshalJSON hydrates this items instance with the data from JSON @@ -106,7 +107,7 @@ func (p *Paths) UnmarshalJSON(data []byte) error { return nil } -func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (p *Paths) UnmarshalJSONFrom(dec *jsontext.Decoder) error { tok, err := dec.ReadToken() if err != nil { return err @@ -129,7 +130,7 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco switch k := tok.String(); { case internal.IsExtensionKey(k): var ext any - if err := opts.UnmarshalNext(dec, &ext); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &ext); err != nil { return err } @@ -139,7 +140,7 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco p.Extensions[k] = ext case len(k) > 0 && k[0] == '/': pi := Path{} - if err := opts.UnmarshalNext(dec, &pi); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &pi); err != nil { return err } @@ -188,16 +189,16 @@ func (p *Path) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (p *Path) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (p *Path) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Ref string `json:"$ref,omitempty"` - spec.Extensions + Ref string `json:"$ref,omitempty"` + Extensions spec.Extensions `json:",inline"` PathProps } x.Ref = p.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(p.Extensions) x.PathProps = p.PathProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (p *Path) UnmarshalJSON(data []byte) error { @@ -216,13 +217,13 @@ func (p *Path) UnmarshalJSON(data []byte) error { return nil } -func (p *Path) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (p *Path) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` PathProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go index 6f8607e4..b39c0d4f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -54,16 +55,16 @@ func (r *RequestBody) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (r *RequestBody) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (r *RequestBody) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { Ref string `json:"$ref,omitempty"` RequestBodyProps requestBodyPropsOmitZero `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Ref = r.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(r.Extensions) x.RequestBodyProps = requestBodyPropsOmitZero(r.RequestBodyProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (r *RequestBody) UnmarshalJSON(data []byte) error { @@ -98,12 +99,12 @@ type requestBodyPropsOmitZero struct { Required bool `json:"required,omitzero"` } -func (r *RequestBody) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (r *RequestBody) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` RequestBodyProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go index 73e241fd..72ad9882 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go @@ -24,6 +24,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -51,11 +52,11 @@ func (r *Responses) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (r Responses) MarshalJSONTo(enc *jsontext.Encoder) error { type ArbitraryKeys map[string]interface{} var x struct { - ArbitraryKeys - Default *Response `json:"default,omitzero"` + ArbitraryKeys ArbitraryKeys `json:",inline"` + Default *Response `json:"default,omitzero"` } x.ArbitraryKeys = make(map[string]any, len(r.Extensions)+len(r.StatusCodeResponses)) for k, v := range r.Extensions { @@ -67,7 +68,7 @@ func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encod x.ArbitraryKeys[strconv.Itoa(k)] = v } x.Default = r.Default - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (r *Responses) UnmarshalJSON(data []byte) error { @@ -136,7 +137,7 @@ func (r *ResponsesProps) UnmarshalJSON(data []byte) error { return nil } -func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) (err error) { +func (r *Responses) UnmarshalJSONFrom(dec *jsontext.Decoder) (err error) { tok, err := dec.ReadToken() if err != nil { return err @@ -157,7 +158,7 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. switch k := tok.String(); { case internal.IsExtensionKey(k): var ext any - if err := opts.UnmarshalNext(dec, &ext); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &ext); err != nil { return err } @@ -167,14 +168,14 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. r.Extensions[k] = ext case k == "default": resp := Response{} - if err := opts.UnmarshalNext(dec, &resp); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &resp); err != nil { return err } r.ResponsesProps.Default = &resp default: if nk, err := strconv.Atoi(k); err == nil { resp := Response{} - if err := opts.UnmarshalNext(dec, &resp); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &resp); err != nil { return err } @@ -219,16 +220,16 @@ func (r *Response) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (r Response) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (r Response) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Ref string `json:"$ref,omitempty"` - spec.Extensions + Ref string `json:"$ref,omitempty"` + Extensions spec.Extensions `json:",inline"` ResponseProps `json:",inline"` } x.Ref = r.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(r.Extensions) x.ResponseProps = r.ResponseProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (r *Response) UnmarshalJSON(data []byte) error { @@ -247,12 +248,12 @@ func (r *Response) UnmarshalJSON(data []byte) error { return nil } -func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (r *Response) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` ResponseProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { @@ -302,16 +303,16 @@ func (r *Link) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (r *Link) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (r *Link) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Ref string `json:"$ref,omitempty"` - spec.Extensions - LinkProps `json:",inline"` + Ref string `json:"$ref,omitempty"` + Extensions spec.Extensions `json:",inline"` + LinkProps `json:",inline"` } x.Ref = r.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(r.Extensions) x.LinkProps = r.LinkProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (r *Link) UnmarshalJSON(data []byte) error { @@ -331,12 +332,12 @@ func (r *Link) UnmarshalJSON(data []byte) error { return nil } -func (l *Link) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (l *Link) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` LinkProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := internal.JSONRefFromMap(&l.Ref.Ref, x.Extensions); err != nil { diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go index dd1e98ed..9bc180ea 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -52,16 +53,16 @@ func (s *SecurityScheme) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (s *SecurityScheme) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s *SecurityScheme) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { Ref string `json:"$ref,omitempty"` SecuritySchemeProps `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Ref = s.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(s.Extensions) x.SecuritySchemeProps = s.SecuritySchemeProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON hydrates this items instance with the data from JSON diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go index 654a42c0..3037fbce 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -55,14 +56,14 @@ func (s *Server) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (s *Server) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s *Server) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { ServerProps `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Extensions = internal.SanitizeExtensions(s.Extensions) x.ServerProps = s.ServerProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (s *Server) UnmarshalJSON(data []byte) error { @@ -79,12 +80,12 @@ func (s *Server) UnmarshalJSON(data []byte) error { return nil } -func (s *Server) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *Server) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` ServerProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } s.Extensions = internal.SanitizeExtensions(x.Extensions) @@ -123,14 +124,14 @@ func (s *ServerVariable) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (s *ServerVariable) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s *ServerVariable) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { ServerVariableProps `json:",inline"` - spec.Extensions + Extensions spec.Extensions `json:",inline"` } x.Extensions = internal.SanitizeExtensions(s.Extensions) x.ServerVariableProps = s.ServerVariableProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } func (s *ServerVariable) UnmarshalJSON(data []byte) error { @@ -146,12 +147,12 @@ func (s *ServerVariable) UnmarshalJSON(data []byte) error { return nil } -func (s *ServerVariable) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *ServerVariable) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - spec.Extensions + Extensions spec.Extensions `json:",inline"` ServerVariableProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } s.Extensions = internal.SanitizeExtensions(x.Extensions) diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go index 5db819c7..91b1ae33 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go @@ -21,6 +21,7 @@ import ( "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -60,7 +61,7 @@ func (o *OpenAPI) MarshalJSON() ([]byte, error) { return json.Marshal(&p) } -func (o *OpenAPI) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (o *OpenAPI) MarshalJSONTo(enc *jsontext.Encoder) error { type OpenAPIOmitZero struct { Version string `json:"openapi"` Info *spec.Info `json:"info"` @@ -71,5 +72,5 @@ func (o *OpenAPI) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encode ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"` } x := (*OpenAPIOmitZero)(o) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go index 05310c46..5aa66ae2 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) const ( @@ -65,18 +66,18 @@ func (h Header) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4), nil } -func (h Header) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (h Header) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { CommonValidations commonValidationsOmitZero `json:",inline"` SimpleSchema simpleSchemaOmitZero `json:",inline"` - Extensions + Extensions Extensions `json:",inline"` HeaderProps } x.CommonValidations = commonValidationsOmitZero(h.CommonValidations) x.SimpleSchema = simpleSchemaOmitZero(h.SimpleSchema) x.Extensions = internal.SanitizeExtensions(h.Extensions) x.HeaderProps = h.HeaderProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON unmarshals this header from JSON @@ -97,15 +98,15 @@ func (h *Header) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &h.HeaderProps) } -func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (h *Header) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { CommonValidations SimpleSchema - Extensions + Extensions Extensions `json:",inline"` HeaderProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go index d667b705..8d002a1c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go @@ -21,6 +21,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // Extensions vendor specific extensions @@ -183,14 +184,14 @@ func (i Info) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (i Info) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (i Info) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` InfoProps } x.Extensions = i.Extensions x.InfoProps = i.InfoProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON marshal this from JSON @@ -205,12 +206,12 @@ func (i *Info) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &i.VendorExtensible) } -func (i *Info) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (i *Info) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` InfoProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } i.Extensions = internal.SanitizeExtensions(x.Extensions) diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go index 4132467d..6fbb19a4 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) const ( @@ -122,13 +123,13 @@ func (i *Items) UnmarshalJSON(data []byte) error { return nil } -func (i *Items) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (i *Items) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { CommonValidations SimpleSchema - Extensions + Extensions Extensions `json:",inline"` } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := i.Refable.Ref.fromMap(x.Extensions); err != nil { @@ -165,16 +166,16 @@ func (i Items) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b4, b3, b1, b2), nil } -func (i Items) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (i Items) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { CommonValidations commonValidationsOmitZero `json:",inline"` SimpleSchema simpleSchemaOmitZero `json:",inline"` Ref string `json:"$ref,omitempty"` - Extensions + Extensions Extensions `json:",inline"` } x.CommonValidations = commonValidationsOmitZero(i.CommonValidations) x.SimpleSchema = simpleSchemaOmitZero(i.SimpleSchema) x.Ref = i.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(i.Extensions) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go index 63eed346..99b620f9 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // OperationProps describes an operation @@ -104,13 +105,13 @@ func (o *Operation) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &o.VendorExtensible) } -func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (o *Operation) UnmarshalJSONFrom(dec *jsontext.Decoder) error { type OperationPropsNoMethods OperationProps // strip MarshalJSON method var x struct { - Extensions + Extensions Extensions `json:",inline"` OperationPropsNoMethods } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } o.Extensions = internal.SanitizeExtensions(x.Extensions) @@ -135,12 +136,12 @@ func (o Operation) MarshalJSON() ([]byte, error) { return concated, nil } -func (o Operation) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (o Operation) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` OperationProps operationPropsOmitZero `json:",inline"` } x.Extensions = internal.SanitizeExtensions(o.Extensions) x.OperationProps = operationPropsOmitZero(o.OperationProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go index 53d1e0aa..f2e61a72 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // ParamProps describes the specific attributes of an operation parameter @@ -107,14 +108,14 @@ func (p *Parameter) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &p.ParamProps) } -func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (p *Parameter) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { CommonValidations SimpleSchema - Extensions + Extensions Extensions `json:",inline"` ParamProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { @@ -155,18 +156,18 @@ func (p Parameter) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b3, b1, b2, b4, b5), nil } -func (p Parameter) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (p Parameter) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { CommonValidations commonValidationsOmitZero `json:",inline"` SimpleSchema simpleSchemaOmitZero `json:",inline"` ParamProps paramPropsOmitZero `json:",inline"` Ref string `json:"$ref,omitempty"` - Extensions + Extensions Extensions `json:",inline"` } x.CommonValidations = commonValidationsOmitZero(p.CommonValidations) x.SimpleSchema = simpleSchemaOmitZero(p.SimpleSchema) x.Extensions = internal.SanitizeExtensions(p.Extensions) x.ParamProps = paramPropsOmitZero(p.ParamProps) x.Ref = p.Refable.Ref.String() - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go index 1d1588cb..f2a0d954 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // PathItemProps the path item specific properties @@ -61,13 +62,13 @@ func (p *PathItem) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &p.PathItemProps) } -func (p *PathItem) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (p *PathItem) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` PathItemProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { @@ -100,14 +101,14 @@ func (p PathItem) MarshalJSON() ([]byte, error) { return concated, nil } -func (p PathItem) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (p PathItem) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Ref string `json:"$ref,omitempty"` - Extensions + Ref string `json:"$ref,omitempty"` + Extensions Extensions `json:",inline"` PathItemProps } x.Ref = p.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(p.Extensions) x.PathItemProps = p.PathItemProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go index 18f6a9f4..23b72ccc 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go @@ -22,6 +22,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // Paths holds the relative paths to the individual endpoints. @@ -70,7 +71,7 @@ func (p *Paths) UnmarshalJSON(data []byte) error { return nil } -func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (p *Paths) UnmarshalJSONFrom(dec *jsontext.Decoder) error { tok, err := dec.ReadToken() if err != nil { return err @@ -94,7 +95,7 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco switch k := tok.String(); { case internal.IsExtensionKey(k): ext = nil - if err := opts.UnmarshalNext(dec, &ext); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &ext); err != nil { return err } @@ -104,7 +105,7 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco p.Extensions[k] = ext case len(k) > 0 && k[0] == '/': pi = PathItem{} - if err := opts.UnmarshalNext(dec, &pi); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &pi); err != nil { return err } @@ -148,7 +149,7 @@ func (p Paths) MarshalJSON() ([]byte, error) { return concated, nil } -func (p Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (p Paths) MarshalJSONTo(enc *jsontext.Encoder) error { m := make(map[string]any, len(p.Extensions)+len(p.Paths)) for k, v := range p.Extensions { if internal.IsExtensionKey(k) { @@ -160,5 +161,5 @@ func (p Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) m[k] = v } } - return opts.MarshalNext(enc, m) + return jsonv2.MarshalEncode(enc, m) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go index 3ff1fe13..585a93ac 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // ResponseProps properties specific to a response @@ -67,13 +68,13 @@ func (r *Response) UnmarshalJSON(data []byte) error { return nil } -func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (r *Response) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { ResponseProps - Extensions + Extensions Extensions `json:",inline"` } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } @@ -106,16 +107,16 @@ func (r Response) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } -func (r Response) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (r Response) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Ref string `json:"$ref,omitempty"` - Extensions + Ref string `json:"$ref,omitempty"` + Extensions Extensions `json:",inline"` ResponseProps responsePropsOmitZero `json:",inline"` } x.Ref = r.Refable.Ref.String() x.Extensions = internal.SanitizeExtensions(r.Extensions) x.ResponseProps = responsePropsOmitZero(r.ResponseProps) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // NewResponse creates a new response instance diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go index d9ad760a..a1a3d0fd 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go @@ -23,6 +23,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // Responses is a container for the expected responses of an operation. @@ -78,11 +79,11 @@ func (r Responses) MarshalJSON() ([]byte, error) { return concated, nil } -func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (r Responses) MarshalJSONTo(enc *jsontext.Encoder) error { type ArbitraryKeys map[string]interface{} var x struct { - ArbitraryKeys - Default *Response `json:"default,omitempty"` + ArbitraryKeys ArbitraryKeys `json:",inline"` + Default *Response `json:"default,omitempty"` } x.ArbitraryKeys = make(map[string]any, len(r.Extensions)+len(r.StatusCodeResponses)) for k, v := range r.Extensions { @@ -94,7 +95,7 @@ func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encod x.ArbitraryKeys[strconv.Itoa(k)] = v } x.Default = r.Default - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // ResponsesProps describes all responses for an operation. @@ -150,7 +151,7 @@ func (r *ResponsesProps) UnmarshalJSON(data []byte) error { return nil } -func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) (err error) { +func (r *Responses) UnmarshalJSONFrom(dec *jsontext.Decoder) (err error) { tok, err := dec.ReadToken() if err != nil { return err @@ -172,7 +173,7 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. switch k := tok.String(); { case internal.IsExtensionKey(k): ext = nil - if err := opts.UnmarshalNext(dec, &ext); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &ext); err != nil { return err } @@ -182,7 +183,7 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. r.Extensions[k] = ext case k == "default": resp = Response{} - if err := opts.UnmarshalNext(dec, &resp); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &resp); err != nil { return err } @@ -191,7 +192,7 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. default: if nk, err := strconv.Atoi(k); err == nil { resp = Response{} - if err := opts.UnmarshalNext(dec, &resp); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &resp); err != nil { return err } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go index dfbb2e05..6c0c6fc1 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go @@ -23,6 +23,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // BooleanProperty creates a boolean property @@ -517,10 +518,10 @@ func (s Schema) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil } -func (s Schema) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s Schema) MarshalJSONTo(enc *jsontext.Encoder) error { type ArbitraryKeys map[string]interface{} var x struct { - ArbitraryKeys + ArbitraryKeys ArbitraryKeys `json:",inline"` SchemaProps schemaPropsOmitZero `json:",inline"` SwaggerSchemaProps swaggerSchemaPropsOmitZero `json:",inline"` Schema string `json:"$schema,omitempty"` @@ -539,7 +540,7 @@ func (s Schema) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) x.SwaggerSchemaProps = swaggerSchemaPropsOmitZero(s.SwaggerSchemaProps) x.Ref = s.Ref.String() x.Schema = string(s.Schema) - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON marshal this from JSON @@ -595,13 +596,13 @@ func (s *Schema) UnmarshalJSON(data []byte) error { return nil } -func (s *Schema) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *Schema) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` SchemaProps SwaggerSchemaProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go index e2b7da14..7c7b6bdd 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // SecuritySchemeProps describes a swagger security scheme in the securityDefinitions section @@ -60,14 +61,14 @@ func (s SecurityScheme) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (s SecurityScheme) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s SecurityScheme) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` SecuritySchemeProps } x.Extensions = internal.SanitizeExtensions(s.Extensions) x.SecuritySchemeProps = s.SecuritySchemeProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON marshal this from JSON @@ -78,12 +79,12 @@ func (s *SecurityScheme) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &s.VendorExtensible) } -func (s *SecurityScheme) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *SecurityScheme) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` SecuritySchemeProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } s.Extensions = internal.SanitizeExtensions(x.Extensions) diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go index c8f3beaa..533b7cc8 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go @@ -21,6 +21,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // Swagger this is the root document object for the API specification. @@ -50,14 +51,14 @@ func (s Swagger) MarshalJSON() ([]byte, error) { } // MarshalJSON marshals this swagger structure to json -func (s Swagger) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s Swagger) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` SwaggerProps } x.Extensions = internal.SanitizeExtensions(s.Extensions) x.SwaggerProps = s.SwaggerProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON unmarshals a swagger spec from json @@ -76,16 +77,16 @@ func (s *Swagger) UnmarshalJSON(data []byte) error { return nil } -func (s *Swagger) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *Swagger) UnmarshalJSONFrom(dec *jsontext.Decoder) error { // Note: If you're willing to make breaking changes, it is possible to // optimize this and other usages of this pattern: // https://github.com/kubernetes/kube-openapi/pull/319#discussion_r983165948 var x struct { - Extensions + Extensions Extensions `json:",inline"` SwaggerProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } s.Extensions = internal.SanitizeExtensions(x.Extensions) @@ -146,15 +147,15 @@ func (s SchemaOrBool) MarshalJSON() ([]byte, error) { } // MarshalJSON convert this object to JSON -func (s SchemaOrBool) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s SchemaOrBool) MarshalJSONTo(enc *jsontext.Encoder) error { if s.Schema != nil { - return opts.MarshalNext(enc, s.Schema) + return jsonv2.MarshalEncode(enc, s.Schema) } if s.Schema == nil && !s.Allows { - return enc.WriteToken(jsonv2.False) + return enc.WriteToken(jsontext.False) } - return enc.WriteToken(jsonv2.True) + return enc.WriteToken(jsontext.True) } // UnmarshalJSON converts this bool or schema object from a JSON structure @@ -178,17 +179,17 @@ func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { return nil } -func (s *SchemaOrBool) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *SchemaOrBool) UnmarshalJSONFrom(dec *jsontext.Decoder) error { switch k := dec.PeekKind(); k { case '{': - err := opts.UnmarshalNext(dec, &s.Schema) + err := jsonv2.UnmarshalDecode(dec, &s.Schema) if err != nil { return err } s.Allows = true return nil case 't', 'f': - err := opts.UnmarshalNext(dec, &s.Allows) + err := jsonv2.UnmarshalDecode(dec, &s.Allows) if err != nil { return err } @@ -219,14 +220,14 @@ func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { } // MarshalJSON converts this schema object or array into JSON structure -func (s SchemaOrStringArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s SchemaOrStringArray) MarshalJSONTo(enc *jsontext.Encoder) error { if len(s.Property) > 0 { - return opts.MarshalNext(enc, s.Property) + return jsonv2.MarshalEncode(enc, s.Property) } if s.Schema != nil { - return opts.MarshalNext(enc, s.Schema) + return jsonv2.MarshalEncode(enc, s.Schema) } - return enc.WriteToken(jsonv2.Null) + return enc.WriteToken(jsontext.Null) } // UnmarshalJSON converts this schema object or array from a JSON structure @@ -256,12 +257,12 @@ func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error { return nil } -func (s *SchemaOrStringArray) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *SchemaOrStringArray) UnmarshalJSONFrom(dec *jsontext.Decoder) error { switch dec.PeekKind() { case '{': - return opts.UnmarshalNext(dec, &s.Schema) + return jsonv2.UnmarshalDecode(dec, &s.Schema) case '[': - return opts.UnmarshalNext(dec, &s.Property) + return jsonv2.UnmarshalDecode(dec, &s.Property) default: _, err := dec.ReadValue() return err @@ -332,14 +333,14 @@ func (s *StringOrArray) UnmarshalJSON(data []byte) error { } } -func (s *StringOrArray) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *StringOrArray) UnmarshalJSONFrom(dec *jsontext.Decoder) error { switch k := dec.PeekKind(); k { case '[': *s = StringOrArray{} - return opts.UnmarshalNext(dec, (*[]string)(s)) + return jsonv2.UnmarshalDecode(dec, (*[]string)(s)) case '"': *s = StringOrArray{""} - return opts.UnmarshalNext(dec, &(*s)[0]) + return jsonv2.UnmarshalDecode(dec, &(*s)[0]) case 'n': // Throw out null token _, _ = dec.ReadToken() @@ -392,11 +393,11 @@ func (s SchemaOrArray) MarshalJSON() ([]byte, error) { } // MarshalJSON converts this schema object or array into JSON structure -func (s SchemaOrArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (s SchemaOrArray) MarshalJSONTo(enc *jsontext.Encoder) error { if s.Schemas != nil { - return opts.MarshalNext(enc, s.Schemas) + return jsonv2.MarshalEncode(enc, s.Schemas) } - return opts.MarshalNext(enc, s.Schema) + return jsonv2.MarshalEncode(enc, s.Schema) } // UnmarshalJSON converts this schema object or array from a JSON structure @@ -426,12 +427,12 @@ func (s *SchemaOrArray) UnmarshalJSON(data []byte) error { return nil } -func (s *SchemaOrArray) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (s *SchemaOrArray) UnmarshalJSONFrom(dec *jsontext.Decoder) error { switch dec.PeekKind() { case '{': - return opts.UnmarshalNext(dec, &s.Schema) + return jsonv2.UnmarshalDecode(dec, &s.Schema) case '[': - return opts.UnmarshalNext(dec, &s.Schemas) + return jsonv2.UnmarshalDecode(dec, &s.Schemas) default: _, err := dec.ReadValue() return err diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go index d105d52c..89c3d0d8 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go @@ -20,6 +20,7 @@ import ( "github.com/go-openapi/swag" "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext" ) // TagProps describe a tag entry in the top level tags section of a swagger spec @@ -55,14 +56,14 @@ func (t Tag) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } -func (t Tag) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { +func (t Tag) MarshalJSONTo(enc *jsontext.Encoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` TagProps } x.Extensions = internal.SanitizeExtensions(t.Extensions) x.TagProps = t.TagProps - return opts.MarshalNext(enc, x) + return jsonv2.MarshalEncode(enc, x) } // UnmarshalJSON marshal this from JSON @@ -77,12 +78,12 @@ func (t *Tag) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &t.VendorExtensible) } -func (t *Tag) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { +func (t *Tag) UnmarshalJSONFrom(dec *jsontext.Decoder) error { var x struct { - Extensions + Extensions Extensions `json:",inline"` TagProps } - if err := opts.UnmarshalNext(dec, &x); err != nil { + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } t.Extensions = internal.SanitizeExtensions(x.Extensions) diff --git a/vendor/k8s.io/utils/ptr/OWNERS b/vendor/k8s.io/utils/ptr/OWNERS index 0d639275..55da8262 100644 --- a/vendor/k8s.io/utils/ptr/OWNERS +++ b/vendor/k8s.io/utils/ptr/OWNERS @@ -2,9 +2,11 @@ approvers: - apelisse +- skitt - stewart-yu - thockin reviewers: - apelisse +- skitt - stewart-yu - thockin diff --git a/vendor/k8s.io/utils/ptr/ptr.go b/vendor/k8s.io/utils/ptr/ptr.go index 659ed3b9..ea847fd3 100644 --- a/vendor/k8s.io/utils/ptr/ptr.go +++ b/vendor/k8s.io/utils/ptr/ptr.go @@ -51,7 +51,7 @@ func To[T any](v T) *T { return &v } -// Deref dereferences ptr and returns the value it points to if no nil, or else +// Deref dereferences ptr and returns the value it points to if not nil, or else // returns def. func Deref[T any](ptr *T, def T) T { if ptr != nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index ef3de050..17eb7ff8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,3 +1,28 @@ +# cel.dev/cel-go v0.32.0 +## explicit; go 1.23.0 +cel.dev/cel-go/cel +cel.dev/cel-go/cel/async +cel.dev/cel-go/checker +cel.dev/cel-go/checker/decls +cel.dev/cel-go/common +cel.dev/cel-go/common/ast +cel.dev/cel-go/common/containers +cel.dev/cel-go/common/cost +cel.dev/cel-go/common/debug +cel.dev/cel-go/common/decls +cel.dev/cel-go/common/env +cel.dev/cel-go/common/functions +cel.dev/cel-go/common/operators +cel.dev/cel-go/common/overloads +cel.dev/cel-go/common/runes +cel.dev/cel-go/common/stdlib +cel.dev/cel-go/common/types +cel.dev/cel-go/common/types/pb +cel.dev/cel-go/common/types/ref +cel.dev/cel-go/common/types/traits +cel.dev/cel-go/interpreter +cel.dev/cel-go/parser +cel.dev/cel-go/parser/gen # cel.dev/expr v0.25.2 ## explicit; go 1.23.0 cel.dev/expr @@ -22,7 +47,7 @@ github.com/cespare/xxhash/v2 # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/docker/cli v29.6.2+incompatible +# github.com/docker/cli v29.7.2+incompatible ## explicit github.com/docker/cli/cli/config github.com/docker/cli/cli/config/configfile @@ -33,7 +58,7 @@ github.com/docker/cli/cli/config/types ## explicit; go 1.21 github.com/docker/docker-credential-helpers/client github.com/docker/docker-credential-helpers/credentials -# github.com/emicklei/go-restful/v3 v3.12.2 +# github.com/emicklei/go-restful/v3 v3.13.0 ## explicit; go 1.13 github.com/emicklei/go-restful/v3 github.com/emicklei/go-restful/v3/log @@ -41,10 +66,10 @@ github.com/emicklei/go-restful/v3/log ## explicit; go 1.18 github.com/evanphx/json-patch/v5 github.com/evanphx/json-patch/v5/internal/json -# github.com/felixge/httpsnoop v1.0.4 -## explicit; go 1.13 +# github.com/felixge/httpsnoop v1.1.0 +## explicit; go 1.25 github.com/felixge/httpsnoop -# github.com/fxamacker/cbor/v2 v2.9.0 +# github.com/fxamacker/cbor/v2 v2.9.1 ## explicit; go 1.20 github.com/fxamacker/cbor/v2 # github.com/go-logr/logr v1.4.4 @@ -58,40 +83,53 @@ github.com/go-logr/stdr # github.com/go-logr/zapr v1.3.0 ## explicit; go 1.18 github.com/go-logr/zapr -# github.com/go-openapi/jsonpointer v0.21.1 -## explicit; go 1.20 +# github.com/go-openapi/jsonpointer v1.0.0 +## explicit; go 1.25.0 github.com/go-openapi/jsonpointer -# github.com/go-openapi/jsonreference v0.21.0 -## explicit; go 1.20 +github.com/go-openapi/jsonpointer/jsonname +# github.com/go-openapi/jsonreference v1.0.0 +## explicit; go 1.25.0 github.com/go-openapi/jsonreference github.com/go-openapi/jsonreference/internal -# github.com/go-openapi/swag v0.23.1 -## explicit; go 1.20 +# github.com/go-openapi/swag v0.27.1 +## explicit; go 1.25.0 github.com/go-openapi/swag -# github.com/google/cel-go v0.31.0 -## explicit; go 1.23.0 -github.com/google/cel-go/cel -github.com/google/cel-go/cel/async -github.com/google/cel-go/checker -github.com/google/cel-go/checker/decls -github.com/google/cel-go/common -github.com/google/cel-go/common/ast -github.com/google/cel-go/common/containers -github.com/google/cel-go/common/debug -github.com/google/cel-go/common/decls -github.com/google/cel-go/common/env -github.com/google/cel-go/common/functions -github.com/google/cel-go/common/operators -github.com/google/cel-go/common/overloads -github.com/google/cel-go/common/runes -github.com/google/cel-go/common/stdlib -github.com/google/cel-go/common/types -github.com/google/cel-go/common/types/pb -github.com/google/cel-go/common/types/ref -github.com/google/cel-go/common/types/traits -github.com/google/cel-go/interpreter -github.com/google/cel-go/parser -github.com/google/cel-go/parser/gen +# github.com/go-openapi/swag/cmdutils v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/cmdutils +# github.com/go-openapi/swag/conv v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/conv +# github.com/go-openapi/swag/fileutils v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/fileutils +# github.com/go-openapi/swag/jsonutils v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/jsonutils +github.com/go-openapi/swag/jsonutils/adapters +github.com/go-openapi/swag/jsonutils/adapters/ifaces +github.com/go-openapi/swag/jsonutils/adapters/stdlib/json +# github.com/go-openapi/swag/loading v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/loading +# github.com/go-openapi/swag/mangling v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/mangling +# github.com/go-openapi/swag/netutils v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/netutils +# github.com/go-openapi/swag/pools v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/pools +# github.com/go-openapi/swag/stringutils v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/stringutils +# github.com/go-openapi/swag/typeutils v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/typeutils +# github.com/go-openapi/swag/yamlutils v0.27.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/yamlutils # github.com/google/gnostic-models v0.7.0 ## explicit; go 1.22 github.com/google/gnostic-models/compiler @@ -106,11 +144,12 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/go-containerregistry v0.21.9 +# github.com/google/go-containerregistry v0.22.1 ## explicit; go 1.25.0 github.com/google/go-containerregistry/internal/and github.com/google/go-containerregistry/internal/compression github.com/google/go-containerregistry/internal/gzip +github.com/google/go-containerregistry/internal/ipaddr github.com/google/go-containerregistry/internal/limit github.com/google/go-containerregistry/internal/redact github.com/google/go-containerregistry/internal/retry @@ -144,16 +183,13 @@ github.com/grpc-ecosystem/grpc-gateway/v2/utilities ## explicit; go 1.12 github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru/simplelru -# github.com/josharian/intern v1.0.0 -## explicit; go 1.5 -github.com/josharian/intern # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go # github.com/kelseyhightower/envconfig v1.4.0 ## explicit github.com/kelseyhightower/envconfig -# github.com/klauspost/compress v1.19.1 +# github.com/klauspost/compress v1.19.2 ## explicit; go 1.24 github.com/klauspost/compress github.com/klauspost/compress/fse @@ -163,11 +199,6 @@ github.com/klauspost/compress/internal/le github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash -# github.com/mailru/easyjson v0.9.0 -## explicit; go 1.20 -github.com/mailru/easyjson/buffer -github.com/mailru/easyjson/jlexer -github.com/mailru/easyjson/jwriter # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd ## explicit github.com/modern-go/concurrent @@ -195,10 +226,10 @@ github.com/prometheus/client_golang/prometheus github.com/prometheus/client_golang/prometheus/internal github.com/prometheus/client_golang/prometheus/promhttp github.com/prometheus/client_golang/prometheus/promhttp/internal -# github.com/prometheus/client_model v0.6.2 -## explicit; go 1.22.0 +# github.com/prometheus/client_model v0.6.3 +## explicit; go 1.23 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.70.1 +# github.com/prometheus/common v0.71.0 ## explicit; go 1.25.0 github.com/prometheus/common/expfmt github.com/prometheus/common/model @@ -210,8 +241,8 @@ github.com/prometheus/otlptranslator github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util -# github.com/sirupsen/logrus v1.9.4 -## explicit; go 1.17 +# github.com/sirupsen/logrus v1.10.2 +## explicit; go 1.23 github.com/sirupsen/logrus # github.com/spf13/pflag v1.0.10 ## explicit; go 1.12 @@ -222,8 +253,8 @@ github.com/stretchr/testify/assert github.com/stretchr/testify/assert/yaml github.com/stretchr/testify/internal/difflib github.com/stretchr/testify/internal/spew -# github.com/tektoncd/pipeline v1.16.0 -## explicit; go 1.26.4 +# github.com/tektoncd/pipeline v1.17.0 +## explicit; go 1.27.0 github.com/tektoncd/pipeline/internal/artifactref github.com/tektoncd/pipeline/pkg/apis/config github.com/tektoncd/pipeline/pkg/apis/pipeline @@ -438,8 +469,8 @@ go.yaml.in/yaml/v3 # golang.org/x/exp v0.0.0-20250808145144-a408d31f581a ## explicit; go 1.23.0 golang.org/x/exp/slices -# golang.org/x/mod v0.38.0 -## explicit; go 1.25.0 +# golang.org/x/mod v0.41.0 +## explicit; go 1.26.0 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/module golang.org/x/mod/semver @@ -454,24 +485,24 @@ golang.org/x/net/internal/httpcommon golang.org/x/net/internal/httpsfv golang.org/x/net/internal/timeseries golang.org/x/net/trace -# golang.org/x/oauth2 v0.36.0 -## explicit; go 1.25.0 +# golang.org/x/oauth2 v0.37.0 +## explicit; go 1.26.0 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.22.0 -## explicit; go 1.25.0 +# golang.org/x/sync v0.23.0 +## explicit; go 1.26.0 golang.org/x/sync/errgroup -# golang.org/x/sys v0.47.0 -## explicit; go 1.25.0 +# golang.org/x/sys v0.48.0 +## explicit; go 1.26.0 golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/term v0.45.0 -## explicit; go 1.25.0 +# golang.org/x/term v0.46.0 +## explicit; go 1.26.0 golang.org/x/term -# golang.org/x/text v0.41.0 -## explicit; go 1.25.0 +# golang.org/x/text v0.42.0 +## explicit; go 1.26.0 golang.org/x/text/cases golang.org/x/text/internal golang.org/x/text/internal/language @@ -485,7 +516,7 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.15.0 ## explicit; go 1.25.0 golang.org/x/time/rate -# golang.org/x/tools v0.48.0 +# golang.org/x/tools v0.49.0 ## explicit; go 1.25.0 golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/ast/edge @@ -493,7 +524,6 @@ golang.org/x/tools/go/ast/inspector golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/packages golang.org/x/tools/go/types/objectpath -golang.org/x/tools/go/types/typeutil golang.org/x/tools/imports golang.org/x/tools/internal/aliases golang.org/x/tools/internal/event @@ -505,10 +535,10 @@ golang.org/x/tools/internal/gocommand golang.org/x/tools/internal/gopathwalk golang.org/x/tools/internal/imports golang.org/x/tools/internal/modindex +golang.org/x/tools/internal/moremaps golang.org/x/tools/internal/packagesinternal golang.org/x/tools/internal/pkgbits golang.org/x/tools/internal/stdlib -golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal golang.org/x/tools/internal/versions # gomodules.xyz/jsonpatch/v2 v2.5.0 @@ -518,11 +548,11 @@ gomodules.xyz/jsonpatch/v2 ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/api/expr/v1alpha1 google.golang.org/genproto/googleapis/api/httpbody -# google.golang.org/genproto/googleapis/rpc v0.0.0-20260720155508-bb71a54f79dc +# google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.83.2 +# google.golang.org/grpc v1.84.0 ## explicit; go 1.25.0 google.golang.org/grpc google.golang.org/grpc/attributes @@ -641,9 +671,6 @@ gopkg.in/evanphx/json-patch.v4 # gopkg.in/inf.v0 v0.9.1 ## explicit gopkg.in/inf.v0 -# gopkg.in/yaml.v3 v3.0.1 -## explicit -gopkg.in/yaml.v3 # gotest.tools/v3 v3.5.2 ## explicit; go 1.17 # k8s.io/api v0.35.9 @@ -707,11 +734,11 @@ k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 k8s.io/api/storagemigration/v1beta1 -# k8s.io/apiextensions-apiserver v0.35.8 +# k8s.io/apiextensions-apiserver v0.35.9 ## explicit; go 1.25.0 k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 -# k8s.io/apimachinery v0.36.5 +# k8s.io/apimachinery v0.37.1 ## explicit; go 1.26.0 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -1148,8 +1175,8 @@ k8s.io/klog/v2/internal/severity k8s.io/klog/v2/internal/sloghandler k8s.io/klog/v2/internal/verbosity k8s.io/klog/v2/textlogger -# k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a -## explicit; go 1.23.0 +# k8s.io/kube-openapi v0.0.0-20260821135717-be32def86098 +## explicit; go 1.25.0 k8s.io/kube-openapi/cmd/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen/args k8s.io/kube-openapi/pkg/cached @@ -1159,13 +1186,18 @@ k8s.io/kube-openapi/pkg/generators/rules k8s.io/kube-openapi/pkg/handler3 k8s.io/kube-openapi/pkg/internal k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json +k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal +k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonflags +k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonopts +k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/internal/jsonwire +k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/jsontext k8s.io/kube-openapi/pkg/schemaconv k8s.io/kube-openapi/pkg/spec3 k8s.io/kube-openapi/pkg/util k8s.io/kube-openapi/pkg/util/proto k8s.io/kube-openapi/pkg/util/sets k8s.io/kube-openapi/pkg/validation/spec -# k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 +# k8s.io/utils v0.0.0-20260626114624-be93311217bd ## explicit; go 1.23 k8s.io/utils/buffer k8s.io/utils/clock @@ -1250,7 +1282,7 @@ sigs.k8s.io/json/internal/golang/encoding/json ## explicit; go 1.18 sigs.k8s.io/randfill sigs.k8s.io/randfill/bytesource -# sigs.k8s.io/structured-merge-diff/v6 v6.3.3 +# sigs.k8s.io/structured-merge-diff/v6 v6.4.2 ## explicit; go 1.23 sigs.k8s.io/structured-merge-diff/v6/fieldpath sigs.k8s.io/structured-merge-diff/v6/merge diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go index 73436912..f1607601 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/element.go @@ -19,7 +19,7 @@ package fieldpath import ( "fmt" "iter" - "sort" + "slices" "strings" "sigs.k8s.io/structured-merge-diff/v6/value" @@ -255,19 +255,13 @@ func (s PathElementSet) Copy() PathElementSet { // Insert adds pe to the set. func (s *PathElementSet) Insert(pe PathElement) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a, b PathElement) int { + return a.Compare(b) }) - if loc == len(s.members) { - s.members = append(s.members, pe) + if found { return } - if s.members[loc].Equals(pe) { - return - } - s.members = append(s.members, PathElement{}) - copy(s.members[loc+1:], s.members[loc:]) - s.members[loc] = pe + s.members = slices.Insert(s.members, loc, pe) } // Union returns a set containing elements that appear in either s or s2. @@ -344,16 +338,10 @@ func (s *PathElementSet) Size() int { return len(s.members) } // Has returns true if pe is a member of the set. func (s *PathElementSet) Has(pe PathElement) bool { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].Less(pe) + _, found := slices.BinarySearchFunc(s.members, pe, func(a, b PathElement) int { + return a.Compare(b) }) - if loc == len(s.members) { - return false - } - if s.members[loc].Equals(pe) { - return true - } - return false + return found } // Equals returns true if s and s2 have exactly the same members. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go index ff7ee510..ca50b84e 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/pathelementmap.go @@ -17,7 +17,7 @@ limitations under the License. package fieldpath import ( - "sort" + "slices" "sigs.k8s.io/structured-merge-diff/v6/value" ) @@ -82,32 +82,23 @@ func MakePathElementMap(size int) PathElementMap { // Insert adds the pathelement and associated value in the map. // If insert is called twice with the same PathElement, the value is replaced. func (s *PathElementMap) Insert(pe PathElement, v interface{}) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].PathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a pathElementValue, b PathElement) int { + return a.PathElement.Compare(b) }) - if loc == len(s.members) { - s.members = append(s.members, pathElementValue{pe, v}) - return - } - if s.members[loc].PathElement.Equals(pe) { + if found { s.members[loc].Value = v return } - s.members = append(s.members, pathElementValue{}) - copy(s.members[loc+1:], s.members[loc:]) - s.members[loc] = pathElementValue{pe, v} + s.members = slices.Insert(s.members, loc, pathElementValue{PathElement: pe, Value: v}) } // Get retrieves the value associated with the given PathElement from the map. // (nil, false) is returned if there is no such PathElement. func (s *PathElementMap) Get(pe PathElement) (interface{}, bool) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].PathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a pathElementValue, b PathElement) int { + return a.PathElement.Compare(b) }) - if loc == len(s.members) { - return nil, false - } - if s.members[loc].PathElement.Equals(pe) { + if found { return s.members[loc].Value, true } return nil, false diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go index f4b00c2e..b2f62dc6 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize-pe.go @@ -97,6 +97,14 @@ func DeserializePathElement(s string) (PathElement, error) { if err != nil { return PathElement{}, err } + // Lookahead validates that there is no unexpected trailing data. + // io.EOF is a successful termination indicator; all other errors or trailing data fail. + if iter.WhatIsNext(); iter.Error != io.EOF { + if iter.Error == nil { + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + } + return PathElement{}, iter.Error + } return PathElement{Value: &v}, nil case peKeySepBytes[0]: iter := readPool.BorrowIterator(b) @@ -112,8 +120,16 @@ func DeserializePathElement(s string) (PathElement, error) { fields = append(fields, value.Field{Name: key, Value: v}) return true }) + // Lookahead validates that there is no unexpected trailing data. + // io.EOF is a successful termination indicator; all other errors or trailing data fail. + if iter.WhatIsNext(); iter.Error != io.EOF { + if iter.Error == nil { + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + } + return PathElement{}, iter.Error + } fields.Sort() - return PathElement{Key: &fields}, iter.Error + return PathElement{Key: &fields}, nil case peIndexSepBytes[0]: i, err := strconv.Atoi(s[2:]) if err != nil { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go index b992b93c..6701f17e 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/serialize.go @@ -175,6 +175,17 @@ func (s *Set) FromJSON(r io.Reader) error { } else { *s = *found } + if iter.Error != nil { + return iter.Error + } + if iter.WhatIsNext(); iter.Error == nil { + // Piggy back on scanner aware error reporting here. + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + return iter.Error + } + if iter.Error == io.EOF { + return nil + } return iter.Error } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go index d2d8c8a4..d7fe643b 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/fieldpath/set.go @@ -19,6 +19,7 @@ package fieldpath import ( "fmt" "iter" + "slices" "sort" "strings" @@ -486,19 +487,13 @@ func (s *SetNodeMap) Copy() SetNodeMap { // Descend adds pe to the set if necessary, returning the associated subset. func (s *SetNodeMap) Descend(pe PathElement) *Set { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].pathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a setNode, b PathElement) int { + return a.pathElement.Compare(b) }) - if loc == len(s.members) { - s.members = append(s.members, setNode{pathElement: pe, set: &Set{}}) + if found { return s.members[loc].set } - if s.members[loc].pathElement.Equals(pe) { - return s.members[loc].set - } - s.members = append(s.members, setNode{}) - copy(s.members[loc+1:], s.members[loc:]) - s.members[loc] = setNode{pathElement: pe, set: &Set{}} + s.members = slices.Insert(s.members, loc, setNode{pathElement: pe, set: &Set{}}) return s.members[loc].set } @@ -523,13 +518,10 @@ func (s *SetNodeMap) Empty() bool { // Get returns (the associated set, true) or (nil, false) if there is none. func (s *SetNodeMap) Get(pe PathElement) (*Set, bool) { - loc := sort.Search(len(s.members), func(i int) bool { - return !s.members[i].pathElement.Less(pe) + loc, found := slices.BinarySearchFunc(s.members, pe, func(a setNode, b PathElement) int { + return a.pathElement.Compare(b) }) - if loc == len(s.members) { - return nil, false - } - if s.members[loc].pathElement.Equals(pe) { + if found { return s.members[loc].set, true } return nil, false diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go index c8138a65..4c0e30b2 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go @@ -62,6 +62,10 @@ type TypeRef struct { // If this field is nil, then it has no effect. // See `Map` and `List` for more information about `ElementRelationship` ElementRelationship *ElementRelationship `yaml:"elementRelationship,omitempty"` + + // Nullable indicates that an explicit null is a valid value, + // corresponding to OpenAPI's `nullable: true`. + Nullable bool `yaml:"nullable,omitempty"` } // Atom represents the smallest possible pieces of the type system. diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go index b668eff8..e1fa5c95 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go @@ -55,6 +55,9 @@ func (a *TypeRef) Equals(b *TypeRef) bool { if a.ElementRelationship != b.ElementRelationship { return false } + if a.Nullable != b.Nullable { + return false + } return a.Inlined.Equals(&b.Inlined) } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go index 6eb6c36d..4eb367b6 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go @@ -69,6 +69,9 @@ var SchemaSchemaYAML = `types: - name: elementRelationship type: scalar: string + - name: nullable + type: + scalar: boolean - name: scalar scalar: string - name: map diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go index f70cd416..acbfe8ce 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/allocator.go @@ -16,6 +16,8 @@ limitations under the License. package value +import "reflect" + // Allocator provides a value object allocation strategy. // Value objects can be allocated by passing an allocator to the "Using" // receiver functions on the value interfaces, e.g. Map.ZipUsing(allocator, ...). @@ -24,8 +26,8 @@ package value type Allocator interface { // Free gives the allocator back any value objects returned by the "Using" // receiver functions on the value interfaces. - // interface{} may be any of: Value, Map, List or Range. - Free(interface{}) + // any may be any of: Value, Map, List or Range. + Free(any) // The unexported functions are for "Using" receiver functions of the value types // to request what they need from the allocator. @@ -74,7 +76,7 @@ func (p *heapAllocator) allocListReflectRange() *listReflectRange { return &listReflectRange{vr: &valueReflect{}} } -func (p *heapAllocator) Free(_ interface{}) {} +func (p *heapAllocator) Free(_ any) {} // NewFreelistAllocator creates freelist based allocator. // This allocator provides fast allocation and freeing of short lived value objects. @@ -89,25 +91,25 @@ func (p *heapAllocator) Free(_ interface{}) {} // for all temporary value access. func NewFreelistAllocator() Allocator { return &freelistAllocator{ - valueUnstructured: &freelist{new: func() interface{} { + valueUnstructured: &freelist[*valueUnstructured]{new: func() *valueUnstructured { return &valueUnstructured{} }}, - listUnstructuredRange: &freelist{new: func() interface{} { + listUnstructuredRange: &freelist[*listUnstructuredRange]{new: func() *listUnstructuredRange { return &listUnstructuredRange{vv: &valueUnstructured{}} }}, - valueReflect: &freelist{new: func() interface{} { + valueReflect: &freelist[*valueReflect]{new: func() *valueReflect { return &valueReflect{} }}, - mapReflect: &freelist{new: func() interface{} { + mapReflect: &freelist[*mapReflect]{new: func() *mapReflect { return &mapReflect{} }}, - structReflect: &freelist{new: func() interface{} { + structReflect: &freelist[*structReflect]{new: func() *structReflect { return &structReflect{} }}, - listReflect: &freelist{new: func() interface{} { + listReflect: &freelist[*listReflect]{new: func() *listReflect { return &listReflect{} }}, - listReflectRange: &freelist{new: func() interface{} { + listReflectRange: &freelist[*listReflectRange]{new: func() *listReflectRange { return &listReflectRange{vr: &valueReflect{}} }}, } @@ -119,22 +121,22 @@ func NewFreelistAllocator() Allocator { const freelistMaxSize = 1000 type freelistAllocator struct { - valueUnstructured *freelist - listUnstructuredRange *freelist - valueReflect *freelist - mapReflect *freelist - structReflect *freelist - listReflect *freelist - listReflectRange *freelist + valueUnstructured *freelist[*valueUnstructured] + listUnstructuredRange *freelist[*listUnstructuredRange] + valueReflect *freelist[*valueReflect] + mapReflect *freelist[*mapReflect] + structReflect *freelist[*structReflect] + listReflect *freelist[*listReflect] + listReflectRange *freelist[*listReflectRange] } -type freelist struct { - list []interface{} - new func() interface{} +type freelist[T any] struct { + list []T + new func() T } -func (f *freelist) allocate() interface{} { - var w2 interface{} +func (f *freelist[T]) allocate() T { + var w2 T if n := len(f.list); n > 0 { w2, f.list = f.list[n-1], f.list[:n-1] } else { @@ -143,61 +145,73 @@ func (f *freelist) allocate() interface{} { return w2 } -func (f *freelist) free(v interface{}) { +func (f *freelist[T]) free(v T) { if len(f.list) < freelistMaxSize { f.list = append(f.list, v) } } -func (w *freelistAllocator) Free(value interface{}) { +func (w *freelistAllocator) Free(value any) { switch v := value.(type) { case *valueUnstructured: v.Value = nil // don't hold references to unstructured objects w.valueUnstructured.free(v) case *listUnstructuredRange: + v.list = nil // don't hold references to unstructured objects v.vv.Value = nil // don't hold references to unstructured objects w.listUnstructuredRange.free(v) case *valueReflect: - v.ParentMapKey = nil v.ParentMap = nil + v.ParentMapKey = nil + v.Value = reflect.Value{} // don't hold references to reflected objects w.valueReflect.free(v) case *mapReflect: + v.valueReflect.ParentMap = nil + v.valueReflect.ParentMapKey = nil + v.valueReflect.Value = reflect.Value{} // don't hold references to reflected objects w.mapReflect.free(v) case *structReflect: + v.valueReflect.ParentMap = nil + v.valueReflect.ParentMapKey = nil + v.valueReflect.Value = reflect.Value{} // don't hold references to reflected objects w.structReflect.free(v) case *listReflect: + v.Value = reflect.Value{} // don't hold references to reflected objects w.listReflect.free(v) case *listReflectRange: - v.vr.ParentMapKey = nil + v.list = reflect.Value{} // don't hold references to reflected objects v.vr.ParentMap = nil + v.vr.ParentMapKey = nil + v.vr.Value = reflect.Value{} // don't hold references to reflected objects + v.entry = nil w.listReflectRange.free(v) } } func (w *freelistAllocator) allocValueUnstructured() *valueUnstructured { - return w.valueUnstructured.allocate().(*valueUnstructured) + return w.valueUnstructured.allocate() } func (w *freelistAllocator) allocListUnstructuredRange() *listUnstructuredRange { - return w.listUnstructuredRange.allocate().(*listUnstructuredRange) + return w.listUnstructuredRange.allocate() } func (w *freelistAllocator) allocValueReflect() *valueReflect { - return w.valueReflect.allocate().(*valueReflect) + return w.valueReflect.allocate() } func (w *freelistAllocator) allocStructReflect() *structReflect { - return w.structReflect.allocate().(*structReflect) + return w.structReflect.allocate() } func (w *freelistAllocator) allocMapReflect() *mapReflect { - return w.mapReflect.allocate().(*mapReflect) + return w.mapReflect.allocate() } func (w *freelistAllocator) allocListReflect() *listReflect { - return w.listReflect.allocate().(*listReflect) + return w.listReflect.allocate() } func (w *freelistAllocator) allocListReflectRange() *listReflectRange { - return w.listReflectRange.allocate().(*listReflectRange) + return w.listReflectRange.allocate() } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go index 3aadceb2..db256137 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/jsontagutil.go @@ -76,11 +76,16 @@ func OmitZeroFunc(t reflect.Type) func(reflect.Value) bool { // but is based on the highly efficient approach from https://golang.org/src/encoding/json/encode.go func lookupJsonTags(f reflect.StructField) (name string, omit bool, inline bool, omitempty bool, omitzero func(reflect.Value) bool) { + // Skip unexported non-embedded fields, matching encoding/json behavior. + if f.PkgPath != "" && !f.Anonymous { + return "", true, false, false, nil + } tag := f.Tag.Get("json") if tag == "-" { return "", true, false, false, nil } name, opts := parseTag(tag) + inline = f.Anonymous && name == "" if name == "" { name = f.Name } @@ -89,7 +94,7 @@ func lookupJsonTags(f reflect.StructField) (name string, omit bool, inline bool, omitzero = OmitZeroFunc(f.Type) } - return name, false, opts.Contains("inline"), opts.Contains("omitempty"), omitzero + return name, false, inline, opts.Contains("omitempty"), omitzero } func isEmpty(v reflect.Value) bool { diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go index 75b7085c..f4f4c2b4 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/reflectcache.go @@ -39,14 +39,28 @@ type UnstructuredConverter interface { ToUnstructured() interface{} } +// UnstructuredConverterWithError is implemented instead of UnstructuredConverter by types for which +// some, but not all, values can be converted directly to unstructured. If a type implements both +// UnstructuredConverter and UnstructuredConverterWithError, its UnstructuredConverterWithError +// implementation takes precedence during conversion. +type UnstructuredConverterWithError interface { + json.Marshaler // require that json.Marshaler is implemented + + // ToUnstructured returns the unstructured representation, or a non-nil error if the value + // cannot be converted to unstructured. + ToUnstructuredWithError() (any, error) +} + // TypeReflectCacheEntry keeps data gathered using reflection about how a type is converted to/from unstructured. type TypeReflectCacheEntry struct { - isJsonMarshaler bool - ptrIsJsonMarshaler bool - isJsonUnmarshaler bool - ptrIsJsonUnmarshaler bool - isStringConvertable bool - ptrIsStringConvertable bool + isJsonMarshaler bool + ptrIsJsonMarshaler bool + isJsonUnmarshaler bool + ptrIsJsonUnmarshaler bool + isUnstructuredConverter bool + ptrIsUnstructuredConverter bool + isUnstructuredConverterWithError bool + ptrIsUnstructuredConverterWithError bool structFields map[string]*FieldCacheEntry orderedStructFields []*FieldCacheEntry @@ -93,9 +107,10 @@ func (f *FieldCacheEntry) GetFrom(structVal reflect.Value) reflect.Value { return structVal } -var marshalerType = reflect.TypeOf(new(json.Marshaler)).Elem() -var unmarshalerType = reflect.TypeOf(new(json.Unmarshaler)).Elem() -var unstructuredConvertableType = reflect.TypeOf(new(UnstructuredConverter)).Elem() +var marshalerType = reflect.TypeFor[json.Marshaler]() +var unmarshalerType = reflect.TypeFor[json.Unmarshaler]() +var unstructuredConverterType = reflect.TypeFor[UnstructuredConverter]() +var unstructuredConverterWithErrorType = reflect.TypeFor[UnstructuredConverterWithError]() var defaultReflectCache = newReflectCache() // TypeReflectEntryOf returns the TypeReflectCacheEntry of the provided reflect.Type. @@ -122,11 +137,13 @@ func typeReflectEntryOf(cm reflectCacheMap, t reflect.Type, updates reflectCache return record } typeEntry := &TypeReflectCacheEntry{ - isJsonMarshaler: t.Implements(marshalerType), - ptrIsJsonMarshaler: reflect.PtrTo(t).Implements(marshalerType), - isJsonUnmarshaler: reflect.PtrTo(t).Implements(unmarshalerType), - isStringConvertable: t.Implements(unstructuredConvertableType), - ptrIsStringConvertable: reflect.PtrTo(t).Implements(unstructuredConvertableType), + isJsonMarshaler: t.Implements(marshalerType), + ptrIsJsonMarshaler: reflect.PointerTo(t).Implements(marshalerType), + isJsonUnmarshaler: reflect.PointerTo(t).Implements(unmarshalerType), + isUnstructuredConverter: t.Implements(unstructuredConverterType), + ptrIsUnstructuredConverter: reflect.PointerTo(t).Implements(unstructuredConverterType), + isUnstructuredConverterWithError: t.Implements(unstructuredConverterWithErrorType), + ptrIsUnstructuredConverterWithError: reflect.PointerTo(t).Implements(unstructuredConverterWithErrorType), } if t.Kind() == reflect.Struct { fieldEntries := map[string]*FieldCacheEntry{} @@ -190,7 +207,7 @@ func (e TypeReflectCacheEntry) OrderedFields() []*FieldCacheEntry { // CanConvertToUnstructured returns true if this TypeReflectCacheEntry can convert values of its type to unstructured. func (e TypeReflectCacheEntry) CanConvertToUnstructured() bool { - return e.isJsonMarshaler || e.ptrIsJsonMarshaler || e.isStringConvertable || e.ptrIsStringConvertable + return e.isJsonMarshaler || e.ptrIsJsonMarshaler || e.isUnstructuredConverter || e.ptrIsUnstructuredConverter || e.isUnstructuredConverterWithError || e.ptrIsUnstructuredConverterWithError } // ToUnstructured converts the provided value to unstructured and returns it. @@ -206,7 +223,7 @@ func (e TypeReflectCacheEntry) ToUnstructured(sv reflect.Value) (interface{}, er // Check if the object has a custom string converter and use it if available, since it is much more efficient // than round tripping through json. if converter, ok := e.getUnstructuredConverter(sv); ok { - return converter.ToUnstructured(), nil + return converter.ToUnstructuredWithError() } // Check if the object has a custom JSON marshaller/unmarshaller. if marshaler, ok := e.getJsonMarshaler(sv); ok { @@ -318,16 +335,26 @@ func (e TypeReflectCacheEntry) getJsonUnmarshaler(v reflect.Value) (json.Unmarsh return v.Addr().Interface().(json.Unmarshaler), true } -func (e TypeReflectCacheEntry) getUnstructuredConverter(v reflect.Value) (UnstructuredConverter, bool) { - if e.isStringConvertable { - return v.Interface().(UnstructuredConverter), true - } - if e.ptrIsStringConvertable { +type unstructuredConverterWithNilError struct { + UnstructuredConverter +} + +func (c unstructuredConverterWithNilError) ToUnstructuredWithError() (any, error) { + return c.UnstructuredConverter.ToUnstructured(), nil +} + +func (e TypeReflectCacheEntry) getUnstructuredConverter(v reflect.Value) (UnstructuredConverterWithError, bool) { + switch { + case e.isUnstructuredConverterWithError: + return v.Interface().(UnstructuredConverterWithError), true + case e.ptrIsUnstructuredConverterWithError && v.CanAddr(): // Check pointer receivers if v is not a pointer - if v.CanAddr() { - v = v.Addr() - return v.Interface().(UnstructuredConverter), true - } + return v.Addr().Interface().(UnstructuredConverterWithError), true + case e.isUnstructuredConverter: + return unstructuredConverterWithNilError{v.Interface().(UnstructuredConverter)}, true + case e.ptrIsUnstructuredConverter && v.CanAddr(): + // Check pointer receivers if v is not a pointer + return unstructuredConverterWithNilError{v.Addr().Interface().(UnstructuredConverter)}, true } return nil, false } diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go index 140b9903..167848eb 100644 --- a/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/value/value.go @@ -118,6 +118,11 @@ func readJSONIter(iter *jsoniter.Iterator) (Value, error) { if iter.Error != nil && iter.Error != io.EOF { return nil, iter.Error } + if iter.WhatIsNext(); iter.Error == nil { + // Piggy back on scanner aware error reporting here. + iter.ReportError("managedFields parsing", "unexpected trailing data after JSON object") + return nil, iter.Error + } return NewValueInterface(v), nil }